diff --git a/winarea_d2d/area.h b/winarea_d2d/area.h deleted file mode 100644 index 19b632bd..00000000 --- a/winarea_d2d/area.h +++ /dev/null @@ -1,21 +0,0 @@ -// 8 september 2015 -#include "../windows/winapi.h" -#include -#include -#include "ui.h" -#include "uipriv.h" -#include "uipriv_windows.h" - -extern HINSTANCE hInstance; - -extern ATOM registerAreaClass(void); -extern void unregisterAreaClass(void); -extern HWND makeArea(DWORD exstyle, DWORD style, int x, int y, int cx, int cy, HWND parent, uiAreaHandler *ah); - -extern HRESULT logLastError(const char *); -extern HRESULT logHRESULT(const char *, HRESULT); -extern HRESULT logMemoryExhausted(const char *); - -extern uiDrawContext *newContext(ID2D1RenderTarget *); - -extern void areaUpdateScroll(HWND); diff --git a/winarea_d2d/uipriv_windows.h b/winarea_d2d/uipriv_windows.h deleted file mode 100644 index 5a554ecc..00000000 --- a/winarea_d2d/uipriv_windows.h +++ /dev/null @@ -1,6 +0,0 @@ -// 16 september 2015 - -// draw.c -extern HRESULT initDraw(void); -extern void uninitDraw(void); -extern ID2D1HwndRenderTarget *makeHWNDRenderTarget(HWND hwnd); diff --git a/windows/GNUmakeinc.mk b/windows/GNUmakeinc.mk index 403bd645..cefdfed7 100644 --- a/windows/GNUmakeinc.mk +++ b/windows/GNUmakeinc.mk @@ -2,6 +2,7 @@ osCFILES = \ windows/alloc.c \ + windows/area.c \ windows/box.c \ windows/button.c \ windows/checkbox.c \ @@ -12,6 +13,7 @@ osCFILES = \ windows/datetimepicker.c \ windows/debug.c \ windows/dialoghelper.c \ + windows/draw.c \ windows/entry.c \ windows/events.c \ windows/group.c \ @@ -49,7 +51,7 @@ osCFLAGS = \ osLDFLAGS = \ -static-libgcc \ - -luser32 -lkernel32 -lgdi32 -lcomctl32 -luxtheme -lmsimg32 -lcomdlg32 -lole32 -loleaut32 -loleacc -luuid + -luser32 -lkernel32 -lgdi32 -lcomctl32 -luxtheme -lmsimg32 -lcomdlg32 -ld2d1 -lole32 -loleaut32 -loleacc -luuid osLDWarnUndefinedFlags = -Wl,--no-undefined -Wl,--no-allow-shlib-undefined diff --git a/winarea_d2d/area.c b/windows/area.c similarity index 95% rename from winarea_d2d/area.c rename to windows/area.c index f4e37551..579c3dc5 100644 --- a/winarea_d2d/area.c +++ b/windows/area.c @@ -1,13 +1,13 @@ // 8 september 2015 -#include "area.h" +#include "uipriv_windows.h" // TODOs // - things look very wrong on initial draw - -#define areaClass L"libui_uiAreaClass" +// - initial scrolling is not set properly +// - should background be inherited from parent control? struct uiArea { -// uiWindowsControl c; + uiWindowsControl c; HWND hwnd; uiAreaHandler *ah; intmax_t hscrollpos; @@ -19,6 +19,11 @@ struct uiArea { ID2D1HwndRenderTarget *rt; }; +uiWindowsDefineControl( + uiArea, // type name + uiAreaType // type function +) + static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *client, RECT *clip) { uiAreaHandler *ah = a->ah; @@ -617,19 +622,20 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM return DefWindowProc(hwnd, uMsg, wParam, lParam); } +// control implementation + +static void minimumSize(uiWindowsControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height) +{ + // TODO + *width = 0; + *height = 0; +} + // TODO affect visibility properly -BOOL processAreaMessage(MSG *msg) +void processAreaMessage(HWND active, MSG *msg) { LRESULT handled; - // TODO get rid of this part - WCHAR classname[260 + 1]; - GetClassNameW(msg->hwnd, classname, 260); - if (wcscmp(classname, areaClass) != 0) return FALSE; - HWND active; - active = GetActiveWindow(); - if (active == NULL) return FALSE; - handled = 0; switch (msg->message) { case WM_KEYDOWN: @@ -642,17 +648,16 @@ BOOL processAreaMessage(MSG *msg) break; } if (handled) - return TRUE; + return; // don't call TranslateMessage(); we do our own keyboard handling // TODO should we just return to the standard message loop? if (IsDialogMessage(active, msg) != 0) - return TRUE; + return; DispatchMessageW(msg); - return TRUE; } -ATOM registerAreaClass(void) +ATOM registerAreaClass(HICON hDefaultIcon, HCURSOR hDefaultCursor) { WNDCLASSW wc; @@ -660,8 +665,8 @@ ATOM registerAreaClass(void) wc.lpszClassName = areaClass; wc.lpfnWndProc = areaWndProc; wc.hInstance = hInstance; -//TODO wc.hIcon = hDefaultIcon; -//TODO wc.hCursor = hDefaultCursor; + wc.hIcon = hDefaultIcon; + wc.hCursor = hDefaultCursor; wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); // don't specify CS_HREDRAW or CS_VREDRAW; that's decided by the uiAreaHandler in RedrawOnResize() return RegisterClassW(&wc); @@ -673,35 +678,29 @@ void unregisterAreaClass(void) logLastError("error unregistering uiArea window class in unregisterAreaClass()"); } -HWND makeArea(DWORD exstyle, DWORD style, int x, int y, int cx, int cy, HWND parent, uiAreaHandler *ah) +void uiAreaUpdateScroll(uiArea *a) { - uiArea *a; - - // TODO - a = malloc(sizeof (uiArea)); -a->rt = NULL; - - a->ah = ah; - - a->hwnd = CreateWindowExW(exstyle, - areaClass, L"", - style | WS_HSCROLL | WS_VSCROLL, - x, y, cx, cy, - parent, NULL, hInstance, a); - - clickCounterReset(&(a->cc)); - - a->capturing = FALSE; - - return a->hwnd; -} - -void areaUpdateScroll(HWND area) -{ - uiArea *a; - - a = (uiArea *) GetWindowLongPtrW(area, GWLP_USERDATA); // use a no-op scroll to simulate scrolling hscrollby(a, 0); vscrollby(a, 0); } + +uiArea *uiNewArea(uiAreaHandler *ah) +{ + uiArea *a; + + a = (uiArea *) uiNewControl(uiAreaType()); + + a->ah = ah; + clickCounterReset(&(a->cc)); + + a->hwnd = uiWindowsEnsureCreateControlHWND(0, + areaClass, L"", + WS_HSCROLL | WS_VSCROLL, + hInstance, a, + FALSE); + + uiWindowsFinishNewControl(a, uiArea); + + return a; +} diff --git a/winarea_d2d/draw.c b/windows/draw.c similarity index 99% rename from winarea_d2d/draw.c rename to windows/draw.c index 293ad5ca..cf660ec7 100644 --- a/winarea_d2d/draw.c +++ b/windows/draw.c @@ -1,5 +1,5 @@ // 7 september 2015 -#include "area.h" +#include "uipriv_windows.h" static ID2D1Factory *d2dfactory = NULL; diff --git a/windows/init.c b/windows/init.c index e3f38c5c..f7c0c07a 100644 --- a/windows/init.c +++ b/windows/init.c @@ -158,12 +158,21 @@ const char *uiInit(uiInitOptions *o) // TODO initialize COM security // TODO (windows vista) turn off COM exception handling + hr = initDraw(); + if (hr != S_OK) + return loadHRESULT("initializing Direct2D", hr); + + if (registerAreaClass(hDefaultIcon, hDefaultCursor) == 0) + return loadLastError("registering uiArea window class"); + return NULL; } void uiUninit(void) { uninitMenus(); + unregisterAreaClass(); + uninitDraw(); CoUninitialize(); uninitDialogHelper(); if (DeleteObject(hollowBrush) == 0) diff --git a/windows/main.c b/windows/main.c index ad3e9d32..4d9d84e6 100644 --- a/windows/main.c +++ b/windows/main.c @@ -33,9 +33,9 @@ void uiMain(void) // as for Tabs, we can't have both WS_TABSTOP and WS_EX_CONTROLPARENT set at the same time, so we hotswap the two styles to get the behavior we want focus = GetFocus(); if (focus != NULL) { - switch (windowClassOf(focus, L"TODO Area not yet implemented", NULL)) { + switch (windowClassOf(focus, areaClass, NULL)) { case 0: // uiArea -// msgloop_area(active, focus, &msg); + processAreaMessage(active, &msg); continue; } // else fall through diff --git a/windows/uipriv_windows.h b/windows/uipriv_windows.h index d1fb7294..f6070763 100644 --- a/windows/uipriv_windows.h +++ b/windows/uipriv_windows.h @@ -121,3 +121,16 @@ extern void childSetIntmax(struct child *c, int n, intmax_t to); // tabpage.c extern void tabPageMargins(HWND, intmax_t *, intmax_t *, intmax_t *, intmax_t *); extern HWND newTabPage(void); + +// area.c +#define areaClass L"libui_uiAreaClass" +extern void processAreaMessage(HWND, MSG *); +extern ATOM registerAreaClass(HICON, HCURSOR); +extern void unregisterAreaClass(void); + +// draw.c +extern HRESULT initDraw(void); +extern void uninitDraw(void); +extern ID2D1HwndRenderTarget *makeHWNDRenderTarget(HWND hwnd); +extern uiDrawContext *newContext(ID2D1RenderTarget *); +extern void freeContext(uiDrawContext *);