diff options
Diffstat (limited to 'new/windows/newcontrol.c')
| -rw-r--r-- | new/windows/newcontrol.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/new/windows/newcontrol.c b/new/windows/newcontrol.c new file mode 100644 index 0000000..105b70c --- /dev/null +++ b/new/windows/newcontrol.c @@ -0,0 +1,241 @@ +// 6 april 2015 +#include "uipriv_windows.h" + +typedef struct singleHWND singleHWND; + +struct singleHWND { + HWND hwnd; + BOOL (*onWM_COMMAND)(uiControl *, WORD, LRESULT *); + BOOL (*onWM_NOTIFY)(uiControl *, NMHDR *, LRESULT *); + void (*onWM_DESTROY)(uiControl *); + uiParent *parent; + BOOL userHid; + BOOL containerHid; + BOOL userDisabled; + BOOL containerDisabled; +}; + +static void singleDestroy(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->internal); + + if (DestroyWindow(s->hwnd) == 0) + logLastError("error destroying control in singleDestroy()"); + // the data structures are destroyed in the subclass procedure +} + +static uintptr_t singleHandle(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->internal); + + return (uintptr_t) (s->hwnd); +} + +static void singleSetParent(uiControl *c, uiParent *parent) +{ + singleHWND *s = (singleHWND *) (c->internal); + uiParent *oldparent; + HWND newParentHWND; + + oldparent = s->parent; + s->parent = parent; + newParentHWND = initialParent; + if (s->parent != NULL) + newParentHWND = uiParentHWND(s->parent); + if (SetParent(s->hwnd, newParentHWND) == NULL) + logLastError("error setting control parent in singleSetParent()"); + if (oldparent != NULL) + uiParentUpdate(oldparent); + if (s->parent != NULL) + uiParentUpdate(s->parent); +} + +static void singleResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d) +{ + singleHWND *s = (singleHWND *) (c->internal); + + if (MoveWindow(s->hwnd, x, y, width, height, TRUE) == 0) + logLastError("error moving control in singleResize()"); +} + +static int singleVisible(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->internal); + + if (s->userHid) + return 0; + return 1; +} + +static void singleShow(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->internal); + + s->userHid = FALSE; + if (!s->containerHid) { + ShowWindow(s->hwnd, SW_SHOW); + if (s->parent != NULL) + uiParentUpdate(s->parent); + } +} + +static void singleHide(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->internal); + + s->userHid = TRUE; + ShowWindow(s->hwnd, SW_HIDE); + if (s->parent != NULL) + uiParentUpdate(s->parent); +} + +static void singleContainerShow(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->internal); + + s->containerHid = FALSE; + if (!s->userHid) { + ShowWindow(s->hwnd, SW_SHOW); + if (s->parent != NULL) + uiParentUpdate(s->parent); + } +} + +static void singleContainerHide(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->internal); + + s->containerHid = TRUE; + ShowWindow(s->hwnd, SW_HIDE); + if (s->parent != NULL) + uiParentUpdate(s->parent); +} + +static void singleEnable(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->internal); + + s->userDisabled = FALSE; + if (!s->containerDisabled) + EnableWindow(s->hwnd, TRUE); +} + +static void singleDisable(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->internal); + + s->userDisabled = TRUE; + EnableWindow(s->hwnd, FALSE); +} + +static void singleContainerEnable(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->internal); + + s->containerDisabled = FALSE; + if (!s->userDisabled) + EnableWindow(s->hwnd, TRUE); +} + +static void singleContainerDisable(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->internal); + + s->containerDisabled = TRUE; + EnableWindow(s->hwnd, FALSE); +} + +static LRESULT CALLBACK singleSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) +{ + uiControl *c = (uiControl *) dwRefData; + singleHWND *s = (singleHWND *) (c->internal); + LRESULT lResult; + + switch (uMsg) { + case msgCOMMAND: + if ((*(s->onWM_COMMAND))(c, HIWORD(wParam), &lResult) != FALSE) + return lResult; + break; + case msgNOTIFY: + if ((*(s->onWM_NOTIFY))(c, (NMHDR *) lParam, &lResult) != FALSE) + return lResult; + break; + case WM_DESTROY: + (*(s->onWM_DESTROY))(c); + uiFree(s); + uiFree(c); + break; + case WM_NCDESTROY: + if ((*fv_RemoveWindowSubclass)(hwnd, singleSubclassProc, uIdSubclass) == FALSE) + logLastError("error removing Windows control subclass in singleSubclassProc()"); + break; + } + return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam); +} + +uiControl *uiWindowsNewControl(uiWindowsNewControlParams *p) +{ + uiControl *c; + singleHWND *s; + + s = uiNew(singleHWND); + s->hwnd = CreateWindowExW(p->dwExStyle, + p->lpClassName, p->lpWindowName, + p->dwStyle | WS_CHILD | WS_VISIBLE, + 0, 0, + // use a nonzero initial size just in case some control breaks with a zero initial size + 100, 100, + initialParent, NULL, p->hInstance, NULL); + if (s->hwnd == NULL) + logLastError("error creating control in uiWindowsNewControl()"); + s->onWM_COMMAND = p->onWM_COMMAND; + s->onWM_NOTIFY = p->onWM_NOTIFY; + s->onWM_DESTROY = p->onWM_DESTROY; + + c = uiNew(uiControl); + c->destroy = singleDestroy; + c->handle = singleHandle; + c->setParent = singleSetParent; + c->resize = singleResize; + c->visible = singleVisible; + c->show = singleShow; + c->hide = singleHide; + c->containerShow = singleContainerShow; + c->containerHide = singleContainerHide; + c->enable = singleEnable; + c->disable = singleDisable; + c->containerEnable = singleContainerEnable; + c->containerDisable = singleContainerDisable; + + if (p->useStandardControlFont) + SendMessageW(s->hwnd, WM_SETFONT, (WPARAM) hMessageFont, (LPARAM) TRUE); + + if ((*fv_SetWindowSubclass)(s->hwnd, singleSubclassProc, 0, (DWORD_PTR) c) == FALSE) + logLastError("error subclassing Windows control in uiWindowsNewControl()"); + + c->internal = s; + return c; +} + +char *uiWindowsControlText(uiControl *c) +{ + singleHWND *s = (singleHWND *) (c->internal); + WCHAR *wtext; + char *text; + + wtext = windowText(s->hwnd); + text = toUTF8(wtext); + uiFree(wtext); + return text; +} + +void uiWindowsControlSetText(uiControl *c, const char *text) +{ + singleHWND *s = (singleHWND *) (c->internal); + WCHAR *wtext; + + wtext = toUTF16(text); + if (SetWindowTextW(s->hwnd, wtext) == 0) + logLastError("error setting control text in uiWindowsControlSetText()"); + uiFree(wtext); +} |
