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.c... ============================================================================== --- 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_bu... ============================================================================== --- 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);