diff --git a/dlls/comctl32/datetime.c b/dlls/comctl32/datetime.c index 46ac3e5b5cf..62310702407 100644 --- a/dlls/comctl32/datetime.c +++ b/dlls/comctl32/datetime.c @@ -1454,6 +1454,58 @@ DATETIME_StyleChanged(DATETIME_INFO *infoPtr, WPARAM wStyleType, const STYLESTRU return 0; } +static BOOL DATETIME_GetIdealSize(DATETIME_INFO *infoPtr, SIZE *size) +{ + SIZE field_size; + RECT rect; + SHORT width; + WCHAR txt[80]; + HDC hdc; + HFONT oldFont; + int i; + + size->cx = size->cy = 0; + + hdc = GetDC(infoPtr->hwndSelf); + oldFont = SelectObject(hdc, infoPtr->hFont); + + /* Get text font height */ + DATETIME_ReturnTxt(infoPtr, 0, txt, ARRAY_SIZE(txt)); + GetTextExtentPoint32W(hdc, txt, strlenW(txt), &field_size); + size->cy = field_size.cy; + + /* Get text font width */ + for (i = 0; i < infoPtr->nrFields; i++) + { + DATETIME_ReturnFieldWidth(infoPtr, hdc, i, &width); + size->cx += width; + } + + SelectObject(hdc, oldFont); + ReleaseDC(infoPtr->hwndSelf, hdc); + + if (infoPtr->dwStyle & DTS_UPDOWN) + { + GetWindowRect(infoPtr->hUpdown, &rect); + size->cx += rect.right - rect.left; + } + else + { + size->cx += infoPtr->calbutton.right - infoPtr->calbutton.left; + } + + if (infoPtr->dwStyle & DTS_SHOWNONE) + { + size->cx += infoPtr->checkbox.right - infoPtr->checkbox.left; + } + + /* Add space between controls for them not to get too close */ + size->cx += 12; + size->cy += 4; + + TRACE("cx=%d cy=%d\n", size->cx, size->cy); + return TRUE; +} static LRESULT DATETIME_SetFont (DATETIME_INFO *infoPtr, HFONT font, BOOL repaint) @@ -1585,6 +1637,9 @@ DATETIME_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case DTM_GETMCFONT: return SendMessageW (infoPtr->hMonthCal, WM_GETFONT, wParam, lParam); + case DTM_GETIDEALSIZE: + return DATETIME_GetIdealSize(infoPtr, (SIZE *)lParam); + case WM_NOTIFY: return DATETIME_Notify (infoPtr, (LPNMHDR)lParam); diff --git a/dlls/comctl32/tests/datetime.c b/dlls/comctl32/tests/datetime.c index 7742dc5d183..88abce9ed61 100644 --- a/dlls/comctl32/tests/datetime.c +++ b/dlls/comctl32/tests/datetime.c @@ -721,6 +721,46 @@ static void test_dtm_set_and_get_systemtime_with_limits(void) DestroyWindow(hWnd); } +static void test_dtm_get_ideal_size(void) +{ + HWND hwnd; + HDC hdc; + HFONT hfont; + LOGFONTA lf; + TEXTMETRICA tm; + SIZE size; + BOOL r; + + hwnd = create_datetime_control(0); + r = SendMessageA(hwnd, DTM_GETIDEALSIZE, 0, (LPARAM)&size); + if (!r) + { + win_skip("DTM_GETIDEALSIZE is not available\n"); + DestroyWindow(hwnd); + return; + } + + /* Set font so that the test is consistent on Wine and Windows */ + ZeroMemory(&lf, sizeof(lf)); + lf.lfWeight = FW_NORMAL; + lf.lfHeight = 20; + lstrcpyA(lf.lfFaceName, "Tahoma"); + hfont = CreateFontIndirectA(&lf); + SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE); + + hdc = GetDC(hwnd); + GetTextMetricsA(hdc, &tm); + ReleaseDC(hwnd, hdc); + + r = SendMessageA(hwnd, DTM_GETIDEALSIZE, 0, (LPARAM)&size); + ok(r, "Expect DTM_GETIDEALSIZE message to return true\n"); + ok(size.cx > 0 && size.cy >= tm.tmHeight, + "Expect size.cx > 0 and size.cy >= %d, got cx:%d cy:%d\n", tm.tmHeight, size.cx, size.cy); + + DestroyWindow(hwnd); + DeleteObject(hfont); +} + static void test_wm_set_get_text(void) { static const CHAR a_str[] = "a"; @@ -821,6 +861,7 @@ START_TEST(datetime) test_dtm_set_and_get_mccolor(); test_dtm_set_and_get_mcfont(); test_dtm_get_monthcal(); + test_dtm_get_ideal_size(); test_wm_set_get_text(); test_dts_shownone(); diff --git a/include/commctrl.h b/include/commctrl.h index 6890b5014ca..ae70cfd6981 100644 --- a/include/commctrl.h +++ b/include/commctrl.h @@ -5009,6 +5009,8 @@ DECL_WINELIB_TYPE_AW(LPNMDATETIMEFORMATQUERY) SNDMSG (hdp, DTM_SETMCFONT, (WPARAM)hfont, (LPARAM)fRedraw) #define DateTime_GetMonthCalFont(hdp) \ SNDMSG (hdp, DTM_GETMCFONT, 0, 0) +#define DateTime_GetIdealSize(hdp, sz) \ + (BOOL) SNDMSG (hdp, DTM_GETIDEALSIZE, 0, (LPARAM)sz) #define DA_LAST (0x7fffffff) #define DPA_APPEND (0x7fffffff)