summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--new/uipriv_windows.h8
-rw-r--r--new/util_windows.c54
-rw-r--r--new/window_windows.c3
3 files changed, 65 insertions, 0 deletions
diff --git a/new/uipriv_windows.h b/new/uipriv_windows.h
index 4d4ba54..86b7734 100644
--- a/new/uipriv_windows.h
+++ b/new/uipriv_windows.h
@@ -28,6 +28,13 @@
#include <stdio.h>
#include "uipriv.h"
+// ui internal window messages
+enum {
+ // redirected WM_COMMAND and WM_NOTIFY
+ msgCOMMAND = WM_APP + 0x40, // start offset just to be safe
+ msgNOTIFY,
+};
+
// alloc_windows.c
extern void *uiAlloc(size_t);
// TODO use this in existing files
@@ -48,6 +55,7 @@ extern HWND initialParent;
// util_windows.c
extern WCHAR *toUTF16(const char *);
+extern BOOL sharedWndProc(HWND, UINT, WPARAM, LPARAM, LRESULT *);
// comctl32_windows.c
extern BOOL (*WINAPI fv_SetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
diff --git a/new/util_windows.c b/new/util_windows.c
index 0bd76a0..6292967 100644
--- a/new/util_windows.c
+++ b/new/util_windows.c
@@ -16,3 +16,57 @@ WCHAR *toUTF16(const char *str)
logLastError("error converting from UTF-8 to UTF-16 in toUTF16()");
return wstr;
}
+
+/*
+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
+*/
+
+/*
+all controls that have events receive the events themselves through subclasses
+to do this, all container windows (including the message-only window; see http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q104069) forward WM_COMMAND to each control with this function, WM_NOTIFY with forwardNotify, etc.
+*/
+static LRESULT forwardCommand(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ HWND control = (HWND) lParam;
+
+ // don't generate an event if the control (if there is one) is unparented (a child of the initial parent window)
+ if (control != NULL && IsChild(initialParent, control) == 0)
+ return SendMessageW(control, msgCOMMAND, wParam, lParam);
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+}
+
+static LRESULT forwardNotify(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ NMHDR *nmhdr = (NMHDR *) lParam;
+ HWND control = nmhdr->hwndFrom;
+
+ // don't generate an event if the control (if there is one) is unparented (a child of the initial parent window)
+ if (control != NULL && IsChild(initialParent, control) == 0)
+ return SendMessageW(control, msgNOTIFY, wParam, lParam);
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+}
+
+BOOL sharedWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
+{
+ switch (uMsg) {
+ case WM_COMMAND:
+ *lResult = forwardCommand(hwnd, uMsg, wParam, lParam);
+ return TRUE;
+ case WM_NOTIFY:
+ *lResult = forwardNotify(hwnd, uMsg, wParam, lParam);
+ return TRUE;
+/*TODO case WM_CTLCOLORSTATIC:
+ case WM_CTLCOLORBTN:
+ // 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());
+ paintControlBackground((HWND) lParam, (HDC) wParam);
+ *lResult = (LRESULT) hollowBrush;
+ return TRUE;
+*/ }
+ return FALSE;
+}
diff --git a/new/window_windows.c b/new/window_windows.c
index 12655b9..aac61db 100644
--- a/new/window_windows.c
+++ b/new/window_windows.c
@@ -14,6 +14,7 @@ static LRESULT CALLBACK uiWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPA
{
uiWindow *w;
CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam;
+ LRESULT lr;
w = (uiWindow *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
if (w == NULL) {
@@ -22,6 +23,8 @@ static LRESULT CALLBACK uiWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPA
// fall through to DefWindowProc() anyway
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
+ if (sharedWindowProc(hwnd, uMsg, wParam, lParam, &lResult) != FALSE)
+ return lResult;
switch (uMsg) {
case WM_CLOSE:
if (!(*(w->onClosing))(w, w->onClosingData))