[User32|Tests] Sync Port Wine Combo Controls.
authorJames Tabor <james.tabor@reactos.org>
Sat, 21 Sep 2019 13:47:56 +0000 (08:47 -0500)
committerJames Tabor <james.tabor@reactos.org>
Sat, 21 Sep 2019 13:47:56 +0000 (08:47 -0500)
Need to cross check these changes with WINE ComCtl32 before you PANIC
HACK!!!!

Not in order:
Piotr Caban : Remove unneeded RECT parameter from CBPaintText helper.
              Don't invalidate ComboBox on CB_SETCURSEL message.
Don't invalidate ComboBox on LBN_SELCHANGE and
LBN_SELCANCEL.
              Add more CB_SETCURSEL tests on ComboBox.
              Redraw combo text field even if it's empty.
Let ComboBox edit control handle the redraw even if
CBF_NOREDRAW is set.
Don't do the painting if combobox is not visible in
CBPaintText.

Dmitry Timoshkov : Don't force a combobox repaint on WM_SIZE.

This breaks z-order based painting and causes side effects
for
applications that during the WM_PAINT processing reference
internal
             data associated with a not fully initialized window.
Ref :
https://source.winehq.org/git/wine.git/commit/2d9e3236ea8ae752184b8a285f9d616ec94afb8f

Fabian Maurer : Set listbox popup height correctly and add tests.

                Properly set dropdown height.

             Now that user32 and comctl32 combo are separated,
             this won't lead to a regression anymore
             Ref :
https://source.winehq.org/git/wine.git/commit/3d0be0bad8eca72e67199ebfb451150d58494ba3
             Info by Sebastian Lackner Ref:
https://source.winehq.org/git/wine.git/commit/f0fc0349976924379cc3ae2ff95fb342d7541294

Nikolay Sivov : Remove some misleading TODOs and confusing comments.

modules/rostests/winetests/user32/combo.c
win32ss/user/user32/controls/combo.c

index ad706ea..0d3b1b1 100644 (file)
@@ -291,7 +291,7 @@ static void test_WM_LBUTTONDOWN(void)
     hCombo = CreateWindowA("ComboBox", "Combo", WS_VISIBLE|WS_CHILD|CBS_DROPDOWN,
             0, 0, 200, 150, hMainWnd, (HMENU)COMBO_ID, NULL, 0);
 
-    for (i = 0; i < sizeof(choices)/sizeof(UINT); i++){
+    for (i = 0; i < ARRAY_SIZE(choices); i++){
         sprintf(buffer, stringFormat, choices[i]);
         result = SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM)buffer);
         ok(result == i,
@@ -688,28 +688,28 @@ static void test_listbox_size(DWORD style)
         int height_combo;
         BOOL todo;
     } info_height[] = {
-        {2, 24, TRUE},
+        {2, 24, FALSE},
         {2, 41, TRUE},
-        {2, 42, TRUE},
-        {2, 50, TRUE},
+        {2, 42, FALSE},
+        {2, 50, FALSE},
         {2, 60},
         {2, 80},
         {2, 89},
         {2, 90},
         {2, 100},
 
-        {10, 24, TRUE},
+        {10, 24, FALSE},
         {10, 41, TRUE},
-        {10, 42, TRUE},
-        {10, 50, TRUE},
-        {10, 60, TRUE},
-        {10, 80, TRUE},
+        {10, 42, FALSE},
+        {10, 50, FALSE},
+        {10, 60, FALSE},
+        {10, 80, FALSE},
         {10, 89, TRUE},
-        {10, 90, TRUE},
-        {10, 100, TRUE},
+        {10, 90, FALSE},
+        {10, 100, FALSE},
     };
 
-    for(test = 0; test < sizeof(info_height) / sizeof(info_height[0]); test++)
+    for(test = 0; test < ARRAY_SIZE(info_height); test++)
     {
         const struct list_size_info *info_test = &info_height[test];
         int height_item; /* Height of a list item */
index 1153790..da453ec 100644 (file)
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * NOTES
- *
- * This code was audited for completeness against the documented features
- * of Comctl32.dll version 6.0 on Oct. 4, 2004, by Dimitrie O. Paun.
- * 
- * Unless otherwise noted, we believe this code to be complete, as per
- * the specification mentioned above.
- * If you discover missing features, or bugs, please note them below.
- * 
  * TODO:
- *   - ComboBox_[GS]etMinVisible()
- *   - CB_GETMINVISIBLE, CB_SETMINVISIBLE
  *   - CB_SETTOPINDEX
  */
 
@@ -651,6 +640,58 @@ static void CBPaintButton( LPHEADCOMBO lphc, HDC hdc, RECT rectButton)
     DrawFrameControl(hdc, &rectButton, DFC_SCROLL, buttonState);
 }
 
