diff --git a/new/button_windows.c b/new/button_windows.c index 3725287..3eb7e1a 100644 --- a/new/button_windows.c +++ b/new/button_windows.c @@ -23,9 +23,30 @@ static BOOL onWM_NOTIFY(uiControl *c, WPARAM wParam, LPARAM lParam, void *data, return FALSE; } +// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing +#define buttonHeight 14 + static void preferredSize(uiControl *c, int baseX, int baseY, LONG internalLeading, intmax_t *width, intmax_t *height) { - // TODO + HWND hwnd; + SIZE size; + + hwnd = (HWND) uiControlHandle(c); + + // try the comctl32 version 6 way + size.cx = 0; // explicitly ask for ideal size + size.cy = 0; + if (SendMessageW(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM) (&size)) != FALSE) { + *width = size.cx; + *height = size.cy; + return; + } + + // that didn't work; fall back to using Microsoft's metrics + // Microsoft says to use a fixed width for all buttons; this isn't good enough + // use the text width instead, with some edge padding + *width = uiWindowsWindowTextWidth(hwnd) + (2 * GetSystemMetrics(SM_CXEDGE)); + *height = uiDlgUnitToY(buttonHeight, baseY); } static void defaultOnClicked(uiControl *c, void *data) diff --git a/new/ui_windows.h b/new/ui_windows.h index 22b0a14..cbbe859 100644 --- a/new/ui_windows.h +++ b/new/ui_windows.h @@ -41,4 +41,8 @@ void *uiWindowsControlData(uiControl *); #define uiDlgUnitToX(dlg, baseX) MulDiv((dlg), baseX, 4) #define uiDlgUnitToY(dlg, baseY) MulDiv((dlg), baseY, 8) +// and use this if you need the text of the window width +// TODO really export? +extern intmax_t uiWindowsWindowTextWidth(HWND hwnd); + #endif diff --git a/new/util_windows.c b/new/util_windows.c index 0bd76a0..c0d3d6c 100644 --- a/new/util_windows.c +++ b/new/util_windows.c @@ -16,3 +16,34 @@ WCHAR *toUTF16(const char *str) logLastError("error converting from UTF-8 to UTF-16 in toUTF16()"); return wstr; } + +// TODO this and resize(): initialize size and other values to avoid garbage on failure +intmax_t uiWindowsWindowTextWidth(HWND hwnd) +{ + int len; + WCHAR *text; + HDC dc; + HFONT prevfont; + + // TODO check for error + len = GetWindowTextLengthW(hwnd); + if (len == 0) // no text; nothing to do + return 0; + text = (WCHAR *) uiAlloc((len + 1) * sizeof (WCHAR)); + if (GetWindowText(hwnd, text, len + 1) == 0) // should only happen on error given explicit test for len == 0 above + logLastError("error getting window text in uiWindowsWindowTextWidth()"); + dc = GetDC(parent); + if (dc == NULL) + logLastError("error getting DC in uiWindowsWindowTextWidth()"); + prevFont = (HFONT) SelectObject(dc, hMessageFont); + if (prevFont == NULL) + logLastError("error loading control font into device context in uiWindowsWindowTextWidth()"); + if (GetTextExtentPoint32W(dc, text, len, &size) == 0) + logLastError("error getting text extent point in uiWindowsWindowTextWidth()"); + if (SelectObject(dc, prevFont) != hMessageFont) + logLastError("error restoring previous font into device context in uiWindowsWindowTextWidth()"); + if (ReleaseDC(parent, dc) == 0) + logLastError("error releasing DC in uiWindowsWindowTextWidth()"); + uiFree(text); + return size.cx; +}