[PATCH 3/4] user32/combo: Force minimal item height
Nikolay Sivov
nsivov at codeweavers.com
Wed Nov 27 02:31:04 CST 2019
Signed-off-by: Nikolay Sivov <nsivov at 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;
--
2.24.0
More information about the wine-devel
mailing list