1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
// 4 december 2014
typedef BOOL (*handlerfunc)(struct table *, UINT, WPARAM, LPARAM, LRESULT *);
#define HANDLER(name) static BOOL name(struct table *t, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
static BOOL runHandlers(const handlerfunc list[], struct table *t, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
{
handlerfunc *p;
for (p = list; *p != NULL; p++)
if ((*(*p))(t, uMsg, wParam, lParam, lResult))
return TRUE;
return FALSE;
}
// memory allocation stuff
// each of these functions do an implicit ZeroMemory()
// these also make tableRealloc(NULL, ...)/tableFree(NULL) act like realloc(NULL, ...)/free(NULL) (that is, same as tableAlloc(...)/malloc(...) and a no-op, respectively)
// we're using LocalAlloc() because:
// - whether the malloc() family supports the last-error code is undefined
// - the HeapAlloc() family DOES NOT support the last-error code; you're supposed to use Windows exceptions, and I can't find a clean way to do this with MinGW-w64 that doesn't rely on inline assembly or external libraries (unless they added __try/__except blocks)
// - there's no VirtualReAlloc() to complement VirtualAlloc() and I'm not sure if we can even get the original allocated size back out reliably to write it ourselves (http://blogs.msdn.com/b/oldnewthing/archive/2012/03/16/10283988.aspx)
// needless to say, TODO
static void *tableAlloc(size_t size, const char *panicMessage)
{
HLOCAL out;
out = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, size);
if (out == NULL)
panic(panicMessage);
return (void *) out;
}
static void *tableRealloc(void *p, size_t size, const char *panicMessage)
{
HLOCAL out;
if (p == NULL)
return tableAlloc(size, panicMessage);
out = LocalReAlloc((HLOCAL) p, size, LMEM_ZEROINIT);
if (out == NULL)
panic(panicMessage);
return (void *) out;
}
static void tableFree(void *p, const char *panicMessage)
{
if (p == NULL)
return;
if (LocalFree((HLOCAL) p) != NULL)
panic(panicMessage);
}
// font selection
static HFONT selectFont(struct table *t, HDC dc, HFONT *newfont)
{
HFONT prevfont;
// copy it in casse we get a WM_SETFONT before this call's respective deselectFont() call
*newfont = t->font;
if (*newfont == NULL) {
// get it on demand in the (unlikely) event it changes while this Table is alive
*newfont = GetStockObject(SYSTEM_FONT);
if (*newfont == NULL)
panic("error getting default font for selecting into Table DC");
}
prevfont = (HFONT) SelectObject(dc, *newfont);
if (prevfont == NULL)
panic("error selecting Table font into Table DC");
return prevfont;
}
static void deselectFont(HDC dc, HFONT prevfont, HFONT newfont)
{
if (SelectObject(dc, prevfont) != newfont)
panic("error deselecting Table font from Table DC");
// doin't delete newfont here, even if it is the system font (see http://msdn.microsoft.com/en-us/library/windows/desktop/dd144925%28v=vs.85%29.aspx)
}
// and back to other functions
static LONG columnWidth(struct table *t, intptr_t n)
{
RECT r;
if (SendMessageW(t->header, HDM_GETITEMRECT, (WPARAM) n, (LPARAM) (&r)) == 0)
panic("error getting Table column width");
return r.right - r.left;
}
|