+/***********************************************************************
+ *           COMBO_PrepareColors
+ *
+ * This method will sent the appropriate WM_CTLCOLOR message to
+ * prepare and setup the colors for the combo's DC.
+ *
+ * It also returns the brush to use for the background.
+ */
+static HBRUSH COMBO_PrepareColors(
+  LPHEADCOMBO lphc,
+  HDC         hDC)
+{
+  HBRUSH  hBkgBrush;
+
+  /*
+   * Get the background brush for this control.
+   */
+  if (CB_DISABLED(lphc))
+  {
+#ifdef __REACTOS__
+    hBkgBrush = GetControlColor(lphc->owner, lphc->self, hDC, WM_CTLCOLORSTATIC);
+#else
+    hBkgBrush = (HBRUSH)SendMessageW(lphc->owner, WM_CTLCOLORSTATIC,
+                                    (WPARAM)hDC, (LPARAM)lphc->self );
+#endif
+    /*
+     * We have to change the text color since WM_CTLCOLORSTATIC will
+     * set it to the "enabled" color. This is the same behavior as the
+     * edit control
+     */
+    SetTextColor(hDC, GetSysColor(COLOR_GRAYTEXT));
+  }
+  else
+  {
+      /* FIXME: In which cases WM_CTLCOLORLISTBOX should be sent? */
+#ifdef __REACTOS__
+      hBkgBrush = GetControlColor(lphc->owner, lphc->self, hDC, WM_CTLCOLOREDIT);
+#else
+      hBkgBrush = (HBRUSH)SendMessageW(lphc->owner, WM_CTLCOLOREDIT,
+                                      (WPARAM)hDC, (LPARAM)lphc->self );
+#endif
+  }
+
+  /*
+   * Catch errors.
+   */
+  if( !hBkgBrush )
+    hBkgBrush = GetSysColorBrush(COLOR_WINDOW);
+
+  return hBkgBrush;
+}
+
 /***********************************************************************
  *           CBPaintText
  *
@@ -658,14 +699,12 @@ static void CBPaintButton( LPHEADCOMBO lphc, HDC hdc, RECT rectButton)
  */
 static void CBPaintText(
   LPHEADCOMBO lphc,
-  HDC         hdc,
-  RECT        rectEdit)
+  HDC         hdc_paint)
 {
+   RECT rectEdit = lphc->textRect;
    INT id, size = 0;
    LPWSTR pText = NULL;
 
-   if( lphc->wState & CBF_NOREDRAW ) return;
-
    TRACE("\n");
 
    /* follow Windows combobox that sends a bunch of text
@@ -683,27 +722,31 @@ static void CBPaintText(
            pText[size] = '\0'; /* just in case */
        } else return;
    }
-   else
-       if( !CB_OWNERDRAWN(lphc) )
-          return;
 
    if( lphc->wState & CBF_EDIT )
    {
         static const WCHAR empty_stringW[] = { 0 };
        if( CB_HASSTRINGS(lphc) ) SetWindowTextW( lphc->hWndEdit, pText ? pText : empty_stringW );
        if( lphc->wState & CBF_FOCUSED )
-           SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1));
+           SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, MAXLONG);
    }
