user32/combo: Force minimal item height.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2019-11-27 11:31:04 +03:00 committed by Alexandre Julliard
parent 722f4fc084
commit ad6a8d50e8
2 changed files with 63 additions and 52 deletions

View File

@ -75,6 +75,9 @@ static UINT CBitHeight, CBitWidth;
#define COMBO_EDITBUTTONSPACE() 0 #define COMBO_EDITBUTTONSPACE() 0
#define EDIT_CONTROL_PADDING() 1 #define EDIT_CONTROL_PADDING() 1
static void CBCalcPlacement(HEADCOMBO *combo);
static void CBResetPos(HEADCOMBO *combo, BOOL redraw);
/********************************************************************* /*********************************************************************
* combo class descriptor * combo class descriptor
*/ */
@ -181,6 +184,25 @@ static LRESULT COMBO_NCDestroy( LPHEADCOMBO lphc )
return 0; 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 * CBGetTextAreaHeight
* *
@ -193,35 +215,18 @@ static LRESULT COMBO_NCDestroy( LPHEADCOMBO lphc )
* This height was determined through experimentation. * This height was determined through experimentation.
* CBCalcPlacement will add 2*COMBO_YBORDERSIZE pixels for the border * 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) item_height = lphc->item_height;
hPrevFont = SelectObject( hDC, lphc->hFont );
GetTextMetricsW(hDC, &tm);
baseUnitY = tm.tmHeight;
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 * Check the ownerdraw case if we haven't asked the parent the size
@ -232,7 +237,7 @@ static INT CBGetTextAreaHeight(HEADCOMBO *lphc)
{ {
MEASUREITEMSTRUCT measureItem; MEASUREITEMSTRUCT measureItem;
RECT clientRect; RECT clientRect;
INT originalItemHeight = iTextItemHeight; INT originalItemHeight = item_height;
UINT id = (UINT)GetWindowLongPtrW( lphc->self, GWLP_ID ); UINT id = (UINT)GetWindowLongPtrW( lphc->self, GWLP_ID );
/* /*
@ -249,10 +254,10 @@ static INT CBGetTextAreaHeight(HEADCOMBO *lphc)
measureItem.CtlID = id; measureItem.CtlID = id;
measureItem.itemID = -1; measureItem.itemID = -1;
measureItem.itemWidth = clientRect.right; measureItem.itemWidth = clientRect.right;
measureItem.itemHeight = iTextItemHeight - 6; /* ownerdrawn cb is taller */ measureItem.itemHeight = item_height - 6; /* ownerdrawn cb is taller */
measureItem.itemData = 0; measureItem.itemData = 0;
SendMessageW(lphc->owner, WM_MEASUREITEM, id, (LPARAM)&measureItem); 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 * 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 * 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 * a re-arranging of the contents of the combobox and the recalculation
* of the size of the "real" control window. * of the size of the "real" control window.
*/ */
static void CBForceDummyResize( static void CBForceDummyResize(LPHEADCOMBO lphc)
LPHEADCOMBO lphc)
{ {
RECT windowRect; RECT windowRect;
int newComboHeight; int newComboHeight;
newComboHeight = CBGetTextAreaHeight(lphc) + 2*COMBO_YBORDERSIZE(); newComboHeight = CBGetTextAreaHeight(lphc, FALSE) + 2*COMBO_YBORDERSIZE();
GetWindowRect(lphc->self, &windowRect); GetWindowRect(lphc->self, &windowRect);
@ -304,12 +308,17 @@ static void CBForceDummyResize(
* this will cancel-out in the processing of the WM_WINDOWPOSCHANGING * this will cancel-out in the processing of the WM_WINDOWPOSCHANGING
* message. * message.
*/ */
lphc->wState |= CBF_NORESIZE;
SetWindowPos( lphc->self, SetWindowPos( lphc->self,
NULL, NULL,
0, 0, 0, 0,
windowRect.right - windowRect.left, windowRect.right - windowRect.left,
newComboHeight, newComboHeight,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE ); 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()); InflateRect(&combo->textRect, -COMBO_XBORDERSIZE(), -COMBO_YBORDERSIZE());
/* Chop off the bottom part to fit with the height of the text area. */ /* 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. */ /* The button starts the same vertical position as the text area. */
combo->buttonRect = combo->textRect; combo->buttonRect = combo->textRect;
@ -412,11 +421,9 @@ static LRESULT COMBO_Create( HWND hwnd, LPHEADCOMBO lphc, HWND hwndParent, LONG
lphc->owner = hwndParent; lphc->owner = hwndParent;
/* lphc->droppedWidth = 0;
* The item height and dropped width are not set when the control
* is created. lphc->item_height = combo_get_text_height(lphc);
*/
lphc->droppedWidth = lphc->editHeight = 0;
/* /*
* The first time we go through, we want to measure the ownerdraw item * 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 * 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 * Those controls are always the same height. So we have to make sure
* they are not resized to another value. * they are not resized to another value.
@ -1449,7 +1459,7 @@ static void COMBO_Size( LPHEADCOMBO lphc )
GetWindowRect(lphc->self, &rc); GetWindowRect(lphc->self, &rc);
curComboHeight = rc.bottom - rc.top; curComboHeight = rc.bottom - rc.top;
curComboWidth = rc.right - rc.left; 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 * Resizing a combobox has another side effect, it resizes the dropped
@ -1470,8 +1480,12 @@ static void COMBO_Size( LPHEADCOMBO lphc )
* Restore original height * Restore original height
*/ */
if (curComboHeight != newComboHeight) if (curComboHeight != newComboHeight)
{
lphc->wState |= CBF_NORESIZE;
SetWindowPos(lphc->self, 0, 0, 0, curComboWidth, newComboHeight, SetWindowPos(lphc->self, 0, 0, 0, curComboWidth, newComboHeight,
SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW); SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW);
lphc->wState &= ~CBF_NORESIZE;
}
} }
CBCalcPlacement(lphc); CBCalcPlacement(lphc);
@ -1485,10 +1499,8 @@ static void COMBO_Size( LPHEADCOMBO lphc )
*/ */
static void COMBO_Font( LPHEADCOMBO lphc, HFONT hFont, BOOL bRedraw ) static void COMBO_Font( LPHEADCOMBO lphc, HFONT hFont, BOOL bRedraw )
{ {
/*
* Set the font
*/
lphc->hFont = hFont; lphc->hFont = hFont;
lphc->item_height = combo_get_text_height(lphc);
/* /*
* Propagate to owned windows. * Propagate to owned windows.
@ -1524,7 +1536,7 @@ static LRESULT COMBO_SetItemHeight( LPHEADCOMBO lphc, INT index, INT height )
{ {
if( height < 32768 ) 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. * Redo the layout of the control.
@ -1781,8 +1793,7 @@ LRESULT ComboWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar
return result; return result;
} }
case WM_SIZE: case WM_SIZE:
if( lphc->hWndLBox && COMBO_Size( lphc );
!(lphc->wState & CBF_NORESIZE) ) COMBO_Size( lphc );
return TRUE; return TRUE;
case WM_SETFONT: case WM_SETFONT:
COMBO_Font( lphc, (HFONT)wParam, (BOOL)lParam ); 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: case CB_GETITEMHEIGHT:
if( (INT)wParam >= 0 ) /* listbox item */ if( (INT)wParam >= 0 ) /* listbox item */
return SendMessageW(lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0); return SendMessageW(lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
return CBGetTextAreaHeight(lphc); return CBGetTextAreaHeight(lphc, FALSE);
case CB_RESETCONTENT: case CB_RESETCONTENT:
SendMessageW(lphc->hWndLBox, LB_RESETCONTENT, 0, 0); SendMessageW(lphc->hWndLBox, LB_RESETCONTENT, 0, 0);
if( (lphc->wState & CBF_EDIT) && CB_HASSTRINGS(lphc) ) if( (lphc->wState & CBF_EDIT) && CB_HASSTRINGS(lphc) )

View File

@ -219,8 +219,8 @@ typedef struct
RECT droppedRect; RECT droppedRect;
INT droppedIndex; INT droppedIndex;
INT fixedOwnerDrawHeight; INT fixedOwnerDrawHeight;
INT droppedWidth; /* last two are not used unless set */ INT droppedWidth; /* not used unless set explicitly */
INT editHeight; /* explicitly */ INT item_height;
} HEADCOMBO,*LPHEADCOMBO; } HEADCOMBO,*LPHEADCOMBO;
extern BOOL COMBO_FlipListbox( LPHEADCOMBO, BOOL, BOOL ) DECLSPEC_HIDDEN; extern BOOL COMBO_FlipListbox( LPHEADCOMBO, BOOL, BOOL ) DECLSPEC_HIDDEN;