Split out common container window procedure code in Windows to its own function.

This commit is contained in:
Pietro Gagliardi 2014-08-14 16:00:31 -04:00
parent 52339e1f11
commit d944af8609
6 changed files with 54 additions and 45 deletions

View File

@ -35,3 +35,46 @@ void storelpParam(HWND hwnd, LPARAM lParam)
SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) (cs->lpCreateParams));
}
/*
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 message-only window)
if (control != NULL && IsChild(msgwin, 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 message-only window)
if (control != NULL && IsChild(msgwin, control) == 0)
return SendMessageW(control, msgNOTIFY, wParam, lParam);
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
// TODO give this a better name
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;
}
return FALSE;
}

View File

@ -15,10 +15,7 @@ static LRESULT CALLBACK containerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LP
{
void *data;
RECT r;
HDC dc;
PAINTSTRUCT ps;
HWND parent;
POINT client;
LRESULT shared;
data = (void *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
if (data == NULL) {
@ -31,12 +28,9 @@ static LRESULT CALLBACK containerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LP
// act as if we're not ready yet, even during WM_NCCREATE (nothing important to the switch statement below happens here anyway)
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
if (sharedWndProc(hwnd, uMsg, wParam, lParam, &shared))
return shared;
switch (uMsg) {
case WM_COMMAND:
return forwardCommand(hwnd, uMsg, wParam, lParam);
case WM_NOTIFY:
return forwardNotify(hwnd, uMsg, wParam, lParam);
case WM_SIZE:
if (GetClientRect(hwnd, &r) == 0)
xpanic("error getting client rect for Window in WM_SIZE", GetLastError());

View File

@ -34,31 +34,6 @@ void controlSetControlFont(HWND which)
SendMessageW(which, WM_SETFONT, (WPARAM) controlFont, TRUE);
}
/*
all controls that have events receive the events themselves through subclasses
to do this, all 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
*/
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 message-only window)
if (control != NULL && IsChild(msgwin, control) == 0)
return SendMessageW(control, msgCOMMAND, wParam, lParam);
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
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 message-only window)
if (control != NULL && IsChild(msgwin, control) == 0)
return SendMessageW(control, msgNOTIFY, wParam, lParam);
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
void moveWindow(HWND hwnd, int x, int y, int width, int height)
{
if (MoveWindow(hwnd, x, y, width, height, TRUE) == 0)

View File

@ -73,11 +73,11 @@ HWND msgwin;
static LRESULT CALLBACK msgwinproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT shared;
if (sharedWndProc(hwnd, uMsg, wParam, lParam, &shared))
return shared;
switch (uMsg) {
case WM_COMMAND:
return forwardCommand(hwnd, uMsg, wParam, lParam);
case WM_NOTIFY:
return forwardNotify(hwnd, uMsg, wParam, lParam);
case msgRequest:
doissue((void *) lParam);
return 0;

View File

@ -49,8 +49,6 @@ extern LRESULT (*WINAPI fv_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
extern HWND newControl(LPWSTR, DWORD, DWORD);
extern void controlSetParent(HWND, HWND);
extern void controlSetControlFont(HWND);
extern LRESULT forwardCommand(HWND, UINT, WPARAM, LPARAM);
extern LRESULT forwardNotify(HWND, UINT, WPARAM, LPARAM);
extern void moveWindow(HWND, int, int, int, int);
extern LONG controlTextLength(HWND, LPWSTR);
@ -84,6 +82,7 @@ extern void getWindowText(HWND, WPARAM, LPWSTR);
extern void setWindowText(HWND, LPWSTR);
extern void updateWindow(HWND);
extern void storelpParam(HWND, LPARAM);
extern BOOL sharedWndProc(HWND, UINT, WPARAM, LPARAM, LRESULT *);
// tab_windows.go
extern LPWSTR xWC_TABCONTROL;

View File

@ -9,6 +9,7 @@ static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA
{
void *data;
RECT r;
LRESULT shared;
data = (void *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
if (data == NULL) {
@ -21,12 +22,9 @@ static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA
// act as if we're not ready yet, even during WM_NCCREATE (nothing important to the switch statement below happens here anyway)
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
if (sharedWndProc(hwnd, uMsg, wParam, lParam, &shared))
return shared;
switch (uMsg) {
case WM_COMMAND:
return forwardCommand(hwnd, uMsg, wParam, lParam);
case WM_NOTIFY:
return forwardNotify(hwnd, uMsg, wParam, lParam);
case WM_SIZE:
if (GetClientRect(hwnd, &r) == 0)
xpanic("error getting client rect for Window in WM_SIZE", GetLastError());