summaryrefslogtreecommitdiff
path: root/redo/tab_windows.c
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-08-02 22:35:58 -0400
committerPietro Gagliardi <[email protected]>2014-08-02 22:35:58 -0400
commitd018953d7ef1b276cc3229e04ba6fc75018c888a (patch)
tree3f980a017ca498bf499ff9c5e6a53210606b12f9 /redo/tab_windows.c
parent1f6bcde3d9ddcab921f2f4347148f6784ca36a14 (diff)
Split all the Control implementations into their own files and renamed the containerctrls implementation files to say tab instead as they only hold Tab. This is the first part of what should hopefully be the final restructuring.
Diffstat (limited to 'redo/tab_windows.c')
-rw-r--r--redo/tab_windows.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/redo/tab_windows.c b/redo/tab_windows.c
new file mode 100644
index 0000000..5a998b5
--- /dev/null
+++ b/redo/tab_windows.c
@@ -0,0 +1,82 @@
+/* 25 july 2014 */
+
+#include "winapi_windows.h"
+#include "_cgo_export.h"
+
+/* provided for cgo's benefit */
+LPWSTR xWC_TABCONTROL = WC_TABCONTROL;
+
+static LRESULT CALLBACK tabSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR id, DWORD_PTR data)
+{
+ NMHDR *nmhdr = (NMHDR *) lParam;
+ LRESULT r;
+
+ switch (uMsg) {
+ case msgNOTIFY:
+ switch (nmhdr->code) {
+ case TCN_SELCHANGING:
+ r = SendMessageW(hwnd, TCM_GETCURSEL, 0, 0);
+ if (r == (LRESULT) -1) /* no tab currently selected */
+ return FALSE;
+ tabChanging((void *) data, r);
+ return FALSE; /* allow change */
+ case TCN_SELCHANGE:
+ tabChanged((void *) data, SendMessageW(hwnd, TCM_GETCURSEL, 0, 0));
+ return 0;
+ }
+ return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
+ case WM_NCDESTROY:
+ if ((*fv_RemoveWindowSubclass)(hwnd, tabSubProc, id) == FALSE)
+ xpanic("error removing Tab subclass (which was for its own event handler)", GetLastError());
+ return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
+ default:
+ return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
+ }
+ xmissedmsg("Tab", "tabSubProc()", uMsg);
+ return 0; /* unreached */
+}
+
+void setTabSubclass(HWND hwnd, void *data)
+{
+ if ((*fv_SetWindowSubclass)(hwnd, tabSubProc, 0, (DWORD_PTR) data) == FALSE)
+ xpanic("error subclassing Tab to give it its own event handler", GetLastError());
+}
+
+void tabAppend(HWND hwnd, LPWSTR name)
+{
+ TCITEM item;
+ LRESULT n;
+
+ ZeroMemory(&item, sizeof (TCITEM));
+ item.mask = TCIF_TEXT;
+ item.pszText = name;
+ /* MSDN's example code uses the first invalid index directly for this */
+ n = SendMessageW(hwnd, TCM_GETITEMCOUNT, 0, 0);
+ if (SendMessageW(hwnd, TCM_INSERTITEM, (WPARAM) n, (LPARAM) (&item)) == (LRESULT) -1)
+ xpanic("error adding tab to Tab", GetLastError());
+}
+
+void tabGetContentRect(HWND hwnd, RECT *r)
+{
+ /* not &r; already a pointer (thanks MindChild in irc.efnet.net/#winprog for spotting my failure) */
+ SendMessageW(hwnd, TCM_ADJUSTRECT, FALSE, (LPARAM) r);
+}
+
+/* theoretically we don't need to iterate over every tab for this, but let's do it just to be safe */
+LONG tabGetTabHeight(HWND hwnd)
+{
+ RECT r;
+ LRESULT i, n;
+ LONG tallest;
+
+ n = SendMessageW(hwnd, TCM_GETITEMCOUNT, 0, 0);
+ /* if there are no tabs, then the control just draws a box over the full window rect, reserving no space for tabs (TODO check on windows xp and 7); this is handled here */
+ tallest = 0;
+ for (i = 0; i < n; i++) {
+ if (SendMessageW(hwnd, TCM_GETITEMRECT, (WPARAM) i, (LPARAM) (&r)) == FALSE)
+ xpanic("error getting tab height for Tab.preferredSize()", GetLastError());
+ if (tallest < (r.bottom - r.top))
+ tallest = r.bottom - r.top;
+ }
+ return tallest;
+}