-   else /* paint text field ourselves */
+   else if(!(lphc->wState & CBF_NOREDRAW) && IsWindowVisible( lphc->self ))
    {
-     UINT      itemState = ODS_COMBOBOXEDIT;
-     HFONT     hPrevFont = (lphc->hFont) ? SelectObject(hdc, lphc->hFont) : 0;
+     /* paint text field ourselves */
+     HDC hdc = hdc_paint ? hdc_paint : GetDC(lphc->self);
+     UINT itemState = ODS_COMBOBOXEDIT;
+     HFONT hPrevFont = (lphc->hFont) ? SelectObject(hdc, lphc->hFont) : 0;
+     HBRUSH hPrevBrush, hBkgBrush;
 
      /*
       * Give ourselves some space.
       */
      InflateRect( &rectEdit, -1, -1 );
 
+     hBkgBrush = COMBO_PrepareColors( lphc, hdc );
+     hPrevBrush = SelectObject( hdc, hBkgBrush );
+     FillRect( hdc, &rectEdit, hBkgBrush );
+
      if( CB_OWNERDRAWN(lphc) )
      {
        DRAWITEMSTRUCT dis;
@@ -769,6 +812,12 @@ static void CBPaintText(
 
      if( hPrevFont )
        SelectObject(hdc, hPrevFont );
+
+     if( hPrevBrush )
+        SelectObject( hdc, hPrevBrush );
+
+     if( !hdc_paint )
+       ReleaseDC( lphc->self, hdc );
    }
 #ifdef __REACTOS__
    if (pText)
@@ -801,59 +850,6 @@ static void CBPaintBorder(
   DrawEdge(hdc, &clientRect, EDGE_SUNKEN, BF_RECT);
 }
 
-/***********************************************************************
- *           COMBO_PrepareColors
- *
- * This method will sent the appropriate WM_CTLCOLOR message to
- * prepare and setup the colors for the combo's DC.
- *
- * It also returns the brush to use for the background.
- */
-static HBRUSH COMBO_PrepareColors(
-  LPHEADCOMBO lphc,
-  HDC         hDC)
-{
-  HBRUSH  hBkgBrush;
-
-  /*
-   * Get the background brush for this control.
-   */
-  if (CB_DISABLED(lphc))
-  {
-#ifdef __REACTOS__
-    hBkgBrush = GetControlColor(lphc->owner, lphc->self, hDC, WM_CTLCOLORSTATIC);
-#else
-    hBkgBrush = (HBRUSH)SendMessageW(lphc->owner, WM_CTLCOLORSTATIC,
-                                    (WPARAM)hDC, (LPARAM)lphc->self );
-#endif
-    /*
-     * We have to change the text color since WM_CTLCOLORSTATIC will
-     * set it to the "enabled" color. This is the same behavior as the
-     * edit control
-     */
-    SetTextColor(hDC, GetSysColor(COLOR_GRAYTEXT));
-  }
-  else
-  {
-      /* FIXME: In which cases WM_CTLCOLORLISTBOX should be sent? */
-#ifdef __REACTOS__
-      hBkgBrush = GetControlColor(lphc->owner, lphc->self, hDC, WM_CTLCOLOREDIT);
-#else
-      hBkgBrush = (HBRUSH)SendMessageW(lphc->owner, WM_CTLCOLOREDIT,
-                                      (WPARAM)hDC, (LPARAM)lphc->self );
-#endif
-  }
-
-  /*
-   * Catch errors.
-   */
-  if( !hBkgBrush )
-    hBkgBrush = GetSysColorBrush(COLOR_WINDOW);
-
-  return hBkgBrush;
-}
-
-
 /***********************************************************************
  *           COMBO_Paint
  */
@@ -902,7 +898,7 @@ static LRESULT COMBO_Paint(LPHEADCOMBO lphc, HDC hParamDC)
       }
 
       if( !(lphc->wState & CBF_EDIT) )
-       CBPaintText( lphc, hDC, lphc->textRect);
+       CBPaintText( lphc, hDC );
 
       if( hPrevBrush )
        SelectObject( hDC, hPrevBrush );
@@ -1055,14 +1051,6 @@ static void CBDropDown( LPHEADCOMBO lphc )
 
       if (nHeight < nDroppedHeight - COMBO_YBORDERSIZE())
          nDroppedHeight = nHeight + COMBO_YBORDERSIZE();
-
-      if (nDroppedHeight < nHeight)
-      {
-            if (nItems < 5)
-                nDroppedHeight = (nItems+1)*nIHeight;
-            else if (nDroppedHeight < 6*nIHeight)
-                nDroppedHeight = 6*nIHeight;
-      }
    }
 
    r.left = rect.left;
@@ -1580,7 +1568,7 @@ static void COMBO_Size( LPHEADCOMBO lphc )
                  &lphc->buttonRect,
                  &lphc->droppedRect);
 
-  CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
+  CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, FALSE );
 }
 
 
@@ -2203,10 +2191,7 @@ LRESULT WINAPI ComboWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPAR
                    SendMessageW(lphc->hWndLBox, LB_SETTOPINDEX, wParam, 0);
 
                /* no LBN_SELCHANGE in this case, update manually */
-               if( lphc->wState & CBF_EDIT )
-                   CBUpdateEdit( lphc, (INT)wParam );
-               else
-                   InvalidateRect(lphc->self, &lphc->textRect, TRUE);
+               CBPaintText( lphc, NULL );
                lphc->wState &= ~CBF_SELCHANGE;
                return  lParam;
        case CB_GETLBTEXT: