[COMCTL32] Ha^^Fix the size of the start button for lautus so as it gets the same...
[reactos.git] / reactos / dll / win32 / comctl32 / button.c
index 820e56f..31f4023 100644 (file)
@@ -237,6 +237,7 @@ HRGN set_control_clipping( HDC hdc, const RECT *rect )
 }
 
 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,100 @@ static inline void paint_button( HWND hwnd, LONG style, UINT action )
     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;
+    BOOL ret = FALSE;
+    LOGFONTW logfont;
+
+    pdata = _GetButtonData(hwnd);
+    text = get_button_text( hwnd );
+    hdc = GetDC(hwnd);
+    if (!pdata || !text || !hdc || !text[0])
+        goto cleanup;
+
+    /* FIXME : Should use GetThemeTextExtent but unfortunately uses DrawTextW which is broken */
+    if (theme)
+    {
+        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 (logfont.lfHeight == -1 && logfont.lfWidth == 0 && wcscmp(logfont.lfFaceName, L"Arial") == 0)
+    {
+        TextSize.cx = 5;
+        TextSize.cy = 4;
+    }
+
+    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 = rcButtonExtent.right - rcButtonExtent.left;
+        ButtonSize.cy = rcButtonExtent.bottom - rcButtonExtent.top;
+    }
+    else
+    {
+        ButtonSize.cx = ImageSize.cx + TextSize.cx + 5;
+        ButtonSize.cy = max(ImageSize.cy, TextSize.cy  + 7);
+    }
+
+    *psize = ButtonSize;
+    ret = TRUE;
+
+cleanup:
+    if (hFont)
+        DeleteObject(hFont);
+    if (text) 
+        HeapFree( GetProcessHeap(), 0, text );
+    if (hdc)
+        ReleaseDC(hwnd, hdc);
+
+    return ret;
+}
+
 #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) );
@@ -395,6 +485,8 @@ LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
             }
 
             memset(data, 0, sizeof(BUTTON_DATA));
+            SetRect(&data->rcTextMargin, 1,1,1,1);
+
             _SetButtonData(hWnd, data);
             break;
         }
@@ -448,6 +540,64 @@ LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
             }
             break;
         }
+        case BCM_GETTEXTMARGIN:
+        {
+            RECT* prc = (RECT*)lParam;
+            PBUTTON_DATA data = _GetButtonData(hWnd);
+            if (!prc || !data)
+                return FALSE;
+            *prc = data->rcTextMargin;
+            return TRUE;
+        }
+        case BCM_SETTEXTMARGIN:
+        {
+            RECT* prc = (RECT*)lParam;
+            PBUTTON_DATA data = _GetButtonData(hWnd);
+            if (!prc || !data)
+                return FALSE;
+            data->rcTextMargin = *prc;
+            return TRUE;
+        }
+        case BCM_SETIMAGELIST:
+        {
+            BUTTON_IMAGELIST * pimldata = (BUTTON_IMAGELIST *)lParam;
+            PBUTTON_DATA data = _GetButtonData(hWnd);
+            if (!data || !pimldata || !pimldata->himl)
+                return FALSE;
+            data->imlData = *pimldata;
+            return TRUE;
+        }
+        case BCM_GETIMAGELIST:
+        {
+            BUTTON_IMAGELIST * pimldata = (BUTTON_IMAGELIST *)lParam;
+            PBUTTON_DATA data = _GetButtonData(hWnd);
+            if (!data|| !pimldata)
+                return FALSE;
+            *pimldata = data->imlData;
+            return TRUE;
+        }
+        case BCM_GETIDEALSIZE:
+        {
+            HTHEME theme = GetWindowTheme(hWnd);
+            BOOL ret = FALSE;
+            SIZE* pSize = (SIZE*)lParam;
+
+            if (btn_type == BS_PUSHBUTTON || 
+                btn_type == BS_DEFPUSHBUTTON ||
+                btn_type == BS_USERBUTTON)
+            {
+                ret = BUTTON_GetIdealSize(theme, hWnd, pSize);
+            }
+
+            if (!ret)
+            {
+                GetClientRect(hWnd, &rect);
+                pSize->cx = rect.right;
+                pSize->cy = rect.bottom;
+            }
+
+            return TRUE;
+        }
     }
 
     if (!_GetButtonData(hWnd))
@@ -1072,11 +1222,34 @@ static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
  */
 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
 }
 
 
@@ -1112,8 +1285,13 @@ static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, const RECT *rc)
       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__