mirror of
https://github.com/reactos/reactos.git
synced 2025-05-28 13:38:19 +00:00
[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 :2d9e3236ea
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 :3d0be0bad8
Info by Sebastian Lackner Ref:f0fc034997
Nikolay Sivov : Remove some misleading TODOs and confusing comments.
This commit is contained in:
parent
432854ee18
commit
c57d4d7b9e
2 changed files with 86 additions and 101 deletions
|
@ -291,7 +291,7 @@ static void test_WM_LBUTTONDOWN(void)
|
||||||
hCombo = CreateWindowA("ComboBox", "Combo", WS_VISIBLE|WS_CHILD|CBS_DROPDOWN,
|
hCombo = CreateWindowA("ComboBox", "Combo", WS_VISIBLE|WS_CHILD|CBS_DROPDOWN,
|
||||||
0, 0, 200, 150, hMainWnd, (HMENU)COMBO_ID, NULL, 0);
|
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]);
|
sprintf(buffer, stringFormat, choices[i]);
|
||||||
result = SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM)buffer);
|
result = SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM)buffer);
|
||||||
ok(result == i,
|
ok(result == i,
|
||||||
|
@ -688,28 +688,28 @@ static void test_listbox_size(DWORD style)
|
||||||
int height_combo;
|
int height_combo;
|
||||||
BOOL todo;
|
BOOL todo;
|
||||||
} info_height[] = {
|
} info_height[] = {
|
||||||
{2, 24, TRUE},
|
{2, 24, FALSE},
|
||||||
{2, 41, TRUE},
|
{2, 41, TRUE},
|
||||||
{2, 42, TRUE},
|
{2, 42, FALSE},
|
||||||
{2, 50, TRUE},
|
{2, 50, FALSE},
|
||||||
{2, 60},
|
{2, 60},
|
||||||
{2, 80},
|
{2, 80},
|
||||||
{2, 89},
|
{2, 89},
|
||||||
{2, 90},
|
{2, 90},
|
||||||
{2, 100},
|
{2, 100},
|
||||||
|
|
||||||
{10, 24, TRUE},
|
{10, 24, FALSE},
|
||||||
{10, 41, TRUE},
|
{10, 41, TRUE},
|
||||||
{10, 42, TRUE},
|
{10, 42, FALSE},
|
||||||
{10, 50, TRUE},
|
{10, 50, FALSE},
|
||||||
{10, 60, TRUE},
|
{10, 60, FALSE},
|
||||||
{10, 80, TRUE},
|
{10, 80, FALSE},
|
||||||
{10, 89, TRUE},
|
{10, 89, TRUE},
|
||||||
{10, 90, TRUE},
|
{10, 90, FALSE},
|
||||||
{10, 100, TRUE},
|
{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];
|
const struct list_size_info *info_test = &info_height[test];
|
||||||
int height_item; /* Height of a list item */
|
int height_item; /* Height of a list item */
|
||||||
|
|
|
@ -17,18 +17,7 @@
|
||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* 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:
|
* TODO:
|
||||||
* - ComboBox_[GS]etMinVisible()
|
|
||||||
* - CB_GETMINVISIBLE, CB_SETMINVISIBLE
|
|
||||||
* - CB_SETTOPINDEX
|
* - CB_SETTOPINDEX
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -651,6 +640,58 @@ static void CBPaintButton( LPHEADCOMBO lphc, HDC hdc, RECT rectButton)
|
||||||
DrawFrameControl(hdc, &rectButton, DFC_SCROLL, buttonState);
|
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
|
* CBPaintText
|
||||||
*
|
*
|
||||||
|
@ -658,14 +699,12 @@ static void CBPaintButton( LPHEADCOMBO lphc, HDC hdc, RECT rectButton)
|
||||||
*/
|
*/
|
||||||
static void CBPaintText(
|
static void CBPaintText(
|
||||||
LPHEADCOMBO lphc,
|
LPHEADCOMBO lphc,
|
||||||
HDC hdc,
|
HDC hdc_paint)
|
||||||
RECT rectEdit)
|
|
||||||
{
|
{
|
||||||
|
RECT rectEdit = lphc->textRect;
|
||||||
INT id, size = 0;
|
INT id, size = 0;
|
||||||
LPWSTR pText = NULL;
|
LPWSTR pText = NULL;
|
||||||
|
|
||||||
if( lphc->wState & CBF_NOREDRAW ) return;
|
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
/* follow Windows combobox that sends a bunch of text
|
/* follow Windows combobox that sends a bunch of text
|
||||||
|
@ -683,27 +722,31 @@ static void CBPaintText(
|
||||||
pText[size] = '\0'; /* just in case */
|
pText[size] = '\0'; /* just in case */
|
||||||
} else return;
|
} else return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if( !CB_OWNERDRAWN(lphc) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( lphc->wState & CBF_EDIT )
|
if( lphc->wState & CBF_EDIT )
|
||||||
{
|
{
|
||||||
static const WCHAR empty_stringW[] = { 0 };
|
static const WCHAR empty_stringW[] = { 0 };
|
||||||
if( CB_HASSTRINGS(lphc) ) SetWindowTextW( lphc->hWndEdit, pText ? pText : empty_stringW );
|
if( CB_HASSTRINGS(lphc) ) SetWindowTextW( lphc->hWndEdit, pText ? pText : empty_stringW );
|
||||||
if( lphc->wState & CBF_FOCUSED )
|
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 ))
|
||||||
{
|
{
|
||||||
|
/* paint text field ourselves */
|
||||||
|
HDC hdc = hdc_paint ? hdc_paint : GetDC(lphc->self);
|
||||||
UINT itemState = ODS_COMBOBOXEDIT;
|
UINT itemState = ODS_COMBOBOXEDIT;
|
||||||
HFONT hPrevFont = (lphc->hFont) ? SelectObject(hdc, lphc->hFont) : 0;
|
HFONT hPrevFont = (lphc->hFont) ? SelectObject(hdc, lphc->hFont) : 0;
|
||||||
|
HBRUSH hPrevBrush, hBkgBrush;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Give ourselves some space.
|
* Give ourselves some space.
|
||||||
*/
|
*/
|
||||||
InflateRect( &rectEdit, -1, -1 );
|
InflateRect( &rectEdit, -1, -1 );
|
||||||
|
|
||||||
|
hBkgBrush = COMBO_PrepareColors( lphc, hdc );
|
||||||
|
hPrevBrush = SelectObject( hdc, hBkgBrush );
|
||||||
|
FillRect( hdc, &rectEdit, hBkgBrush );
|
||||||
|
|
||||||
if( CB_OWNERDRAWN(lphc) )
|
if( CB_OWNERDRAWN(lphc) )
|
||||||
{
|
{
|
||||||
DRAWITEMSTRUCT dis;
|
DRAWITEMSTRUCT dis;
|
||||||
|
@ -769,6 +812,12 @@ static void CBPaintText(
|
||||||
|
|
||||||
if( hPrevFont )
|
if( hPrevFont )
|
||||||
SelectObject(hdc, hPrevFont );
|
SelectObject(hdc, hPrevFont );
|
||||||
|
|
||||||
|
if( hPrevBrush )
|
||||||
|
SelectObject( hdc, hPrevBrush );
|
||||||
|
|
||||||
|
if( !hdc_paint )
|
||||||
|
ReleaseDC( lphc->self, hdc );
|
||||||
}
|
}
|
||||||
#ifdef __REACTOS__
|
#ifdef __REACTOS__
|
||||||
if (pText)
|
if (pText)
|
||||||
|
@ -801,59 +850,6 @@ static void CBPaintBorder(
|
||||||
DrawEdge(hdc, &clientRect, EDGE_SUNKEN, BF_RECT);
|
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
|
* COMBO_Paint
|
||||||
*/
|
*/
|
||||||
|
@ -902,7 +898,7 @@ static LRESULT COMBO_Paint(LPHEADCOMBO lphc, HDC hParamDC)
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !(lphc->wState & CBF_EDIT) )
|
if( !(lphc->wState & CBF_EDIT) )
|
||||||
CBPaintText( lphc, hDC, lphc->textRect);
|
CBPaintText( lphc, hDC );
|
||||||
|
|
||||||
if( hPrevBrush )
|
if( hPrevBrush )
|
||||||
SelectObject( hDC, hPrevBrush );
|
SelectObject( hDC, hPrevBrush );
|
||||||
|
@ -1055,14 +1051,6 @@ static void CBDropDown( LPHEADCOMBO lphc )
|
||||||
|
|
||||||
if (nHeight < nDroppedHeight - COMBO_YBORDERSIZE())
|
if (nHeight < nDroppedHeight - COMBO_YBORDERSIZE())
|
||||||
nDroppedHeight = nHeight + 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;
|
r.left = rect.left;
|
||||||
|
@ -1580,7 +1568,7 @@ static void COMBO_Size( LPHEADCOMBO lphc )
|
||||||
&lphc->buttonRect,
|
&lphc->buttonRect,
|
||||||
&lphc->droppedRect);
|
&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);
|
SendMessageW(lphc->hWndLBox, LB_SETTOPINDEX, wParam, 0);
|
||||||
|
|
||||||
/* no LBN_SELCHANGE in this case, update manually */
|
/* no LBN_SELCHANGE in this case, update manually */
|
||||||
if( lphc->wState & CBF_EDIT )
|
CBPaintText( lphc, NULL );
|
||||||
CBUpdateEdit( lphc, (INT)wParam );
|
|
||||||
else
|
|
||||||
InvalidateRect(lphc->self, &lphc->textRect, TRUE);
|
|
||||||
lphc->wState &= ~CBF_SELCHANGE;
|
lphc->wState &= ~CBF_SELCHANGE;
|
||||||
return lParam;
|
return lParam;
|
||||||
case CB_GETLBTEXT:
|
case CB_GETLBTEXT:
|
||||||
|
|
Loading…
Reference in a new issue