diff --git a/init_windows.c b/init_windows.c index d525b944..2b24e0ac 100644 --- a/init_windows.c +++ b/init_windows.c @@ -6,8 +6,6 @@ int nCmdShow; HFONT hMessageFont; -HWND initialParent; - struct uiInitError { char *msg; char failbuf[256]; @@ -95,10 +93,9 @@ const char *uiInit(uiInitOptions *o) if (hMessageFont == NULL) return loadLastError("loading default messagebox font; this is the default UI font"); - // give each control a reasonable initial parent - // don't free the initial parent! - // TODO tune this better; it shouldn't be closed, for instance - initialParent = (HWND) uiWindowHandle(uiNewWindow("", 0, 0)); + ce = initInitialParent(hDefaultIcon, hDefaultCursor); + if (ce != NULL) + return loadLastError(ce); return NULL; } diff --git a/initparent_windows.c b/initparent_windows.c new file mode 100644 index 00000000..9f115c16 --- /dev/null +++ b/initparent_windows.c @@ -0,0 +1,46 @@ +// 10 april 2015 +#include "uipriv_windows.h" + +// for maximum safety, all controls that don't have a parent are made children of this, the "initial parent" +// it behaves like other containers due to bugs described in container_windows.c, but is never seen and cannot be interacted with by end users +// despite being called the initial parent, it is used whenever a control has no parent, even if it loses its parent at some later point during the execution of the program + +#define uiInitialParentClass L"uiInitialParentClass" + +HWND initialParent; + +static LRESULT CALLBACK initialParentWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LRESULT lResult; + + if (sharedWndProc(hwnd, uMsg, wParam, lParam, &lResult) != FALSE) + return lResult; + return DefWindowProcW(hwnd, uMsg, wParam, lParam); +} + +const char *initInitialParent(HICON hDefaultIcon, HCURSOR hDefaultCursor) +{ + WNDCLASSW wc; + + ZeroMemory(&wc, sizeof (WNDCLASSW)); + wc.lpszClassName = uiInitialParentClass; + wc.lpfnWndProc = initialParentWndProc; + wc.hInstance = hInstance; + wc.hIcon = hDefaultIcon; + wc.hCursor = hDefaultCursor; + wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); + if (RegisterClassW(&wc) == 0) + return "registering initial parent window class"; + + initialParent = CreateWindowExW(0, + uiInitialParentClass, L"", + WS_OVERLAPPEDWINDOW, + 0, 0, + 100, 100, + NULL, NULL, hInstance, NULL); + if (initialParent == NULL) + return "creating initial parent window"; + + // TODO disable? + return NULL; +} diff --git a/uipriv_windows.h b/uipriv_windows.h index 8e602882..a8cd429c 100644 --- a/uipriv_windows.h +++ b/uipriv_windows.h @@ -64,3 +64,6 @@ extern const char *initCommonControls(void); // window_windows.c extern ATOM registerWindowClass(HICON, HCURSOR); + +// initparent_windows.c +extern const char *initInitialParent(HICON, HCURSOR);