diff options
| author | Pietro Gagliardi <[email protected]> | 2015-01-06 17:27:41 -0500 |
|---|---|---|
| committer | Pietro Gagliardi <[email protected]> | 2015-01-06 17:27:41 -0500 |
| commit | 22123fb676d26d309d428a892c453e35e684e367 (patch) | |
| tree | 9552f1a91a8b8995065e74573e8f59f448f2b08c /wintable/header.h | |
| parent | 720049bfd3c6d205859f3150dee33dee78dc3dc3 (diff) | |
Merged wintable/new/ into wintable/.
Diffstat (limited to 'wintable/header.h')
| -rw-r--r-- | wintable/header.h | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/wintable/header.h b/wintable/header.h new file mode 100644 index 0000000..5652029 --- /dev/null +++ b/wintable/header.h @@ -0,0 +1,109 @@ +// 7 december 2014 + +// TODO verify header events (double-clicking on a divider, for example) + +static void makeHeader(struct table *t, HINSTANCE hInstance) +{ + t->header = CreateWindowExW(0, + WC_HEADERW, L"", + // don't set WS_VISIBLE; according to MSDN we create the header hidden as part of setting the initial position (http://msdn.microsoft.com/en-us/library/windows/desktop/ff485935%28v=vs.85%29.aspx) + // TODO WS_BORDER? + // TODO is HDS_HOTTRACK needed? + WS_CHILD | HDS_FULLDRAG | HDS_HORZ | HDS_HOTTRACK, + 0, 0, 0, 0, // no initial size + t->hwnd, (HMENU) 100, hInstance, NULL); + if (t->header == NULL) + panic("error creating Table header"); +} + +static void destroyHeader(struct table *t) +{ + if (DestroyWindow(t->header) == 0) + panic("error destroying Table header"); +} + +static void repositionHeader(struct table *t) +{ + RECT r; + WINDOWPOS wp; + HDLAYOUT l; + + if (GetClientRect(t->hwnd, &r) == 0) + panic("error getting client rect for Table header repositioning"); + // we fake horizontal scrolling here by extending the client rect to the left by the scroll position + r.left -= t->hscrollpos; + l.prc = &r; + l.pwpos = ℘ + if (SendMessageW(t->header, HDM_LAYOUT, 0, (LPARAM) (&l)) == FALSE) + panic("error getting new Table header position"); + if (SetWindowPos(t->header, wp.hwndInsertAfter, + wp.x, wp.y, wp.cx, wp.cy, + // see above on showing the header here instead of in the CreateWindowExW() call + wp.flags | SWP_SHOWWINDOW) == 0) + panic("error repositioning Table header"); + t->headerHeight = wp.cy; +} + +static void headerAddColumn(struct table *t, WCHAR *name) +{ + HDITEMW item; + + ZeroMemory(&item, sizeof (HDITEMW)); + item.mask = HDI_WIDTH | HDI_TEXT | HDI_FORMAT; + item.cxy = 200; // TODO + item.pszText = name; + item.fmt = HDF_LEFT | HDF_STRING; + // TODO replace 100 with (t->nColumns - 1) + if (SendMessage(t->header, HDM_INSERTITEM, (WPARAM) (100), (LPARAM) (&item)) == (LRESULT) (-1)) + panic("error adding column to Table header"); +} + +// TODO make a better name for this? +// TODO move to hscroll.h? +// TODO organize this in general... +// TODO because of this function's new extended functionality only hscrollto() is allowed to call repositionHeader() +static void updateTableWidth(struct table *t) +{ + HDITEMW item; + intptr_t i; + RECT client; + + t->width = 0; + // TODO count dividers? + // TODO use columnWidth() + for (i = 0; i < t->nColumns; i++) { + ZeroMemory(&item, sizeof (HDITEMW)); + item.mask = HDI_WIDTH; + if (SendMessageW(t->header, HDM_GETITEM, (WPARAM) i, (LPARAM) (&item)) == FALSE) + panic("error getting Table column width for updateTableWidth()"); + t->width += item.cxy; + } + + if (GetClientRect(t->hwnd, &client) == 0) + panic("error getting Table client rect in updateTableWidth()"); + t->hpagesize = client.right - client.left; + + // this part is critical: if we resize the columns to less than the client area width, then the following hscrollby() will make t->hscrollpos negative, which does very bad things + // note to self: do this regardless of whether the table width or the client area width was changed + if (t->hpagesize > t->width) + t->hpagesize = t->width; + + // do a dummy scroll to update the horizontal scrollbar to use the new width + hscrollby(t, 0); +} + +HANDLER(headerNotifyHandler) +{ + NMHDR *nmhdr = (NMHDR *) lParam; + + if (nmhdr->hwndFrom != t->header) + return FALSE; + if (nmhdr->code != HDN_ITEMCHANGED) + return FALSE; + updateTableWidth(t); + // TODO make more intelligent + InvalidateRect(t->hwnd, NULL, TRUE); + // TODO UpdateWindow()? + *lResult = 0; + return TRUE; +} |
