summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--new/container_windows.c51
-rw-r--r--new/init_windows.c6
-rw-r--r--new/uipriv_windows.h6
-rw-r--r--new/util_windows.c33
4 files changed, 90 insertions, 6 deletions
diff --git a/new/container_windows.c b/new/container_windows.c
index b389e70..d1bc9c6 100644
--- a/new/container_windows.c
+++ b/new/container_windows.c
@@ -1,6 +1,11 @@
// 7 april 2015
#include "uipriv_windows.h"
+// TODOs
+// - [12:24] <ZeroOne> There's flickering between tabs
+// - with CTLCOLOR handler: [12:24] <ZeroOne> And setting the button text blanked out the entire GUI until I ran my mouse over the elements / [12:25] <ZeroOne> https://dl.dropboxusercontent.com/u/15144168/GUI%20stuff.png
+// - without CTLCOLOR handler: [12:33] <ZeroOne> If I hide the stack, then show it, it looks like it's drawing duplicate buttons underneath
+
/*
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
*/
@@ -30,6 +35,42 @@ static LRESULT forwardNotify(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
+static void paintControlBackground(HWND hwnd, HDC dc)
+{
+ HWND parent;
+ RECT r;
+ POINT pOrig;
+ DWORD le;
+
+ parent = hwnd;
+ for (;;) {
+ parent = GetParent(parent);
+ if (parent == NULL)
+ logLastError("error getting parent control of control in paintControlBackground()");
+ // wine sends these messages early, yay...
+ if (parent == initialParent)
+ return;
+ // skip groupboxes; they're (supposed to be) transparent
+ if (windowClassOf(parent, L"button", NULL) != 0)
+ break;
+ }
+ if (GetWindowRect(hwnd, &r) == 0)
+ logLastError("error getting control's window rect in paintControlBackground()");
+ // the above is a window rect in screen coordinates; convert to client rect
+ SetLastError(0);
+ if (MapWindowRect(NULL, parent, &r) == 0) {
+ le = GetLastError();
+ SetLastError(le); // just to be safe
+ if (le != 0)
+ logLastError("error getting client origin of control in paintControlBackground()");
+ }
+ if (SetWindowOrgEx(dc, r.left, r.top, &pOrig) == 0)
+ logLastError("error moving window origin in paintControlBackground()");
+ SendMessageW(parent, WM_PRINTCLIENT, (WPARAM) dc, PRF_CLIENT);
+ if (SetWindowOrgEx(dc, pOrig.x, pOrig.y, NULL) == 0)
+ logLastError("error resetting window origin in paintControlBackground()");
+}
+
BOOL sharedWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
{
switch (uMsg) {
@@ -39,19 +80,19 @@ BOOL sharedWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *
case WM_NOTIFY:
*lResult = forwardNotify(hwnd, uMsg, wParam, lParam);
return TRUE;
-/*TODO case WM_CTLCOLORSTATIC:
+ case WM_CTLCOLORSTATIC:
case WM_CTLCOLORBTN:
- // read-only TextFields and Textboxes are exempt
+/*TODO // read-only TextFields and Textboxes are exempt
// this is because read-only edit controls count under WM_CTLCOLORSTATIC
if (windowClassOf((HWND) lParam, L"edit", NULL) == 0)
if (textfieldReadOnly((HWND) lParam))
return FALSE;
- if (SetBkMode((HDC) wParam, TRANSPARENT) == 0)
- xpanic("error setting transparent background mode to Labels", GetLastError());
+*/ if (SetBkMode((HDC) wParam, TRANSPARENT) == 0)
+ logLastError("error setting transparent background mode to controls in sharedWndProc()");
paintControlBackground((HWND) lParam, (HDC) wParam);
*lResult = (LRESULT) hollowBrush;
return TRUE;
-*/ }
+ }
return FALSE;
}
diff --git a/new/init_windows.c b/new/init_windows.c
index 7ebe4e2..d0390be 100644
--- a/new/init_windows.c
+++ b/new/init_windows.c
@@ -6,6 +6,8 @@ int nCmdShow;
HFONT hMessageFont;
+HBRUSH hollowBrush;
+
struct uiInitError {
char *msg;
char failbuf[256];
@@ -97,6 +99,10 @@ const char *uiInit(uiInitOptions *o)
if (ce != NULL)
return loadLastError(ce);
+ hollowBrush = (HBRUSH) GetStockObject(HOLLOW_BRUSH);
+ if (hollowBrush == NULL)
+ return loadLastError("getting hollow brush");
+
return NULL;
}
diff --git a/new/uipriv_windows.h b/new/uipriv_windows.h
index a8cd429..54c0906 100644
--- a/new/uipriv_windows.h
+++ b/new/uipriv_windows.h
@@ -45,7 +45,10 @@ extern HRESULT logMemoryExhausted(const char *);
extern HINSTANCE hInstance;
extern int nCmdShow;
extern HFONT hMessageFont;
-extern HWND initialParent;
+extern HBRUSH hollowBrush;
+
+// util_windows.c
+extern int windowClassOf(HWND, ...);
// text_windows.c
extern WCHAR *toUTF16(const char *);
@@ -66,4 +69,5 @@ extern const char *initCommonControls(void);
extern ATOM registerWindowClass(HICON, HCURSOR);
// initparent_windows.c
+extern HWND initialParent;
extern const char *initInitialParent(HICON, HCURSOR);
diff --git a/new/util_windows.c b/new/util_windows.c
index e3332be..93b32d8 100644
--- a/new/util_windows.c
+++ b/new/util_windows.c
@@ -38,3 +38,36 @@ intmax_t uiWindowsWindowTextWidth(HWND hwnd)
return size.cx;
}
+
+// 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)
+ logLastError("error getting name of window class in windowClassOf()");
+ 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;
+}