From a9e731ed5968f812fd7ecbaa37c7c89a1dcec744 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Tue, 24 May 2016 22:14:05 -0400 Subject: [PATCH] Added uiMainStep() and implemented it on Windows. --- ui.h | 1 + windows/main.cpp | 82 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/ui.h b/ui.h index c1d7bb31..adc0b327 100644 --- a/ui.h +++ b/ui.h @@ -36,6 +36,7 @@ _UI_EXTERN void uiUninit(void); _UI_EXTERN void uiFreeInitError(const char *err); _UI_EXTERN void uiMain(void); +_UI_EXTERN int uiMainStep(int wait); _UI_EXTERN void uiQuit(void); _UI_EXTERN void uiQueueMain(void (*f)(void *data), void *data); diff --git a/windows/main.cpp b/windows/main.cpp index 2480cd46..3edd8635 100644 --- a/windows/main.cpp +++ b/windows/main.cpp @@ -41,31 +41,73 @@ void unregisterMessageFilter(void) logLastError(L"error unregistering libui message filter"); } -// TODO http://blogs.msdn.com/b/oldnewthing/archive/2005/04/08/406509.aspx when adding accelerators, TranslateAccelerators() before IsDialogMessage() +// LONGTERM http://blogs.msdn.com/b/oldnewthing/archive/2005/04/08/406509.aspx when adding accelerators, TranslateAccelerators() before IsDialogMessage() + +static void processMessage(MSG *msg) +{ + HWND active; + + // TODO really active? or parentToplevel(msg->hwnd)? + active = GetActiveWindow(); + if (active != NULL) + // TODO find documentation that says IsDialogMessage() calls CallMsgFilter() for us, because that's what's happening + if (IsDialogMessage(active, msg) != 0) + return; + TranslateMessage(msg); + DispatchMessageW(msg); +} + +static int waitMessage(MSG *msg) +{ + int res; + + res = GetMessageW(msg, NULL, 0, 0); + if (res < 0) { + logLastError(L"error calling GetMessage()"); + return 0; // bail out on error + } + return res != 0; // returns false on WM_QUIT +} void uiMain(void) { - MSG msg; - int res; - HWND active; + while (uiMainStep(1)) + ; +} - for (;;) { - res = GetMessageW(&msg, NULL, 0, 0); - if (res < 0) { - logLastError(L"error calling GetMessage()"); - break; // bail out on error - } - if (res == 0) // WM_QUIT - break; - // TODO really active? or parentToplevel(msg->hwnd)? - active = GetActiveWindow(); - if (active != NULL) - // TODO find documentation that says IsDialogMessage() calls CallMsgFilter() for us, because that's what's happening - if (IsDialogMessage(active, &msg) != 0) - continue; - TranslateMessage(&msg); - DispatchMessageW(&msg); +static int peekMessage(MSG *msg) +{ + BOOL res; + + res = PeekMessageW(msg, NULL, 0, 0, PM_REMOVE); + if (res == 0) + return 2; // no message available + if (msg->message != WM_QUIT) + return 1; // a message + return 0; // WM_QUIT +} + +int uiMainStep(int wait) +{ + MSG msg; + + if (wait) { + if (!waitMessage(&msg)) + return 0; + processMessage(&msg); + return 1; } + + // don't wait for a message + switch (peekMessage(&msg)) { + case 0: // quit + // TODO PostQuitMessage() again? + return 0; + case 1: // process a message + processMessage(&msg); + // fall out to the case for no message + } + return 1; // no message } void uiQuit(void)