Author: gadamopoulos
Date: Wed Mar 1 11:49:59 2017
New Revision: 74012
URL:
http://svn.reactos.org/svn/reactos?rev=74012&view=rev
Log:
[COMCTL32] -Add initial implementation for BCM_GETIDEALSIZE and support to draw buttons
with image lists. This is still WIP and needs tons of new tests. Crappy themes will be
displayed like crap for now.
Modified:
trunk/reactos/dll/win32/comctl32/button.c
trunk/reactos/dll/win32/comctl32/theme_button.c
Modified: trunk/reactos/dll/win32/comctl32/button.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/comctl32/button.…
==============================================================================
--- trunk/reactos/dll/win32/comctl32/button.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/comctl32/button.c [iso-8859-1] Wed Mar 1 11:49:59 2017
@@ -237,6 +237,7 @@
}
BOOL BUTTON_PaintWithTheme(HTHEME theme, HWND hwnd, HDC hParamDC, LPARAM prfFlag);
+WCHAR *get_button_text( HWND hwnd );
static inline LONG_PTR get_button_image(HWND hwnd)
{
@@ -307,11 +308,96 @@
ReleaseDC( hwnd, hdc );
}
+BOOL BUTTON_GetIdealSize(HTHEME theme, HWND hwnd, SIZE* psize)
+{
+ PBUTTON_DATA pdata;
+ HDC hdc;
+ WCHAR *text;
+ HFONT hFont = 0, hPrevFont = 0;
+ SIZE TextSize, ImageSize, ButtonSize;
+
+ pdata = _GetButtonData(hwnd);
+ text = get_button_text( hwnd );
+ hdc = GetDC(hwnd);
+ if (!pdata || !text || !hdc || !text[0])
+ {
+ psize->cx = 100;
+ psize->cy = 100;
+ goto cleanup;
+ }
+
+ /* FIXME : Should use GetThemeTextExtent but unfortunately uses DrawTextW which is
broken */
+ if (theme)
+ {
+ LOGFONTW logfont;
+ HRESULT hr = GetThemeFont(theme, hdc, BP_PUSHBUTTON, PBS_NORMAL, TMT_FONT,
&logfont);
+ if(SUCCEEDED(hr))
+ {
+ hFont = CreateFontIndirectW(&logfont);
+ if(hFont)
+ hPrevFont = SelectObject( hdc, hFont );
+ }
+ }
+ else
+ {
+ if (pdata->font)
+ hPrevFont = SelectObject( hdc, pdata->font );
+ }
+
+ GetTextExtentPoint32W(hdc, text, wcslen(text), &TextSize);
+
+ if (hPrevFont)
+ SelectObject( hdc, hPrevFont );
+
+ TextSize.cy += pdata->rcTextMargin.top + pdata->rcTextMargin.bottom;
+ TextSize.cx += pdata->rcTextMargin.left + pdata->rcTextMargin.right;
+
+ if (pdata->imlData.himl && ImageList_GetIconSize(pdata->imlData.himl,
&ImageSize.cx, &ImageSize.cy))
+ {
+ ImageSize.cx += pdata->imlData.margin.left + pdata->imlData.margin.right;
+ ImageSize.cy += pdata->imlData.margin.top + pdata->imlData.margin.bottom;
+ }
+ else
+ {
+ ImageSize.cx = ImageSize.cy = 0;
+ }
+
+ if (theme)
+ {
+ RECT rcContents = {0};
+ RECT rcButtonExtent = {0};
+ rcContents.right = ImageSize.cx + TextSize.cx;
+ rcContents.bottom = max(ImageSize.cy, TextSize.cy);
+ GetThemeBackgroundExtent(theme, hdc, BP_PUSHBUTTON, PBS_NORMAL, &rcContents,
&rcButtonExtent);
+ ERR("rcContents: %d, %d, %d, %d\n", rcContents.left, rcContents.top,
rcContents.right, rcContents.bottom);
+ ERR("rcButtonExtent: %d, %d, %d, %d\n", rcButtonExtent.left,
rcButtonExtent.top, rcButtonExtent.right, rcButtonExtent.bottom);
+ ButtonSize.cx = abs(rcButtonExtent.right - rcButtonExtent.left) + 1;
+ ButtonSize.cy = abs(rcButtonExtent.bottom - rcButtonExtent.top) - 1;
+ }
+ else
+ {
+ ButtonSize.cx = ImageSize.cx + TextSize.cx + 5;
+ ButtonSize.cy = max(ImageSize.cy, TextSize.cy + 7);
+ }
+
+ *psize = ButtonSize;
+
+cleanup:
+ if (hFont)
+ DeleteObject(hFont);
+ if (text)
+ HeapFree( GetProcessHeap(), 0, text );
+ if (hdc)
+ ReleaseDC(hwnd, hdc);
+
+ return TRUE;
+}
+
#endif
/* retrieve the button text; returned buffer must be freed by caller */
-static inline WCHAR *get_button_text( HWND hwnd )
+inline WCHAR *get_button_text( HWND hwnd )
{
INT len = 512;
WCHAR *buffer = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) );
@@ -485,6 +571,21 @@
return FALSE;
*pimldata = data->imlData;
return TRUE;
+ }
+ case BCM_GETIDEALSIZE:
+ {
+ HTHEME theme = GetWindowTheme(hWnd);
+
+ if (btn_type != BS_PUSHBUTTON && btn_type != BS_DEFPUSHBUTTON)
+ {
+ SIZE* pSize = (SIZE*)lParam;
+ GetClientRect(hWnd, &rect);
+ pSize->cx = rect.right;
+ pSize->cy = rect.bottom;
+ return TRUE;
+ }
+
+ return BUTTON_GetIdealSize(theme, hWnd, (SIZE*)lParam);
}
}
@@ -1110,11 +1211,34 @@
*/
static BOOL CALLBACK BUTTON_DrawTextCallback(HDC hdc, LPARAM lp, WPARAM wp, int cx, int
cy)
{
+#ifdef _USER32_
RECT rc;
SetRect(&rc, 0, 0, cx, cy);
DrawTextW(hdc, (LPCWSTR)lp, -1, &rc, (UINT)wp);
return TRUE;
+#else
+ HWND hwnd = (HWND)lp;
+ RECT rc;
+ PBUTTON_DATA pdata = _GetButtonData(hwnd);
+ SIZE ImageSize;
+ WCHAR *text = NULL;
+
+ if (!(text = get_button_text( hwnd ))) return TRUE;
+
+ SetRect(&rc, 0, 0, cx, cy);
+
+ if (pdata->imlData.himl && ImageList_GetIconSize(pdata->imlData.himl,
&ImageSize.cx, &ImageSize.cy))
+ {
+ int left = pdata->imlData.margin.left;
+ int top = (cy - ImageSize.cy) / 2;
+ rc.left += pdata->imlData.margin.left + pdata->imlData.margin.right +
ImageSize.cy;
+ ImageList_Draw(pdata->imlData.himl, 0, hdc, left, top, 0);
+ }
+
+ DrawTextW(hdc, text, -1, &rc, (UINT)wp);
+ return TRUE;
+#endif
}
@@ -1150,8 +1274,13 @@
case BS_TEXT:
/* DST_COMPLEX -- is 0 */
lpOutputProc = BUTTON_DrawTextCallback;
+#ifdef _USER32_
if (!(text = get_button_text( hwnd ))) return;
lp = (LPARAM)text;
+#else
+ lp = (LPARAM)hwnd;
+#endif
+
wp = (WPARAM)dtFlags;
#ifdef __REACTOS__
Modified: trunk/reactos/dll/win32/comctl32/theme_button.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/comctl32/theme_b…
==============================================================================
--- trunk/reactos/dll/win32/comctl32/theme_button.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/comctl32/theme_button.c [iso-8859-1] Wed Mar 1 11:49:59 2017
@@ -111,6 +111,8 @@
HFONT hPrevFont = font ? SelectObject(hDC, font) : NULL;
int state = states[ drawState ];
WCHAR *text = get_button_text(hwnd);
+ PBUTTON_DATA pdata = _GetButtonData(hwnd);
+ SIZE ImageSize;
GetClientRect(hwnd, &bgRect);
GetThemeBackgroundContentRect(theme, hDC, BP_PUSHBUTTON, state, &bgRect,
&textRect);
@@ -122,6 +124,15 @@
}
DrawThemeBackground(theme, hDC, BP_PUSHBUTTON, state, &bgRect, NULL);
+
+ if (pdata->imlData.himl && ImageList_GetIconSize(pdata->imlData.himl,
&ImageSize.cx, &ImageSize.cy))
+ {
+ int left = textRect.left + pdata->imlData.margin.left;
+ int top = textRect.top + (textRect.bottom - textRect.top - ImageSize.cy) / 2;
+ textRect.left += pdata->imlData.margin.left + pdata->imlData.margin.right +
ImageSize.cy;
+ ImageList_Draw(pdata->imlData.himl, 0, hDC, left, top, 0);
+ }
+
if (text)
{
DrawThemeText(theme, hDC, BP_PUSHBUTTON, state, text, lstrlenW(text), dtFlags, 0,
&textRect);