Cleaned up uimsgloop() in Windows. This will be important, as I'm going to be changing AreaHandler.Key()... again...
This commit is contained in:
parent
e845fcbf78
commit
f3ca234dda
|
@ -8,6 +8,36 @@
|
||||||
// this also assumes WC_TABCONTROL is longer than areaWindowClass
|
// this also assumes WC_TABCONTROL is longer than areaWindowClass
|
||||||
#define NCLASSNAME (sizeof WC_TABCONTROL / sizeof WC_TABCONTROL[0])
|
#define NCLASSNAME (sizeof WC_TABCONTROL / sizeof WC_TABCONTROL[0])
|
||||||
|
|
||||||
|
void uimsgloop_area(MSG *msg)
|
||||||
|
{
|
||||||
|
// don't call TranslateMessage(); we do our own keyboard handling
|
||||||
|
DispatchMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uimsgloop_tab(HWND active, HWND focus, MSG *msg)
|
||||||
|
{
|
||||||
|
BOOL hasChildren;
|
||||||
|
BOOL idm;
|
||||||
|
|
||||||
|
// THIS BIT IS IMPORTANT: if the current tab has no children, then there will be no children left in the dialog to tab to, and IsDialogMessageW() will loop forever
|
||||||
|
hasChildren = SendMessageW(focus, msgTabCurrentTabHasChildren, 0, 0);
|
||||||
|
if (hasChildren)
|
||||||
|
tabEnterChildren(focus);
|
||||||
|
idm = IsDialogMessageW(active, msg);
|
||||||
|
if (hasChildren)
|
||||||
|
tabLeaveChildren(focus);
|
||||||
|
if (idm != 0)
|
||||||
|
return;
|
||||||
|
TranslateMessage(msg);
|
||||||
|
DispatchMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uimsgloop_else(MSG *msg)
|
||||||
|
{
|
||||||
|
TranslateMessage(msg);
|
||||||
|
DispatchMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
void uimsgloop(void)
|
void uimsgloop(void)
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
@ -15,8 +45,6 @@ void uimsgloop(void)
|
||||||
HWND active, focus;
|
HWND active, focus;
|
||||||
WCHAR classchk[NCLASSNAME];
|
WCHAR classchk[NCLASSNAME];
|
||||||
BOOL dodlgmessage;
|
BOOL dodlgmessage;
|
||||||
BOOL istab;
|
|
||||||
BOOL idm;
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
SetLastError(0);
|
SetLastError(0);
|
||||||
|
@ -26,38 +54,34 @@ void uimsgloop(void)
|
||||||
if (res == 0) // WM_QUIT
|
if (res == 0) // WM_QUIT
|
||||||
break;
|
break;
|
||||||
active = GetActiveWindow();
|
active = GetActiveWindow();
|
||||||
if (active != NULL) {
|
if (active == NULL) {
|
||||||
// bit of logic involved here:
|
uimsgloop_else(&msg);
|
||||||
// we don't want dialog messages passed into Areas, so we don't call IsDialogMessageW() there
|
continue;
|
||||||
// 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
|
|
||||||
// theoretically we could use the class atom to avoid a wcscmp()
|
|
||||||
// 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)
|
|
||||||
// we could also theoretically just send msgAreaDefocuses directly, but what DefWindowProc() does to a WM_APP message is undocumented
|
|
||||||
dodlgmessage = TRUE;
|
|
||||||
istab = FALSE;
|
|
||||||
focus = GetFocus();
|
|
||||||
if (focus != NULL) {
|
|
||||||
if (GetClassNameW(focus, classchk, NCLASSNAME) == 0)
|
|
||||||
xpanic("error getting name of focused window class for Area check", GetLastError());
|
|
||||||
if (wcscmp(classchk, areaWindowClass) == 0)
|
|
||||||
dodlgmessage = FALSE;
|
|
||||||
else if (wcscmp(classchk, WC_TABCONTROL) == 0)
|
|
||||||
// THIS BIT IS IMPORTANT
|
|
||||||
// if the current tab has no children, then there will be no children left in the dialog to tab to, and IsDialogMessageW() will loop forever
|
|
||||||
istab = (BOOL) SendMessageW(focus, msgTabCurrentTabHasChildren, 0, 0);
|
|
||||||
}
|
|
||||||
if (dodlgmessage) {
|
|
||||||
if (istab)
|
|
||||||
tabEnterChildren(focus);
|
|
||||||
idm = IsDialogMessageW(active, &msg);
|
|
||||||
if (istab)
|
|
||||||
tabLeaveChildren(focus);
|
|
||||||
if (idm != 0)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessageW(&msg);
|
// bit of logic involved here:
|
||||||
|
// we don't want dialog messages passed into Areas, so we don't call IsDialogMessageW() there
|
||||||
|
// 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
|
||||||
|
// theoretically we could use the class atom to avoid a wcscmp()
|
||||||
|
// 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)
|
||||||
|
// we could also theoretically just send msgAreaDefocuses directly, but what DefWindowProc() does to a WM_APP message is undocumented
|
||||||
|
focus = GetFocus();
|
||||||
|
if (focus != NULL) {
|
||||||
|
if (GetClassNameW(focus, classchk, NCLASSNAME) == 0)
|
||||||
|
xpanic("error getting name of focused window class for Area check", GetLastError());
|
||||||
|
if (wcscmp(classchk, areaWindowClass) == 0) {
|
||||||
|
uimsgloop_area(&msg);
|
||||||
|
continue;
|
||||||
|
} else if (wcscmp(classchk, WC_TABCONTROL) == 0) {
|
||||||
|
uimsgloop_tab(active, focus, &msg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// else fall through
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsDialogMessage(active, &msg) != 0)
|
||||||
|
continue;
|
||||||
|
uimsgloop_else(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue