From 745fdc9dc6f7f0e59ba2e372327d59cf899929ca Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 5 Nov 2014 14:12:57 -0500 Subject: [PATCH] More Windows window class logic simplification. This will be needed for read-only TextFields, next. --- common_windows.c | 38 ++++++++++++++++++++++++++++++++++---- uitask_windows.c | 8 +++----- winapi_windows.h | 9 ++------- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/common_windows.c b/common_windows.c index 9e67a0c..e0142c8 100644 --- a/common_windows.c +++ b/common_windows.c @@ -45,6 +45,39 @@ void *getWindowData(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT return data; } +// this is a helper function that takes the logic of determining window classes and puts it all in one place +// there are a number of places where we need to know what window class an arbitrary handle has +// theoretically we could use the class atom to avoid a _wcsicmp() +// however, raymond chen advises against this - http://blogs.msdn.com/b/oldnewthing/archive/2004/10/11/240744.aspx (and we're not in control of the Tab class, before you say anything) +// usage: windowClassOf(hwnd, L"class 1", L"class 2", ..., NULL) +int windowClassOf(HWND hwnd, ...) +{ +// MSDN says 256 is the maximum length of a class name; add a few characters just to be safe (because it doesn't say whether this includes the terminating null character) +#define maxClassName 260 + WCHAR classname[maxClassName + 1]; + va_list ap; + WCHAR *curname; + int i; + + if (GetClassNameW(hwnd, classname, maxClassName) == 0) + xpanic("error getting name of window class in windowClassOf()", GetLastError()); + va_start(ap, hwnd); + i = 0; + for (;;) { + curname = va_arg(ap, WCHAR *); + if (curname == NULL) + break; + if (_wcsicmp(classname, curname) == 0) { + va_end(ap); + return i; + } + i++; + } + // no match + va_end(ap); + return -1; +} + /* all container windows (including the message-only window, hence this is not in container_windows.c) have to call the sharedWndProc() to ensure messages go in the right place and control colors are handled properly */ @@ -100,7 +133,6 @@ void paintControlBackground(HWND hwnd, HDC dc) HWND parent; RECT r; POINT p, pOrig; - WCHAR classname[maxClassName + 1] = L""; parent = hwnd; for (;;) { @@ -110,10 +142,8 @@ void paintControlBackground(HWND hwnd, HDC dc) // wine sends these messages early, yay... if (parent == msgwin) return; - if (GetClassNameW(parent, classname, maxClassName) == 0) - xpanic("error getting name of focused window class in paintControlBackground()", GetLastError()); // skip groupboxes; they're (supposed to be) transparent - if (_wcsicmp(classname, L"button") != 0) + if (windowClassOf(parent, L"button", NULL) != 0) break; } if (GetWindowRect(hwnd, &r) == 0) diff --git a/uitask_windows.c b/uitask_windows.c index 49937c9..a713e60 100644 --- a/uitask_windows.c +++ b/uitask_windows.c @@ -59,7 +59,6 @@ void uimsgloop(void) MSG msg; int res; HWND active, focus; - WCHAR classchk[maxClassName + 1]; BOOL dodlgmessage; for (;;) { @@ -80,12 +79,11 @@ void uimsgloop(void) // as for Tabs, we can't have both WS_TABSTOP and WS_EX_CONTROLPARENT set at the same time, so we hotswap the two styles to get the behavior we want focus = GetFocus(); if (focus != NULL) { - if (GetClassNameW(focus, classchk, maxClassName) == 0) - xpanic("error getting name of focused window class for Area check", GetLastError()); - if (_wcsicmp(classchk, areaWindowClass) == 0) { + switch (windowClassOf(focus, areaWindowClass, WC_TABCONTROLW, NULL)) { + case 0: // areaWindowClass uimsgloop_area(active, focus, &msg); continue; - } else if (_wcsicmp(classchk, WC_TABCONTROL) == 0) { + case 1: // WC_TABCONTROLW uimsgloop_tab(active, focus, &msg); continue; } diff --git a/winapi_windows.h b/winapi_windows.h index db3b49e..f228d2e 100644 --- a/winapi_windows.h +++ b/winapi_windows.h @@ -23,6 +23,7 @@ #include #include #include +#include // global messages unique to everything enum { @@ -41,13 +42,6 @@ enum { msgOpenFileDone, }; -// there are a number of places where we need to know what window class an arbitrary handle has -// theoretically we could use the class atom to avoid a _wcsicmp() -// however, raymond chen advises against this - http://blogs.msdn.com/b/oldnewthing/archive/2004/10/11/240744.aspx (and we're not in control of the Tab class, before you say anything) -// MSDN says 256 is the maximum length of a class name; add a few characters just to be safe (because it doesn't say whether this includes the terminating null character) -// TODO localize this to a helper function -#define maxClassName 260 - // uitask_windows.c extern void uimsgloop(void); extern void issue(void *); @@ -112,6 +106,7 @@ extern void getWindowText(HWND, WPARAM, LPWSTR); extern void setWindowText(HWND, LPWSTR); extern void updateWindow(HWND); extern void *getWindowData(HWND, UINT, WPARAM, LPARAM, LRESULT *); +extern int windowClassOf(HWND, ...); extern BOOL sharedWndProc(HWND, UINT, WPARAM, LPARAM, LRESULT *); extern void paintControlBackground(HWND, HDC);