Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/user32/combo.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/dlls/user32/combo.c b/dlls/user32/combo.c index 40ff0ef521..52d2f7190d 100644 --- a/dlls/user32/combo.c +++ b/dlls/user32/combo.c @@ -574,10 +574,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;
@@ -588,7 +591,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); }
/*********************************************************************** @@ -816,11 +819,7 @@ static LRESULT COMBO_Paint(LPHEADCOMBO lphc, HDC hParamDC) * In non 3.1 look, there is a sunken border on the combobox */ 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/user32/combo.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/dlls/user32/combo.c b/dlls/user32/combo.c index 52d2f7190d..631bad0aa9 100644 --- a/dlls/user32/combo.c +++ b/dlls/user32/combo.c @@ -766,16 +766,13 @@ static void CBPaintText( /*********************************************************************** * 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 { @@ -818,7 +815,7 @@ static LRESULT COMBO_Paint(LPHEADCOMBO lphc, HDC hParamDC) /* * In non 3.1 look, there is a sunken border on the combobox */ - CBPaintBorder(lphc->self, lphc, hDC); + CBPaintBorder(lphc, hDC); CBPaintButton(lphc, hDC);
/* paint the edit control padding area */
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/user32/combo.c | 111 ++++++++++++++++++++++------------------- dlls/user32/controls.h | 4 +- 2 files changed, 63 insertions(+), 52 deletions(-)
diff --git a/dlls/user32/combo.c b/dlls/user32/combo.c index 631bad0aa9..ff5ed18878 100644 --- a/dlls/user32/combo.c +++ b/dlls/user32/combo.c @@ -75,6 +75,9 @@ static UINT CBitHeight, CBitWidth; #define COMBO_EDITBUTTONSPACE() 0 #define EDIT_CONTROL_PADDING() 1
+static void CBCalcPlacement(HEADCOMBO *combo); +static void CBResetPos(HEADCOMBO *combo, BOOL redraw); + /********************************************************************* * combo class descriptor */ @@ -181,6 +184,25 @@ static LRESULT COMBO_NCDestroy( LPHEADCOMBO 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 * @@ -193,35 +215,18 @@ static LRESULT COMBO_NCDestroy( LPHEADCOMBO 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;
- if( hPrevFont ) - SelectObject( hDC, hPrevFont ); - - ReleaseDC(lphc->self, hDC); - - iTextItemHeight = baseUnitY + 4; - } + item_height = lphc->item_height;
/* * Check the ownerdraw case if we haven't asked the parent the size @@ -232,7 +237,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 );
/* @@ -249,10 +254,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 @@ -273,10 +278,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; }
/*********************************************************************** @@ -286,13 +291,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);
@@ -304,12 +308,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, FALSE); }
/*********************************************************************** @@ -326,7 +335,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; @@ -412,11 +421,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 @@ -1435,8 +1442,11 @@ static void CBResetPos(HEADCOMBO *combo, BOOL redraw) /*********************************************************************** * 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. @@ -1449,7 +1459,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 @@ -1469,9 +1479,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); @@ -1485,10 +1499,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. @@ -1524,7 +1536,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. @@ -1781,8 +1793,7 @@ LRESULT ComboWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar return result; } case WM_SIZE: - if( lphc->hWndLBox && - !(lphc->wState & CBF_NORESIZE) ) COMBO_Size( lphc ); + COMBO_Size( lphc ); return TRUE; case WM_SETFONT: COMBO_Font( lphc, (HFONT)wParam, (BOOL)lParam ); @@ -1998,7 +2009,7 @@ LRESULT ComboWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar 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); if( (lphc->wState & CBF_EDIT) && CB_HASSTRINGS(lphc) ) diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h index d372bafcef..0b0f1c2801 100644 --- a/dlls/user32/controls.h +++ b/dlls/user32/controls.h @@ -219,8 +219,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; } HEADCOMBO,*LPHEADCOMBO;
extern BOOL COMBO_FlipListbox( LPHEADCOMBO, BOOL, BOOL ) DECLSPEC_HIDDEN;
From: John Alway thaleslv@yahoo.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/user32/tests/combo.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/tests/combo.c b/dlls/user32/tests/combo.c index 6b51ff9719..d203f37c2b 100644 --- a/dlls/user32/tests/combo.c +++ b/dlls/user32/tests/combo.c @@ -43,7 +43,7 @@ static HWND build_combo(DWORD style) return CreateWindowA("ComboBox", "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; @@ -74,12 +74,13 @@ static BOOL is_font_installed(const char *name) static void test_setitemheight(DWORD style) { HWND hCombo = build_combo(style); + int i, font_height, height; + HFONT hFont; RECT r; - int i;
trace("Style %x\n", style); 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); @@ -92,6 +93,22 @@ static void test_setitemheight(DWORD style) }
DestroyWindow(hCombo); + + /* Set item height below text height, force resize. */ + hCombo = build_combo(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_setfont(DWORD style) @@ -114,7 +131,7 @@ static void test_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); @@ -123,39 +140,39 @@ static void test_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);