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:
parent
722f4fc084
commit
ad6a8d50e8
|
@ -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) )
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue