Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/combo.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/dlls/comctl32/combo.c b/dlls/comctl32/combo.c index 1fa5f5ef21..827da37c0c 100644 --- a/dlls/comctl32/combo.c +++ b/dlls/comctl32/combo.c @@ -545,10 +545,13 @@ static LRESULT COMBO_Create( HWND hwnd, LPHEADCOMBO lphc, HWND hwndParent, LONG * * Paint combo button (normal, pressed, and disabled states). */ -static void CBPaintButton( LPHEADCOMBO lphc, HDC hdc, RECT rectButton) +static void CBPaintButton(HEADCOMBO *lphc, HDC hdc) { UINT buttonState = DFCS_SCROLLCOMBOBOX;
+ if (IsRectEmpty(&lphc->buttonRect)) + return; + if( lphc->wState & CBF_NOREDRAW ) return;
@@ -559,7 +562,7 @@ static void CBPaintButton( LPHEADCOMBO lphc, HDC hdc, RECT rectButton) if (CB_DISABLED(lphc)) buttonState |= DFCS_INACTIVE;
- DrawFrameControl(hdc, &rectButton, DFC_SCROLL, buttonState); + DrawFrameControl(hdc, &lphc->buttonRect, DFC_SCROLL, buttonState); }
/*********************************************************************** @@ -815,8 +818,7 @@ static LRESULT COMBO_Paint(HEADCOMBO *lphc, HDC hdc) */ CBPaintBorder(lphc->self, lphc, hdc);
- if (!IsRectEmpty(&lphc->buttonRect)) - CBPaintButton(lphc, hdc, lphc->buttonRect); + CBPaintButton(lphc, hdc);
/* paint the edit control padding area */ if (CB_GETTYPE(lphc) != CBS_DROPDOWNLIST)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/combo.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/dlls/comctl32/combo.c b/dlls/comctl32/combo.c index 827da37c0c..a82118bc07 100644 --- a/dlls/comctl32/combo.c +++ b/dlls/comctl32/combo.c @@ -736,16 +736,13 @@ static void CBPaintText(HEADCOMBO *lphc, HDC hdc_paint) /*********************************************************************** * CBPaintBorder */ -static void CBPaintBorder( - HWND hwnd, - const HEADCOMBO *lphc, - HDC hdc) +static void CBPaintBorder(const HEADCOMBO *lphc, HDC hdc) { RECT clientRect;
if (CB_GETTYPE(lphc) != CBS_SIMPLE) { - GetClientRect(hwnd, &clientRect); + GetClientRect(lphc->self, &clientRect); } else { @@ -816,7 +813,7 @@ static LRESULT COMBO_Paint(HEADCOMBO *lphc, HDC hdc) /* * In non 3.1 look, there is a sunken border on the combobox */ - CBPaintBorder(lphc->self, lphc, hdc); + CBPaintBorder(lphc, hdc);
CBPaintButton(lphc, hdc);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/combo.c | 111 +++++++++++++++++++++------------------ dlls/comctl32/comctl32.h | 4 +- 2 files changed, 63 insertions(+), 52 deletions(-)
diff --git a/dlls/comctl32/combo.c b/dlls/comctl32/combo.c index a82118bc07..765fc631e0 100644 --- a/dlls/comctl32/combo.c +++ b/dlls/comctl32/combo.c @@ -78,6 +78,9 @@ static UINT CBitHeight, CBitWidth; #define ID_CB_LISTBOX 1000 #define ID_CB_EDIT 1001
+static void CBCalcPlacement(HEADCOMBO *combo); +static void CBResetPos(HEADCOMBO *combo); + /*********************************************************************** * COMBO_Init * @@ -169,6 +172,25 @@ static LRESULT COMBO_NCDestroy( HEADCOMBO *lphc ) return 0; }
+static INT combo_get_text_height(const HEADCOMBO *combo) +{ + HDC hdc = GetDC(combo->self); + HFONT prev_font = 0; + TEXTMETRICW tm; + + if (combo->hFont) + prev_font = SelectObject(hdc, combo->hFont); + + GetTextMetricsW(hdc, &tm); + + if (prev_font) + SelectObject(hdc, prev_font); + + ReleaseDC(combo->self, hdc); + + return tm.tmHeight + 4; +} + /*********************************************************************** * CBGetTextAreaHeight * @@ -181,35 +203,18 @@ static LRESULT COMBO_NCDestroy( HEADCOMBO *lphc ) * This height was determined through experimentation. * CBCalcPlacement will add 2*COMBO_YBORDERSIZE pixels for the border */ -static INT CBGetTextAreaHeight(HEADCOMBO *lphc) +static INT CBGetTextAreaHeight(HEADCOMBO *lphc, BOOL clip_item_height) { - INT iTextItemHeight; + INT item_height, text_height;
- if( lphc->editHeight ) /* explicitly set height */ + if (clip_item_height && !CB_OWNERDRAWN(lphc)) { - iTextItemHeight = lphc->editHeight; + text_height = combo_get_text_height(lphc); + if (lphc->item_height < text_height) + lphc->item_height = text_height; } - else - { - TEXTMETRICW tm; - HDC hDC = GetDC(lphc->self); - HFONT hPrevFont = 0; - INT baseUnitY; - - if (lphc->hFont) - hPrevFont = SelectObject( hDC, lphc->hFont ); - - GetTextMetricsW(hDC, &tm); - - baseUnitY = tm.tmHeight; + item_height = lphc->item_height;
- if( hPrevFont ) - SelectObject( hDC, hPrevFont ); - - ReleaseDC(lphc->self, hDC); - - iTextItemHeight = baseUnitY + 4; - }
/* * Check the ownerdraw case if we haven't asked the parent the size @@ -220,7 +225,7 @@ static INT CBGetTextAreaHeight(HEADCOMBO *lphc) { MEASUREITEMSTRUCT measureItem; RECT clientRect; - INT originalItemHeight = iTextItemHeight; + INT originalItemHeight = item_height; UINT id = (UINT)GetWindowLongPtrW( lphc->self, GWLP_ID );
/* @@ -237,10 +242,10 @@ static INT CBGetTextAreaHeight(HEADCOMBO *lphc) measureItem.CtlID = id; measureItem.itemID = -1; measureItem.itemWidth = clientRect.right; - measureItem.itemHeight = iTextItemHeight - 6; /* ownerdrawn cb is taller */ + measureItem.itemHeight = item_height - 6; /* ownerdrawn cb is taller */ measureItem.itemData = 0; SendMessageW(lphc->owner, WM_MEASUREITEM, id, (LPARAM)&measureItem); - iTextItemHeight = 6 + measureItem.itemHeight; + item_height = 6 + measureItem.itemHeight;
/* * Send a second one in the case of a fixed ownerdraw list to calculate the @@ -261,10 +266,10 @@ static INT CBGetTextAreaHeight(HEADCOMBO *lphc) /* * Keep the size for the next time */ - lphc->editHeight = iTextItemHeight; + lphc->item_height = item_height; }
- return iTextItemHeight; + return item_height; }
/*********************************************************************** @@ -274,13 +279,12 @@ static INT CBGetTextAreaHeight(HEADCOMBO *lphc) * a re-arranging of the contents of the combobox and the recalculation * of the size of the "real" control window. */ -static void CBForceDummyResize( - LPHEADCOMBO lphc) +static void CBForceDummyResize(LPHEADCOMBO lphc) { RECT windowRect; int newComboHeight;
- newComboHeight = CBGetTextAreaHeight(lphc) + 2*COMBO_YBORDERSIZE(); + newComboHeight = CBGetTextAreaHeight(lphc, FALSE) + 2*COMBO_YBORDERSIZE();
GetWindowRect(lphc->self, &windowRect);
@@ -292,12 +296,17 @@ static void CBForceDummyResize( * this will cancel-out in the processing of the WM_WINDOWPOSCHANGING * message. */ + lphc->wState |= CBF_NORESIZE; SetWindowPos( lphc->self, NULL, 0, 0, windowRect.right - windowRect.left, newComboHeight, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE ); + lphc->wState &= ~CBF_NORESIZE; + + CBCalcPlacement(lphc); + CBResetPos(lphc); }
/*********************************************************************** @@ -314,7 +323,7 @@ static void CBCalcPlacement(HEADCOMBO *combo) InflateRect(&combo->textRect, -COMBO_XBORDERSIZE(), -COMBO_YBORDERSIZE());
/* Chop off the bottom part to fit with the height of the text area. */ - combo->textRect.bottom = combo->textRect.top + CBGetTextAreaHeight(combo); + combo->textRect.bottom = combo->textRect.top + CBGetTextAreaHeight(combo, FALSE);
/* The button starts the same vertical position as the text area. */ combo->buttonRect = combo->textRect; @@ -400,11 +409,9 @@ static LRESULT COMBO_Create( HWND hwnd, LPHEADCOMBO lphc, HWND hwndParent, LONG
lphc->owner = hwndParent;
- /* - * The item height and dropped width are not set when the control - * is created. - */ - lphc->droppedWidth = lphc->editHeight = 0; + lphc->droppedWidth = 0; + + lphc->item_height = combo_get_text_height(lphc);
/* * The first time we go through, we want to measure the ownerdraw item @@ -1381,8 +1388,11 @@ static void CBResetPos(HEADCOMBO *combo) /*********************************************************************** * COMBO_Size */ -static void COMBO_Size( LPHEADCOMBO lphc ) +static void COMBO_Size( HEADCOMBO *lphc ) { + if (!lphc->hWndLBox || (lphc->wState & CBF_NORESIZE)) + return; + /* * Those controls are always the same height. So we have to make sure * they are not resized to another value. @@ -1395,7 +1405,7 @@ static void COMBO_Size( LPHEADCOMBO lphc ) GetWindowRect(lphc->self, &rc); curComboHeight = rc.bottom - rc.top; curComboWidth = rc.right - rc.left; - newComboHeight = CBGetTextAreaHeight(lphc) + 2*COMBO_YBORDERSIZE(); + newComboHeight = CBGetTextAreaHeight(lphc, TRUE) + 2*COMBO_YBORDERSIZE();
/* * Resizing a combobox has another side effect, it resizes the dropped @@ -1415,9 +1425,13 @@ static void COMBO_Size( LPHEADCOMBO lphc ) /* * Restore original height */ - if( curComboHeight != newComboHeight ) - SetWindowPos(lphc->self, 0, 0, 0, curComboWidth, newComboHeight, - SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOREDRAW); + if (curComboHeight != newComboHeight) + { + lphc->wState |= CBF_NORESIZE; + SetWindowPos(lphc->self, 0, 0, 0, curComboWidth, newComboHeight, + SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW); + lphc->wState &= ~CBF_NORESIZE; + } }
CBCalcPlacement(lphc); @@ -1431,10 +1445,8 @@ static void COMBO_Size( LPHEADCOMBO lphc ) */ static void COMBO_Font( LPHEADCOMBO lphc, HFONT hFont, BOOL bRedraw ) { - /* - * Set the font - */ lphc->hFont = hFont; + lphc->item_height = combo_get_text_height(lphc);
/* * Propagate to owned windows. @@ -1470,7 +1482,7 @@ static LRESULT COMBO_SetItemHeight( LPHEADCOMBO lphc, INT index, INT height ) { if( height < 32768 ) { - lphc->editHeight = height + 2; /* Is the 2 for 2*EDIT_CONTROL_PADDING? */ + lphc->item_height = height + 2; /* Is the 2 for 2*EDIT_CONTROL_PADDING? */
/* * Redo the layout of the control. @@ -1730,8 +1742,7 @@ static LRESULT CALLBACK COMBO_WindowProc( HWND hwnd, UINT message, WPARAM wParam }
case WM_SIZE: - if (lphc->hWndLBox && !(lphc->wState & CBF_NORESIZE)) - COMBO_Size( lphc ); + COMBO_Size( lphc ); return TRUE;
case WM_SETFONT: @@ -1942,7 +1953,7 @@ static LRESULT CALLBACK COMBO_WindowProc( HWND hwnd, UINT message, WPARAM wParam case CB_GETITEMHEIGHT: if ((INT)wParam >= 0) /* listbox item */ return SendMessageW(lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0); - return CBGetTextAreaHeight(lphc); + return CBGetTextAreaHeight(lphc, FALSE);
case CB_RESETCONTENT: SendMessageW(lphc->hWndLBox, LB_RESETCONTENT, 0, 0); diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h index f3e889c4bd..78e9798338 100644 --- a/dlls/comctl32/comctl32.h +++ b/dlls/comctl32/comctl32.h @@ -150,8 +150,8 @@ typedef struct RECT droppedRect; INT droppedIndex; INT fixedOwnerDrawHeight; - INT droppedWidth; /* last two are not used unless set */ - INT editHeight; /* explicitly */ + INT droppedWidth; /* not used unless set explicitly */ + INT item_height; INT visibleItems; } HEADCOMBO, *LPHEADCOMBO;
From: John Alway thaleslv@yahoo.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/tests/combo.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/dlls/comctl32/tests/combo.c b/dlls/comctl32/tests/combo.c index 4757fa3cc6..64785326c9 100644 --- a/dlls/comctl32/tests/combo.c +++ b/dlls/comctl32/tests/combo.c @@ -614,7 +614,7 @@ static HWND create_combobox(DWORD style) return CreateWindowA(WC_COMBOBOXA, "Combo", WS_VISIBLE|WS_CHILD|style, 5, 5, 100, 100, hMainWnd, (HMENU)COMBO_ID, NULL, 0); }
-static int font_height(HFONT hFont) +static int get_font_height(HFONT hFont) { TEXTMETRICA tm; HFONT hFontOld; @@ -632,11 +632,12 @@ static int font_height(HFONT hFont) static void test_combo_setitemheight(DWORD style) { HWND hCombo = create_combobox(style); + int i, font_height, height; + HFONT hFont; RECT r; - int i;
GetClientRect(hCombo, &r); - expect_rect(r, 0, 0, 100, font_height(GetStockObject(SYSTEM_FONT)) + 8); + expect_rect(r, 0, 0, 100, get_font_height(GetStockObject(SYSTEM_FONT)) + 8); SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r); MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); todo_wine expect_rect(r, 5, 5, 105, 105); @@ -649,6 +650,22 @@ static void test_combo_setitemheight(DWORD style) }
DestroyWindow(hCombo); + + /* Set item height below text height, force resize. */ + hCombo = create_combobox(style); + + hFont = (HFONT)SendMessageA(hCombo, WM_GETFONT, 0, 0); + font_height = get_font_height(hFont); + SendMessageA(hCombo, CB_SETITEMHEIGHT, -1, font_height / 2); + height = SendMessageA(hCombo, CB_GETITEMHEIGHT, -1, 0); +todo_wine + ok(height == font_height / 2, "Unexpected item height %d, expected %d.\n", height, font_height / 2); + + SetWindowPos(hCombo, NULL, 10, 10, 150, 5 * font_height, SWP_SHOWWINDOW); + height = SendMessageA(hCombo, CB_GETITEMHEIGHT, -1, 0); + ok(height > font_height, "Unexpected item height %d, font height %d.\n", height, font_height); + + DestroyWindow(hCombo); }
static void test_combo_setfont(DWORD style) @@ -663,7 +680,7 @@ static void test_combo_setfont(DWORD style) hFont2 = CreateFontA(8, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett");
GetClientRect(hCombo, &r); - expect_rect(r, 0, 0, 100, font_height(GetStockObject(SYSTEM_FONT)) + 8); + expect_rect(r, 0, 0, 100, get_font_height(GetStockObject(SYSTEM_FONT)) + 8); SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r); MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); todo_wine expect_rect(r, 5, 5, 105, 105); @@ -672,39 +689,39 @@ static void test_combo_setfont(DWORD style) of the window when it was created. The size of the calculated dropped area changes only by how much the selection area changes, not by how much the list area changes. */ - if (font_height(hFont1) == 10 && font_height(hFont2) == 8) + if (get_font_height(hFont1) == 10 && get_font_height(hFont2) == 8) { SendMessageA(hCombo, WM_SETFONT, (WPARAM)hFont1, FALSE); GetClientRect(hCombo, &r); expect_rect(r, 0, 0, 100, 18); SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r); MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); - todo_wine expect_rect(r, 5, 5, 105, 105 - (font_height(GetStockObject(SYSTEM_FONT)) - font_height(hFont1))); + todo_wine expect_rect(r, 5, 5, 105, 105 - (get_font_height(GetStockObject(SYSTEM_FONT)) - get_font_height(hFont1)));
SendMessageA(hCombo, WM_SETFONT, (WPARAM)hFont2, FALSE); GetClientRect(hCombo, &r); expect_rect(r, 0, 0, 100, 16); SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r); MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); - todo_wine expect_rect(r, 5, 5, 105, 105 - (font_height(GetStockObject(SYSTEM_FONT)) - font_height(hFont2))); + todo_wine expect_rect(r, 5, 5, 105, 105 - (get_font_height(GetStockObject(SYSTEM_FONT)) - get_font_height(hFont2)));
SendMessageA(hCombo, WM_SETFONT, (WPARAM)hFont1, FALSE); GetClientRect(hCombo, &r); expect_rect(r, 0, 0, 100, 18); SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r); MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); - todo_wine expect_rect(r, 5, 5, 105, 105 - (font_height(GetStockObject(SYSTEM_FONT)) - font_height(hFont1))); + todo_wine expect_rect(r, 5, 5, 105, 105 - (get_font_height(GetStockObject(SYSTEM_FONT)) - get_font_height(hFont1))); } else { ok(0, "Expected Marlett font heights 10/8, got %d/%d\n", - font_height(hFont1), font_height(hFont2)); + get_font_height(hFont1), get_font_height(hFont2)); }
for (i = 1; i < 30; i++) { HFONT hFont = CreateFontA(i, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett"); - int height = font_height(hFont); + int height = get_font_height(hFont);
SendMessageA(hCombo, WM_SETFONT, (WPARAM)hFont, FALSE); GetClientRect(hCombo, &r);