Started migrating uiWindow on Windows. Oh boy it's UTF-16 time!
This commit is contained in:
parent
d5c06108d6
commit
3f392d04ce
|
@ -71,6 +71,10 @@ bool uiprivSysInit(void *options, uiInitError *err)
|
|||
if (hr != S_OK)
|
||||
return uiprivInitReturnHRESULT(err, "failed to initialize the utility window", hr);
|
||||
|
||||
hr = uiprivRegisterWindowClass(hDefaultIcon, hDefaultCursor);
|
||||
if (hr != S_OK)
|
||||
return uiprivInitReturnHRESULT(err, "failed to register the uiWindow window class", hr);
|
||||
|
||||
ZeroMemory(&icc, sizeof (INITCOMMONCONTROLSEX));
|
||||
icc.dwSize = sizeof (INITCOMMONCONTROLSEX);
|
||||
icc.dwICC = wantedICCClasses;
|
||||
|
|
|
@ -16,3 +16,6 @@ enum {
|
|||
};
|
||||
extern HWND uiprivUtilWindow;
|
||||
extern HRESULT uiprivInitUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor);
|
||||
|
||||
// window.cpp
|
||||
extern HRESULT uiprivRegisterWindowClass(HICON hDefaultIcon, HCURSOR hDefaultCursor);
|
||||
|
|
|
@ -39,6 +39,7 @@ HRESULT uiprivInitUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor)
|
|||
return uiprivHrCreateWindowExW(0,
|
||||
utilWindowClass, L"libui utility window",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
// TODO CW_USEDEFAULT?
|
||||
0, 0, 100, 100,
|
||||
NULL, NULL, uipriv_hInstance, NULL,
|
||||
&uiprivUtilWindow);
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
|
||||
#define windowClass L"libui_uiWindowClass"
|
||||
|
||||
struct uiWindow {
|
||||
uiWindowsControl c;
|
||||
struct windowImplData {
|
||||
HWND hwnd;
|
||||
const char *title;
|
||||
#if 0
|
||||
HMENU menubar;
|
||||
uiControl *child;
|
||||
BOOL shownOnce;
|
||||
|
@ -20,8 +21,12 @@ struct uiWindow {
|
|||
int fullscreen;
|
||||
WINDOWPLACEMENT fsPrevPlacement;
|
||||
int borderless;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if 0
|
||||
// TODO {
|
||||
|
||||
// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
||||
#define windowMargin 7
|
||||
|
||||
|
@ -64,22 +69,11 @@ static void windowRelayout(uiWindow *w)
|
|||
|
||||
static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LONG_PTR ww;
|
||||
uiWindow *w;
|
||||
CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam;
|
||||
WINDOWPOS *wp = (WINDOWPOS *) lParam;
|
||||
MINMAXINFO *mmi = (MINMAXINFO *) lParam;
|
||||
int width, height;
|
||||
LRESULT lResult;
|
||||
|
||||
ww = GetWindowLongPtrW(hwnd, GWLP_USERDATA);
|
||||
if (ww == 0) {
|
||||
if (uMsg == WM_CREATE)
|
||||
SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) (cs->lpCreateParams));
|
||||
// fall through to DefWindowProc() anyway
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
w = uiWindow((void *) ww);
|
||||
if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE)
|
||||
return lResult;
|
||||
switch (uMsg) {
|
||||
|
@ -124,20 +118,6 @@ static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA
|
|||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
ATOM registerWindowClass(HICON hDefaultIcon, HCURSOR hDefaultCursor)
|
||||
{
|
||||
WNDCLASSW wc;
|
||||
|
||||
ZeroMemory(&wc, sizeof (WNDCLASSW));
|
||||
wc.lpszClassName = windowClass;
|
||||
wc.lpfnWndProc = windowWndProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hIcon = hDefaultIcon;
|
||||
wc.hCursor = hDefaultCursor;
|
||||
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
|
||||
return RegisterClassW(&wc);
|
||||
}
|
||||
|
||||
void unregisterWindowClass(void)
|
||||
{
|
||||
if (UnregisterClassW(windowClass, hInstance) == 0)
|
||||
|
@ -465,19 +445,7 @@ uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar)
|
|||
hasMenubarBOOL = TRUE;
|
||||
w->hasMenubar = hasMenubarBOOL;
|
||||
|
||||
#define style WS_OVERLAPPEDWINDOW
|
||||
#define exstyle 0
|
||||
|
||||
wtitle = toUTF16(title);
|
||||
w->hwnd = CreateWindowExW(exstyle,
|
||||
windowClass, wtitle,
|
||||
style,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
// use the raw width and height for now
|
||||
// this will get CW_USEDEFAULT (hopefully) predicting well
|
||||
// even if it doesn't, we're adjusting it later
|
||||
width, height,
|
||||
NULL, NULL, hInstance, w);
|
||||
if (w->hwnd == NULL)
|
||||
logLastError(L"error creating window");
|
||||
uiprivFree(wtitle);
|
||||
|
@ -498,6 +466,156 @@ uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar)
|
|||
return w;
|
||||
}
|
||||
|
||||
// } TODO
|
||||
#endif
|
||||
|
||||
static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LONG_PTR ww;
|
||||
uiWindow *w;
|
||||
struct windowImplData *wi;
|
||||
CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam;
|
||||
|
||||
ww = GetWindowLongPtrW(hwnd, GWLP_USERDATA);
|
||||
if (ww == 0) {
|
||||
if (uMsg == WM_CREATE)
|
||||
SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) (cs->lpCreateParams));
|
||||
// fall through to DefWindowProc() anyway
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
w = uiWindow((void *) ww);
|
||||
wi = (struct windowImplData *) uiControlImplData(uiControl(w));
|
||||
switch (uMsg) {
|
||||
case WM_CLOSE:
|
||||
// don't destroy the window on close; programs decide if they should when handling the closing event
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
HRESULT uiprivRegisterWindowClass(HICON hDefaultIcon, HCURSOR hDefaultCursor)
|
||||
{
|
||||
WNDCLASSW wc;
|
||||
|
||||
ZeroMemory(&wc, sizeof (WNDCLASSW));
|
||||
wc.lpszClassName = windowClass;
|
||||
wc.lpfnWndProc = windowWndProc;
|
||||
wc.hInstance = uipriv_hInstance;
|
||||
wc.hIcon = hDefaultIcon;
|
||||
wc.hCursor = hDefaultCursor;
|
||||
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
|
||||
return uiprivHrRegisterClassW(&wc);
|
||||
}
|
||||
|
||||
static bool windowInit(uiControl *c, void *implData, void *initData)
|
||||
{
|
||||
struct windowImplData *wi = (struct windowImplData *) implData;
|
||||
HRESULT hr;
|
||||
|
||||
#define style WS_OVERLAPPEDWINDOW
|
||||
#define exstyle 0
|
||||
hr = uiprivHrCreateWindowExW(exstyle,
|
||||
windowClass, L"",
|
||||
style,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
NULL, NULL, uipriv_hInstance, c,
|
||||
&(wi->hwnd));
|
||||
if (hr != S_OK) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void windowFree(uiControl *c, void *implData)
|
||||
{
|
||||
struct windowImplData *wi = (struct windowImplData *) implData;
|
||||
|
||||
if (wi->title != NULL) {
|
||||
uiprivFreeUTF8(wi->title);
|
||||
wi->title = NULL;
|
||||
}
|
||||
xxxx
|
||||
}
|
||||
|
||||
static void windowParentChanging(uiControl *c, void *implData, uiControl *oldParent)
|
||||
{
|
||||
uiprivProgrammerErrorCannotHaveWindowsAsChildren();
|
||||
}
|
||||
|
||||
static void windowParentChanged(uiControl *c, void *implData, uiControl *newParent)
|
||||
{
|
||||
uiprivProgrammerErrorCannotHaveWindowsAsChildren();
|
||||
}
|
||||
|
||||
static HWND windowHandle(uiControl *c, void *implData)
|
||||
{
|
||||
struct windowImplData *wi = (struct windowImplData *) implData;
|
||||
|
||||
return wi->hwnd;
|
||||
}
|
||||
|
||||
// gotta do this because of lack of C99-style initializers in C++11
|
||||
// see also https://stackoverflow.com/questions/11516657/c-structure-initialization
|
||||
static const uiControlVtable windowVtable = [](void) {
|
||||
uiControlVtable vt;
|
||||
|
||||
memset(&vt, 0, sizeof (uiControlVtable));
|
||||
vt.Size = sizeof (uiControlVtable);
|
||||
vt.Init = windowInit;
|
||||
vt.Free = windowFree;
|
||||
vt.ParentChanging = windowParentChanging;
|
||||
vt.ParentChanged = windowParentChanged;
|
||||
return vt;
|
||||
}();
|
||||
|
||||
static const uiControlOSVtable windowOSVtable = [](void) {
|
||||
uiControlOSVtable vt;
|
||||
|
||||
memset(&vt, 0, sizeof (uiControlOSVtable));
|
||||
vt.Size = sizeof (uiControlOSVtable);
|
||||
vt.Handle = windowHandle;
|
||||
return vt;
|
||||
}();
|
||||
|
||||
static uint32_t windowType = 0;
|
||||
|
||||
uint32_t uiprivSysWindowType(void)
|
||||
{
|
||||
if (windowType == 0)
|
||||
windowType = uiRegisterControlType("uiWindow", &windowVtable, &windowOSVtable, sizeof (struct windowImplData));
|
||||
return windowType;
|
||||
}
|
||||
|
||||
uiWindow *uiprivSysNewWindow(void)
|
||||
{
|
||||
return (uiWindow *) uiNewControl(uiWindowType(), NULL);
|
||||
}
|
||||
|
||||
const char *uiprivSysWindowTitle(uiWindow *w)
|
||||
{
|
||||
struct windowImplData *wi = (struct windowImplData *) uiControlImplData(uiControl(w));
|
||||
|
||||
if (wi->title == NULL)
|
||||
// TODO replace this with a dedicated UTF-8 empty string object
|
||||
return "";
|
||||
return wi->title;
|
||||
}
|
||||
|
||||
void uiprivSysWindowSetTitle(uiWindow *w, const char *title)
|
||||
{
|
||||
struct windowImplData *wi = (struct windowImplData *) uiControlImplData(uiControl(w));
|
||||
|
||||
if (wi->title != NULL)
|
||||
uiprivFreeUTF8(wi->title);
|
||||
wi->title = uiprivSanitizeUTF8(title);
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
// this cannot queue a resize because it's called by the resize handler
|
||||
void ensureMinimumWindowSize(uiWindow *w)
|
||||
{
|
||||
|
@ -534,3 +652,5 @@ void enableAllWindowsExcept(uiWindow *which)
|
|||
EnableWindow(w.first->hwnd, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue