From 3f1b72721ea30de52186b47271cf585e4af7b9ab Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 2 Sep 2015 16:02:06 -0400 Subject: [PATCH] Implemented uiTab minimum size and uiWindow resize restriction. --- windows/tab.c | 25 ++++++++++--------------- windows/uipriv_windows.h | 1 + windows/util.c | 23 +++++++++++++++++++++++ windows/window.c | 17 +++++++++++++++++ 4 files changed, 51 insertions(+), 15 deletions(-) diff --git a/windows/tab.c b/windows/tab.c index 64a446e1..6b1ea87d 100644 --- a/windows/tab.c +++ b/windows/tab.c @@ -90,34 +90,29 @@ static void tabCommitSetParent(uiWindowsControl *c, HWND parent) static void minimumSize(uiWindowsControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height) { -/* TODO uiTab *t = uiTab(c); - intmax_t maxwid, maxht; intmax_t pagewid, pageht; - uiControl *page; - uintmax_t i; + struct child *page; + LRESULT n; RECT r; - maxwid = 0; - maxht = 0; - for (i = 0; i < t->pages->len; i++) { - page = ptrArrayIndex(t->pages, struct child *, i); + // only consider the current page + pagewid = 0; + pageht = 0; + n = curpage(t); + if (n != (LRESULT) (-1)) { + page = ptrArrayIndex(t->pages, struct child *, n); childMinimumSize(page, d, &pagewid, &pageht); - if (maxwid < pagewid) - maxwid = pagewid; - if (maxht < pageht) - maxht = pageht; } r.left = 0; r.top = 0; - r.right = maxwid; - r.bottom = maxht; + r.right = pagewid; + r.bottom = pageht; // this also includes the tabs themselves SendMessageW(t->hwnd, TCM_ADJUSTRECT, (WPARAM) TRUE, (LPARAM) (&r)); *width = r.right - r.left; *height = r.bottom - r.top; -*/ } static void tabRelayout(uiWindowsControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height) diff --git a/windows/uipriv_windows.h b/windows/uipriv_windows.h index a1f37866..34675fb5 100644 --- a/windows/uipriv_windows.h +++ b/windows/uipriv_windows.h @@ -28,6 +28,7 @@ extern DWORD getStyle(HWND); extern void setStyle(HWND, DWORD); extern DWORD getExStyle(HWND); extern void setExStyle(HWND, DWORD); +extern void clientSizeToWindowSize(HWND, intmax_t *, intmax_t *, BOOL); // text.c extern WCHAR *toUTF16(const char *); diff --git a/windows/util.c b/windows/util.c index 6a3f02c2..ef31b7b4 100644 --- a/windows/util.c +++ b/windows/util.c @@ -98,3 +98,26 @@ void uiWindowsEnsureAssignControlIDZOrder(HWND hwnd, LONG_PTR controlID, HWND in SetWindowLongPtrW(hwnd, GWLP_ID, controlID); setWindowInsertAfter(hwnd, insertAfter); } + +// see http://blogs.msdn.com/b/oldnewthing/archive/2003/09/11/54885.aspx and http://blogs.msdn.com/b/oldnewthing/archive/2003/09/13/54917.aspx +void clientSizeToWindowSize(HWND hwnd, intmax_t *width, intmax_t *height, BOOL hasMenubar) +{ + RECT window; + + window.left = 0; + window.top = 0; + window.right = *width; + window.bottom = *height; + if (AdjustWindowRectEx(&window, getStyle(hwnd), hasMenubar, getExStyle(hwnd)) == 0) + logLastError("error getting real window coordinates in clientSizeToWindowSize()"); + if (hasMenubar) { + RECT temp; + + temp = window; + temp.bottom = 0x7FFF; // infinite height + SendMessageW(hwnd, WM_NCCALCSIZE, (WPARAM) FALSE, (LPARAM) (&temp)); + window.bottom += temp.top; + } + *width = window.right - window.left; + *height = window.bottom - window.top; +} diff --git a/windows/window.c b/windows/window.c index e2914afe..bb0e5c7c 100644 --- a/windows/window.c +++ b/windows/window.c @@ -12,6 +12,7 @@ struct uiWindow { int (*onClosing)(uiWindow *, void *); void *onClosingData; int margined; + BOOL hasMenubar; }; static void onDestroy(uiWindow *); @@ -28,6 +29,9 @@ static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA uiWindow *w; CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam; WINDOWPOS *wp = (WINDOWPOS *) lParam; + MINMAXINFO *mmi = (MINMAXINFO *) lParam; + uiWindowsControl *c; + intmax_t width, height; LRESULT lResult; ww = GetWindowLongPtrW(hwnd, GWLP_USERDATA); @@ -55,6 +59,18 @@ static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA if (w->child != NULL) childQueueRelayout(w->child); return 0; + case WM_GETMINMAXINFO: + // ensure the user cannot resize the window smaller than its minimum size + lResult = DefWindowProcW(hwnd, uMsg, wParam, lParam); + if (w->child == NULL) + return lResult; + c = uiWindowsControl(w); + (*(c->MinimumSize))(c, NULL, &width, &height); + // width and height are in client coordinates; ptMinTrackSize is in window coordinates + clientSizeToWindowSize(w->hwnd, &width, &height, w->hasMenubar); + mmi->ptMinTrackSize.x = width; + mmi->ptMinTrackSize.y = height; + return lResult; case WM_PRINTCLIENT: // we do no special painting; just erase the background // don't worry about the return value; we let DefWindowProcW() handle this message @@ -249,6 +265,7 @@ uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar) hasMenubarBOOL = FALSE; if (hasMenubar) hasMenubarBOOL = TRUE; + w->hasMenubar = hasMenubarBOOL; #define style WS_OVERLAPPEDWINDOW #define exstyle 0