summaryrefslogtreecommitdiff
path: root/wintable/util.h
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2015-01-06 17:27:41 -0500
committerPietro Gagliardi <[email protected]>2015-01-06 17:27:41 -0500
commit22123fb676d26d309d428a892c453e35e684e367 (patch)
tree9552f1a91a8b8995065e74573e8f59f448f2b08c /wintable/util.h
parent720049bfd3c6d205859f3150dee33dee78dc3dc3 (diff)
Merged wintable/new/ into wintable/.
Diffstat (limited to 'wintable/util.h')
-rw-r--r--wintable/util.h119
1 files changed, 119 insertions, 0 deletions
diff --git a/wintable/util.h b/wintable/util.h
new file mode 100644
index 0000000..4dd73d6
--- /dev/null
+++ b/wintable/util.h
@@ -0,0 +1,119 @@
+// 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 /would/ use LocalAlloc() here 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)
+// alas, LocalAlloc() doesn't want to work on real Windows 7 after a few times, throwing up ERROR_NOT_ENOUGH_MEMORY after three (3) ints or so :|
+// we'll use malloc() until then
+// needless to say, TODO
+
+static void *tableAlloc(size_t size, const char *panicMessage)
+{
+// HLOCAL out;
+ void *out;
+
+// out = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, size);
+ out = malloc(size);
+ if (out == NULL)
+ panic(panicMessage);
+ ZeroMemory(out, size);
+ return (void *) out;
+}
+
+static void *tableRealloc(void *p, size_t size, const char *panicMessage)
+{
+// HLOCAL out;
+ void *out;
+
+ if (p == NULL)
+ return tableAlloc(size, panicMessage);
+// out = LocalReAlloc((HLOCAL) p, size, LMEM_ZEROINIT);
+ out = realloc(p, size);
+ if (out == NULL)
+ panic(panicMessage);
+ // TODO zero the extra memory
+ return (void *) out;
+}
+
+static void tableFree(void *p, const char *panicMessage)
+{
+ if (p == NULL)
+ return;
+// if (LocalFree((HLOCAL) p) != NULL)
+// panic(panicMessage);
+ free(p);
+}
+
+// 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;
+}
+
+/* TODO:
+http://blogs.msdn.com/b/oldnewthing/archive/2003/10/13/55279.aspx
+http://blogs.msdn.com/b/oldnewthing/archive/2003/10/14/55286.aspx
+we'll need to make sure that initial edge case works properly
+(TODO get the linked article in the latter)
+also implement retrack() as so, in the WM_MOUSEMOVE handler
+*/
+static void retrack(struct table *t)
+{
+ TRACKMOUSEEVENT tm;
+
+ ZeroMemory(&tm, sizeof (TRACKMOUSEEVENT));
+ tm.cbSize = sizeof (TRACKMOUSEEVENT);
+ tm.dwFlags = TME_LEAVE; // TODO TME_NONCLIENT as well?
+ tm.hwndTrack = t->hwnd;
+ if ((*tableTrackMouseEvent)(&tm) == 0)
+ panic("error retracking Table mouse events");
+}