Started a major overhaul of the control system on Windows. Events are now handled using registered handlers rather than having them be part of the singleHWND. This is needed for radio buttons. Right now, only WM_COMMAND has been modified as such.
This commit is contained in:
parent
02c81c7b0d
commit
6a6ddc61f9
|
@ -9,6 +9,7 @@ osCFILES = \
|
|||
windows/control.c \
|
||||
windows/debug.c \
|
||||
windows/entry.c \
|
||||
windows/events.c \
|
||||
windows/group.c \
|
||||
windows/init.c \
|
||||
windows/label.c \
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
struct singleHWND {
|
||||
uiControl *c;
|
||||
HWND hwnd;
|
||||
BOOL (*onWM_COMMAND)(uiControl *, WORD, LRESULT *);
|
||||
BOOL (*onWM_NOTIFY)(uiControl *, NMHDR *, LRESULT *);
|
||||
BOOL (*onWM_HSCROLL)(uiControl *, WORD, LRESULT *);
|
||||
void (*onDestroy)(void *);
|
||||
|
@ -16,6 +15,7 @@ void osSingleDestroy(void *internal)
|
|||
struct singleHWND *s = (struct singleHWND *) internal;
|
||||
|
||||
(*(s->onDestroy))(s->onDestroyData);
|
||||
uiWindowsUnregisterWM_COMMANDHandler(s->hwnd);
|
||||
if (DestroyWindow(s->hwnd) == 0)
|
||||
logLastError("error destroying control in singleDestroy()");
|
||||
uiFree(s);
|
||||
|
@ -110,10 +110,6 @@ static LRESULT CALLBACK singleSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
|
|||
LRESULT lResult;
|
||||
|
||||
switch (uMsg) {
|
||||
case msgCOMMAND:
|
||||
if ((*(s->onWM_COMMAND))(s->c, HIWORD(wParam), &lResult) != FALSE)
|
||||
return lResult;
|
||||
break;
|
||||
case msgNOTIFY:
|
||||
if ((*(s->onWM_NOTIFY))(s->c, (NMHDR *) lParam, &lResult) != FALSE)
|
||||
return lResult;
|
||||
|
@ -145,7 +141,8 @@ void uiWindowsMakeControl(uiControl *c, uiWindowsMakeControlParams *p)
|
|||
utilWindow, NULL, p->hInstance, p->lpParam);
|
||||
if (s->hwnd == NULL)
|
||||
logLastError("error creating control in uiWindowsMakeControl()");
|
||||
s->onWM_COMMAND = p->onWM_COMMAND;
|
||||
|
||||
uiWindowsRegisterWM_COMMANDHandler(s->hwnd, p->onWM_COMMAND, uiControl(c));
|
||||
s->onWM_NOTIFY = p->onWM_NOTIFY;
|
||||
s->onWM_HSCROLL = p->onWM_HSCROLL;
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
// 20 may 2015
|
||||
#include "uipriv_windows.h"
|
||||
|
||||
// TODO switch to uthash
|
||||
|
||||
struct commandHandler {
|
||||
HWND hwnd;
|
||||
BOOL (*handler)(uiControl *, WORD, LRESULT *);
|
||||
uiControl *c;
|
||||
};
|
||||
|
||||
struct notifyHandler {
|
||||
HWND hwnd;
|
||||
BOOL (*handler)(uiControl *, NMHDR *, LRESULT *);
|
||||
uiControl *c;
|
||||
};
|
||||
|
||||
struct hscrollHandler {
|
||||
HWND hwnd;
|
||||
BOOL (*handler)(uiControl *, WORD, LRESULT *);
|
||||
uiControl *c;
|
||||
};
|
||||
|
||||
struct ptrArray *commandHandlers = NULL;
|
||||
struct ptrArray *notifyHandlers = NULL;
|
||||
struct ptrArray *hscrollHandlers = NULL;
|
||||
|
||||
void uiWindowsRegisterWM_COMMANDHandler(HWND hwnd, BOOL (*handler)(uiControl *, WORD, LRESULT *), uiControl *c)
|
||||
{
|
||||
struct commandHandler *ch;
|
||||
|
||||
ch = uiNew(struct commandHandler);
|
||||
ch->hwnd = hwnd;
|
||||
ch->handler = handler;
|
||||
ch->c = c;
|
||||
if (commandHandlers == NULL)
|
||||
commandHandlers = newPtrArray();
|
||||
ptrArrayAppend(commandHandlers, ch);
|
||||
}
|
||||
|
||||
void uiWindowsUnregisterWM_COMMANDHandler(HWND hwnd)
|
||||
{
|
||||
struct commandHandler *ch;
|
||||
uintmax_t i;
|
||||
|
||||
for (i = 0; i < commandHandlers->len; i++) {
|
||||
ch = ptrArrayIndex(commandHandlers, struct commandHandler *, i);
|
||||
if (ch->hwnd == hwnd) {
|
||||
ptrArrayDelete(commandHandlers, i);
|
||||
uiFree(ch);
|
||||
if (commandHandlers->len == 0) {
|
||||
ptrArrayDestroy(commandHandlers);
|
||||
commandHandlers = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
complain("window handle %p not registered with a WM_COMMAND handler in uiWindowsUnregisterWM_COMMANDHandler()", hwnd);
|
||||
}
|
||||
|
||||
BOOL runWM_COMMAND(WPARAM wParam, LPARAM lParam, LRESULT *lResult)
|
||||
{
|
||||
HWND control;
|
||||
struct commandHandler *ch;
|
||||
uintmax_t i;
|
||||
|
||||
// bounce back to the control in question
|
||||
// don't bounce back if to the utility window, in which case act as if the message was ignored
|
||||
control = (HWND) lParam;
|
||||
if (control != NULL && IsChild(utilWindow, control) == 0) {
|
||||
for (i = 0; i < commandHandlers->len; i++) {
|
||||
ch = ptrArrayIndex(commandHandlers, struct commandHandler *, i);
|
||||
if (ch->hwnd == control)
|
||||
return (*(ch->handler))(ch->c, HIWORD(wParam), lResult);
|
||||
}
|
||||
// not registered; fall out to return FALSE
|
||||
}
|
||||
return FALSE;
|
||||
}
|
|
@ -111,14 +111,7 @@ BOOL handleParentMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LR
|
|||
|
||||
switch (uMsg) {
|
||||
case WM_COMMAND:
|
||||
// bounce back to the control in question
|
||||
// except if to the initial parent, in which case act as if the message was ignored
|
||||
control = (HWND) lParam;
|
||||
if (control != NULL && IsChild(utilWindow, control) == 0) {
|
||||
*lResult = SendMessageW(control, msgCOMMAND, wParam, lParam);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
return runWM_COMMAND(wParam, lParam, lResult);
|
||||
case WM_NOTIFY:
|
||||
// same as WM_COMMAND
|
||||
control = nm->hwndFrom;
|
||||
|
|
|
@ -108,3 +108,9 @@ extern void uninitAlloc(void);
|
|||
// tab.c
|
||||
extern void tabEnterTabNavigation(HWND);
|
||||
extern void tabLeaveTabNavigation(HWND);
|
||||
|
||||
// events.c
|
||||
// TODO split the uiWindows ones to ui_windows.h
|
||||
extern void uiWindowsRegisterWM_COMMANDHandler(HWND, BOOL (*)(uiControl *, WORD, LRESULT *), uiControl *);
|
||||
extern void uiWindowsUnregisterWM_COMMANDHandler(HWND);
|
||||
extern BOOL runWM_COMMAND(WPARAM, LPARAM, LRESULT *);
|
||||
|
|
Loading…
Reference in New Issue