Nikolay Sivov : user32/combo: Force minimal item height.

Alexandre Julliard julliard at winehq.org
Wed Nov 27 16:32:29 CST 2019


Module: wine
Branch: master
Commit: ad6a8d50e8b7e0bebdf9acb05fc9e707ba925629
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=ad6a8d50e8b7e0bebdf9acb05fc9e707ba925629

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Nov 27 11:31:04 2019 +0300

user32/combo: Force minimal item height.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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;




More information about the wine-cvs mailing list