https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c57d4d7b9e76959795b0a…
commit c57d4d7b9e76959795b0abc66b2be5b7f46d3d3c
Author: James Tabor <james.tabor(a)reactos.org>
AuthorDate: Sat Sep 21 08:47:56 2019 -0500
Commit: James Tabor <james.tabor(a)reactos.org>
CommitDate: Sat Sep 21 08:47:56 2019 -0500
[User32|Tests] Sync Port Wine Combo Controls.
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/2d9e3236ea8ae752184b8a285f9d6…
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/3d0be0bad8eca72e67199ebfb4511…
Info by Sebastian Lackner Ref:
https://source.winehq.org/git/wine.git/commit/f0fc0349976924379cc3ae2ff95fb…
Nikolay Sivov : Remove some misleading TODOs and confusing comments.
---
modules/rostests/winetests/user32/combo.c | 24 ++---
win32ss/user/user32/controls/combo.c | 163 ++++++++++++++----------------
2 files changed, 86 insertions(+), 101 deletions(-)
diff --git a/modules/rostests/winetests/user32/combo.c
b/modules/rostests/winetests/user32/combo.c
index ad706ea7540..0d3b1b170f5 100644
--- a/modules/rostests/winetests/user32/combo.c
+++ b/modules/rostests/winetests/user32/combo.c
@@ -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 */
diff --git a/win32ss/user/user32/controls/combo.c b/win32ss/user/user32/controls/combo.c
index 11537901e5f..da453ec08a9 100644
--- a/win32ss/user/user32/controls/combo.c
+++ b/win32ss/user/user32/controls/combo.c
@@ -17,18 +17,7 @@
* 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: