More TODO resolution and elimination and delegation and explanation.
This commit is contained in:
parent
0738eca6e4
commit
a226c80993
|
@ -1,9 +1,6 @@
|
||||||
// 20 may 2015
|
// 20 may 2015
|
||||||
#include "uipriv_windows.hpp"
|
#include "uipriv_windows.hpp"
|
||||||
|
|
||||||
// TODO
|
|
||||||
// - is there extra space on the bottom?
|
|
||||||
|
|
||||||
// we as Common Controls 6 users don't need to worry about the height of comboboxes; see http://blogs.msdn.com/b/oldnewthing/archive/2006/03/10/548537.aspx
|
// we as Common Controls 6 users don't need to worry about the height of comboboxes; see http://blogs.msdn.com/b/oldnewthing/archive/2006/03/10/548537.aspx
|
||||||
|
|
||||||
struct uiCombobox {
|
struct uiCombobox {
|
||||||
|
@ -36,8 +33,8 @@ void uiComboboxDestroy(uiControl *cc)
|
||||||
uiWindowsControlAllDefaultsExceptDestroy(uiCombobox)
|
uiWindowsControlAllDefaultsExceptDestroy(uiCombobox)
|
||||||
|
|
||||||
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
||||||
#define comboboxWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary; TODO */
|
#define comboboxWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary; LONGTERM */
|
||||||
#define comboboxHeight 14
|
#define comboboxHeight 14 /* LONGTERM: is this too high? */
|
||||||
|
|
||||||
static void uiComboboxMinimumSize(uiWindowsControl *cc, intmax_t *width, intmax_t *height)
|
static void uiComboboxMinimumSize(uiWindowsControl *cc, intmax_t *width, intmax_t *height)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
// 20 may 2015
|
// 20 may 2015
|
||||||
#include "uipriv_windows.hpp"
|
#include "uipriv_windows.hpp"
|
||||||
|
|
||||||
// TODO
|
|
||||||
// - is there extra space on the bottom?
|
|
||||||
|
|
||||||
// we as Common Controls 6 users don't need to worry about the height of comboboxes; see http://blogs.msdn.com/b/oldnewthing/archive/2006/03/10/548537.aspx
|
// we as Common Controls 6 users don't need to worry about the height of comboboxes; see http://blogs.msdn.com/b/oldnewthing/archive/2006/03/10/548537.aspx
|
||||||
|
|
||||||
struct uiEditableCombobox {
|
struct uiEditableCombobox {
|
||||||
|
@ -19,11 +16,11 @@ static BOOL onWM_COMMAND(uiControl *cc, HWND hwnd, WORD code, LRESULT *lResult)
|
||||||
|
|
||||||
if (code == CBN_SELCHANGE) {
|
if (code == CBN_SELCHANGE) {
|
||||||
// like on OS X, this is sent before the edit has been updated :(
|
// like on OS X, this is sent before the edit has been updated :(
|
||||||
// TODO error check
|
if (PostMessage(parentOf(hwnd),
|
||||||
PostMessage(parentOf(hwnd),
|
|
||||||
WM_COMMAND,
|
WM_COMMAND,
|
||||||
MAKEWPARAM(GetWindowLongPtrW(hwnd, GWLP_ID), CBN_EDITCHANGE),
|
MAKEWPARAM(GetWindowLongPtrW(hwnd, GWLP_ID), CBN_EDITCHANGE),
|
||||||
(LPARAM) hwnd);
|
(LPARAM) hwnd) == 0)
|
||||||
|
logLastError(L"error posting CBN_EDITCHANGE after CBN_SELCHANGE");
|
||||||
*lResult = 0;
|
*lResult = 0;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -46,8 +43,8 @@ void uiEditableComboboxDestroy(uiControl *cc)
|
||||||
uiWindowsControlAllDefaultsExceptDestroy(uiEditableCombobox)
|
uiWindowsControlAllDefaultsExceptDestroy(uiEditableCombobox)
|
||||||
|
|
||||||
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
||||||
#define comboboxWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary; TODO */
|
#define comboboxWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary; LONGTERM */
|
||||||
#define comboboxHeight 14
|
#define comboboxHeight 14 /* LONGTERM: is this too high? */
|
||||||
|
|
||||||
static void uiEditableComboboxMinimumSize(uiWindowsControl *cc, intmax_t *width, intmax_t *height)
|
static void uiEditableComboboxMinimumSize(uiWindowsControl *cc, intmax_t *width, intmax_t *height)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@ static void updateFontButtonLabel(uiFontButton *b)
|
||||||
WCHAR *text;
|
WCHAR *text;
|
||||||
|
|
||||||
text = fontDialogParamsToString(&(b->params));
|
text = fontDialogParamsToString(&(b->params));
|
||||||
setWindowText(text);
|
setWindowText(b->hwnd, text);
|
||||||
uiFree(text);
|
uiFree(text);
|
||||||
|
|
||||||
// changing the text might necessitate a change in the button's size
|
// changing the text might necessitate a change in the button's size
|
||||||
|
|
|
@ -93,15 +93,18 @@ static void uiGroupMinimumSize(uiWindowsControl *c, intmax_t *width, intmax_t *h
|
||||||
{
|
{
|
||||||
uiGroup *g = uiGroup(c);
|
uiGroup *g = uiGroup(c);
|
||||||
int mx, mtop, mbottom;
|
int mx, mtop, mbottom;
|
||||||
|
intmax_t labelWidth;
|
||||||
|
|
||||||
*width = 0;
|
*width = 0;
|
||||||
*height = 0;
|
*height = 0;
|
||||||
if (g->child != NULL)
|
if (g->child != NULL)
|
||||||
uiWindowsControlMinimumSize(uiWindowsControl(g->child), width, height);
|
uiWindowsControlMinimumSize(uiWindowsControl(g->child), width, height);
|
||||||
|
labelWidth = uiWindowsWindowTextWidth(g->hwnd);
|
||||||
|
if (*width < labelWidth) // don't clip the label; it doesn't ellipsize
|
||||||
|
*width = labelWidth;
|
||||||
groupMargins(g, &mx, &mtop, &mbottom);
|
groupMargins(g, &mx, &mtop, &mbottom);
|
||||||
*width += 2 * mx;
|
*width += 2 * mx;
|
||||||
*height += mtop + mbottom;
|
*height += mtop + mbottom;
|
||||||
// TODO label width? and when?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uiGroupMinimumSizeChanged(uiWindowsControl *c)
|
static void uiGroupMinimumSizeChanged(uiWindowsControl *c)
|
||||||
|
@ -159,18 +162,25 @@ void uiGroupSetMargined(uiGroup *g, int margined)
|
||||||
static LRESULT CALLBACK groupSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
|
static LRESULT CALLBACK groupSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
|
||||||
{
|
{
|
||||||
uiGroup *g = uiGroup(dwRefData);
|
uiGroup *g = uiGroup(dwRefData);
|
||||||
|
WINDOWPOS *wp = (WINDOWPOS *) lParam;
|
||||||
|
MINMAXINFO *mmi = (MINMAXINFO *) lParam;
|
||||||
|
intmax_t minwid, minht;
|
||||||
LRESULT lResult;
|
LRESULT lResult;
|
||||||
|
|
||||||
if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE)
|
if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE)
|
||||||
return lResult;
|
return lResult;
|
||||||
switch (uMsg) {
|
switch (uMsg) {
|
||||||
case WM_WINDOWPOSCHANGED:
|
case WM_WINDOWPOSCHANGED:
|
||||||
// TODO check
|
if ((wp->flags & SWP_NOSIZE) != 0)
|
||||||
// TODO add check in container.c
|
break;
|
||||||
groupRelayout(g);
|
groupRelayout(g);
|
||||||
// TODO is this right?
|
return 0;
|
||||||
break;
|
case WM_GETMINMAXINFO:
|
||||||
// TODO WM_GETMINMAXINFO
|
lResult = DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||||
|
uiWindowsControlMinimumSize(uiWindowsControl(g), &minwid, &minht);
|
||||||
|
mmi->ptMinTrackSize.x = minwid;
|
||||||
|
mmi->ptMinTrackSize.y = minht;
|
||||||
|
return lResult;
|
||||||
case WM_NCDESTROY:
|
case WM_NCDESTROY:
|
||||||
if (RemoveWindowSubclass(hwnd, groupSubProc, uIdSubclass) == FALSE)
|
if (RemoveWindowSubclass(hwnd, groupSubProc, uIdSubclass) == FALSE)
|
||||||
logLastError(L"error removing groupbox subclass");
|
logLastError(L"error removing groupbox subclass");
|
||||||
|
|
|
@ -6,7 +6,7 @@ int nCmdShow;
|
||||||
|
|
||||||
HFONT hMessageFont;
|
HFONT hMessageFont;
|
||||||
|
|
||||||
// TODO needed?
|
// LONGTERM needed?
|
||||||
HBRUSH hollowBrush;
|
HBRUSH hollowBrush;
|
||||||
|
|
||||||
// the returned pointer is actually to the second character
|
// the returned pointer is actually to the second character
|
||||||
|
@ -38,7 +38,7 @@ static const char *initerr(const char *message, const WCHAR *label, DWORD value)
|
||||||
#define ieLastErr(msg) initerr("=" msg, L"GetLastError() ==", GetLastError())
|
#define ieLastErr(msg) initerr("=" msg, L"GetLastError() ==", GetLastError())
|
||||||
#define ieHRESULT(msg, hr) initerr("=" msg, L"HRESULT", (DWORD) hr)
|
#define ieHRESULT(msg, hr) initerr("=" msg, L"HRESULT", (DWORD) hr)
|
||||||
|
|
||||||
// TODO make common
|
// LONGTERM make common
|
||||||
uiInitOptions options;
|
uiInitOptions options;
|
||||||
|
|
||||||
#define wantedICCClasses ( \
|
#define wantedICCClasses ( \
|
||||||
|
@ -70,6 +70,8 @@ const char *uiInit(uiInitOptions *o)
|
||||||
if ((si.dwFlags & STARTF_USESHOWWINDOW) != 0)
|
if ((si.dwFlags & STARTF_USESHOWWINDOW) != 0)
|
||||||
nCmdShow = si.wShowWindow;
|
nCmdShow = si.wShowWindow;
|
||||||
|
|
||||||
|
// LONGTERM set DPI awareness
|
||||||
|
|
||||||
hDefaultIcon = LoadIconW(NULL, IDI_APPLICATION);
|
hDefaultIcon = LoadIconW(NULL, IDI_APPLICATION);
|
||||||
if (hDefaultIcon == NULL)
|
if (hDefaultIcon == NULL)
|
||||||
return ieLastErr("loading default icon for window classes");
|
return ieLastErr("loading default icon for window classes");
|
||||||
|
@ -79,7 +81,7 @@ const char *uiInit(uiInitOptions *o)
|
||||||
|
|
||||||
ce = initUtilWindow(hDefaultIcon, hDefaultCursor);
|
ce = initUtilWindow(hDefaultIcon, hDefaultCursor);
|
||||||
if (ce != NULL)
|
if (ce != NULL)
|
||||||
return ieLastErr("TODO use ce here");
|
return initerr(ce, L"GetLastError() ==", GetLastError());
|
||||||
|
|
||||||
if (registerWindowClass(hDefaultIcon, hDefaultCursor) == 0)
|
if (registerWindowClass(hDefaultIcon, hDefaultCursor) == 0)
|
||||||
return ieLastErr("registering uiWindow window class");
|
return ieLastErr("registering uiWindow window class");
|
||||||
|
@ -92,9 +94,8 @@ const char *uiInit(uiInitOptions *o)
|
||||||
if (hMessageFont == NULL)
|
if (hMessageFont == NULL)
|
||||||
return ieLastErr("loading default messagebox font; this is the default UI font");
|
return ieLastErr("loading default messagebox font; this is the default UI font");
|
||||||
|
|
||||||
// TODO rewrite this error message
|
|
||||||
if (initContainer(hDefaultIcon, hDefaultCursor) == 0)
|
if (initContainer(hDefaultIcon, hDefaultCursor) == 0)
|
||||||
return ieLastErr("initializing uiMakeContainer() window class");
|
return ieLastErr("initializing uiWindowsMakeContainer() window class");
|
||||||
|
|
||||||
hollowBrush = (HBRUSH) GetStockObject(HOLLOW_BRUSH);
|
hollowBrush = (HBRUSH) GetStockObject(HOLLOW_BRUSH);
|
||||||
if (hollowBrush == NULL)
|
if (hollowBrush == NULL)
|
||||||
|
@ -109,8 +110,8 @@ const char *uiInit(uiInitOptions *o)
|
||||||
hr = CoInitialize(NULL);
|
hr = CoInitialize(NULL);
|
||||||
if (hr != S_OK && hr != S_FALSE)
|
if (hr != S_OK && hr != S_FALSE)
|
||||||
return ieHRESULT("initializing COM", hr);
|
return ieHRESULT("initializing COM", hr);
|
||||||
// TODO initialize COM security
|
// LONGTERM initialize COM security
|
||||||
// TODO (windows vista) turn off COM exception handling
|
// LONGTERM (windows vista) turn off COM exception handling
|
||||||
|
|
||||||
hr = initDraw();
|
hr = initDraw();
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
|
|
|
@ -45,13 +45,15 @@ void unregisterMessageFilter(void)
|
||||||
|
|
||||||
static void processMessage(MSG *msg)
|
static void processMessage(MSG *msg)
|
||||||
{
|
{
|
||||||
HWND active;
|
HWND correctParent;
|
||||||
|
|
||||||
// TODO really active? or parentToplevel(msg->hwnd)?
|
if (msg->hwnd != NULL)
|
||||||
active = GetActiveWindow();
|
correctParent = parentToplevel(msg->hwnd);
|
||||||
if (active != NULL)
|
else // just to be safe
|
||||||
// TODO find documentation that says IsDialogMessage() calls CallMsgFilter() for us, because that's what's happening
|
correctParent = GetActiveWindow();
|
||||||
if (IsDialogMessage(active, msg) != 0)
|
if (correctParent != NULL)
|
||||||
|
// this calls our mesage filter above for us
|
||||||
|
if (IsDialogMessage(correctParent, msg) != 0)
|
||||||
return;
|
return;
|
||||||
TranslateMessage(msg);
|
TranslateMessage(msg);
|
||||||
DispatchMessageW(msg);
|
DispatchMessageW(msg);
|
||||||
|
@ -118,6 +120,6 @@ void uiQuit(void)
|
||||||
void uiQueueMain(void (*f)(void *data), void *data)
|
void uiQueueMain(void (*f)(void *data), void *data)
|
||||||
{
|
{
|
||||||
if (PostMessageW(utilWindow, msgQueued, (WPARAM) f, (LPARAM) data) == 0)
|
if (PostMessageW(utilWindow, msgQueued, (WPARAM) f, (LPARAM) data) == 0)
|
||||||
// TODO this is likely not safe to call across threads (allocates memory)
|
// LONGTERM this is likely not safe to call across threads (allocates memory)
|
||||||
logLastError(L"error queueing function to run on main thread");
|
logLastError(L"error queueing function to run on main thread");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// 24 april 2015
|
// 24 april 2015
|
||||||
#include "uipriv_windows.hpp"
|
#include "uipriv_windows.hpp"
|
||||||
|
|
||||||
// TODO migrate to std::vector
|
// LONGTERM migrate to std::vector
|
||||||
|
|
||||||
static uiMenu **menus = NULL;
|
static uiMenu **menus = NULL;
|
||||||
static uintmax_t len = 0;
|
static uintmax_t len = 0;
|
||||||
|
@ -146,10 +146,12 @@ static uiMenuItem *newItem(uiMenu *m, int type, const char *name)
|
||||||
curID++;
|
curID++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO copy this from the unix one
|
if (item->type == typeQuit) {
|
||||||
item->onClicked = defaultOnClicked;
|
// can't call uiMenuItemOnClicked() here
|
||||||
if (item->type == typeQuit)
|
|
||||||
item->onClicked = onQuitClicked;
|
item->onClicked = onQuitClicked;
|
||||||
|
item->onClickedData = NULL;
|
||||||
|
} else
|
||||||
|
uiMenuItemOnClicked(item, defaultOnClicked, NULL);
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -185,7 +187,7 @@ uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m)
|
||||||
uiMenuItem *uiMenuAppendAboutItem(uiMenu *m)
|
uiMenuItem *uiMenuAppendAboutItem(uiMenu *m)
|
||||||
{
|
{
|
||||||
if (hasAbout)
|
if (hasAbout)
|
||||||
// TODO place these userbug strings in a header?
|
// TODO place these userbug strings in a header
|
||||||
userbug("You can not have multiple About menu items in a program.");
|
userbug("You can not have multiple About menu items in a program.");
|
||||||
hasAbout = TRUE;
|
hasAbout = TRUE;
|
||||||
newItem(m, typeSeparator, NULL);
|
newItem(m, typeSeparator, NULL);
|
||||||
|
@ -350,7 +352,7 @@ void uninitMenus(void)
|
||||||
for (j = 0; j < m->len; j++) {
|
for (j = 0; j < m->len; j++) {
|
||||||
item = m->items[j];
|
item = m->items[j];
|
||||||
if (item->len != 0)
|
if (item->len != 0)
|
||||||
// TODO userbug()?
|
// LONGTERM userbug()?
|
||||||
implbug("menu item %p (%ws) still has uiWindows attached; did you forget to destroy some windows?", item, item->name);
|
implbug("menu item %p (%ws) still has uiWindows attached; did you forget to destroy some windows?", item, item->name);
|
||||||
if (item->name != NULL)
|
if (item->name != NULL)
|
||||||
uiFree(item->name);
|
uiFree(item->name);
|
||||||
|
|
|
@ -51,7 +51,8 @@ const char *initUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor)
|
||||||
wc.hCursor = hDefaultCursor;
|
wc.hCursor = hDefaultCursor;
|
||||||
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
|
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
|
||||||
if (RegisterClass(&wc) == 0)
|
if (RegisterClass(&wc) == 0)
|
||||||
return "registering utility window class";
|
// see init.cpp for an explanation of the =s
|
||||||
|
return "=registering utility window class";
|
||||||
|
|
||||||
utilWindow = CreateWindowExW(0,
|
utilWindow = CreateWindowExW(0,
|
||||||
utilWindowClass, L"libui utility window",
|
utilWindowClass, L"libui utility window",
|
||||||
|
@ -59,7 +60,7 @@ const char *initUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor)
|
||||||
0, 0, 100, 100,
|
0, 0, 100, 100,
|
||||||
NULL, NULL, hInstance, NULL);
|
NULL, NULL, hInstance, NULL);
|
||||||
if (utilWindow == NULL)
|
if (utilWindow == NULL)
|
||||||
return "creating utility window";
|
return "=creating utility window";
|
||||||
// and just to be safe
|
// and just to be safe
|
||||||
EnableWindow(utilWindow, FALSE);
|
EnableWindow(utilWindow, FALSE);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue