Implemented uiButton.preferredSize() on Windows. This includes adding a function to get the width of text in a control.

This commit is contained in:
Pietro Gagliardi 2015-04-07 19:32:16 -04:00
parent 38eecd3fc3
commit 42204af086
3 changed files with 57 additions and 1 deletions

View File

@ -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)

View File

@ -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

View File

@ -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;
}