From 2f657576acbf8acd9a3b23586c1ee48480346c3f Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Thu, 14 May 2015 11:19:52 -0400 Subject: [PATCH] Wrote code for a new utility window in the Windows backend to replace the initialParent. --- redo/windows/uipriv_windows.h | 4 ++ redo/windows/utilwin.c | 80 +++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 redo/windows/utilwin.c diff --git a/redo/windows/uipriv_windows.h b/redo/windows/uipriv_windows.h index 1d883903..e61b37ad 100644 --- a/redo/windows/uipriv_windows.h +++ b/redo/windows/uipriv_windows.h @@ -104,3 +104,7 @@ extern void queueResize(uiControl *); extern void doResizes(void); extern void moveWindow(HWND, intmax_t, intmax_t, intmax_t, intmax_t); extern void moveAndReorderWindow(HWND, HWND, intmax_t, intmax_t, intmax_t, intmax_t); + +// utilwindow.c +extern const char *initUtilWindow(HICON, HCURSOR); +extern void uninitUtilWindow(void); diff --git a/redo/windows/utilwin.c b/redo/windows/utilwin.c new file mode 100644 index 00000000..76b90600 --- /dev/null +++ b/redo/windows/utilwin.c @@ -0,0 +1,80 @@ +// 14 may 2015 +#include "uipriv_windows.h" + +// The utility window is a special window that performs certain tasks internal to libui. +// It is not a message-only window, and it is always hidden and disabled. +// Its roles: +// - It is the initial parent of all controls. When a control loses its parent, it also becomes that control's parent. +// - It handles WM_QUERYENDSESSION and console end session requests. +// - It has a timer to run resizes. + +#define utilWindowClass L"libui_utilWindowClass" + +HWND utilWindow; + +#define resizeTimerID 15 /* a safe number */ +#define resizeTimerInterval 15 + +static LRESULT CALLBACK utilWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LRESULT lResult; + + if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE) + return lResult; + switch (uMsg) { + case WM_QUERYENDSESSION: + case msgConsoleEndSession: + // TODO block handler + if (shouldQuit()) { + uiQuit(); + return TRUE; + } + return FALSE; + case WM_TIMER: + if (wParam != resizeTimerID) + break; + if (SetTimer(utilWindow, resizeTimerID, resizeTimerInterval, NULL) == 0) + logLastError("error resetting resize timer in utilWindowWndProc()"); + doResizes(); + return TODO; + } + return DefWindowProcW(hwnd, uMsg, wParam, lParam); +} + +const char *initUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor) +{ + WNDCLASSW wc; + + ZeroMemoryW(&wc, sizeof (WNDCLASSW)); + wc.lpszClassName = utilWindowClass; + wc.lpfnWndProc = utilWindowWndProc; + wc.hInstance = hInstance; + wc.hIcon = hDefaultIcon; + wc.hCursor = hDefaultCursor; + wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); + if (RegisterClass(&wc) == 0) + return "registering utility window class"; + + utilWindow = CreateWindowExW(0, + utilWindowClass, L"libui utility window", + WS_OVERLAPPEDWINDOW, + 0, 0, 100, 100, + NULL, NULL, hInstance, NULL); + if (utilWindow == NULL) + return "creating utility window"; + // and just to be safe + EnableWindow(utilWindow, FALSE); + + if (SetTimer(utilWindow, resizeTimerID, resizeTimerInterval, NULL) == 0) + return "starting resize timer"; +} + +void uninitUtilWindow(void) +{ + if (KillTimer(utilWindow, resizeTimerID) == 0) + logLastError("error stopping resize timer in uninitUtilWindow()"); + if (DestroyWindow(utilWindow) == 0) + logLastError("error destroying utility window in uninitUtilWindow()"); + if (UnregisterClass(utilWindowClass, hInstance) == 0) + logLastError("error unregistering utility window class in uninitUtilWindow()"); +}