user32: Add a test for combobox navigation with arrow keys, make it pass under Wine
Dmitry Timoshkov
dmitry at codeweavers.com
Thu Mar 27 01:35:59 CDT 2008
Hello,
this patch fixes the problem reported in the bug 12070.
Changelog:
user32: Add a test for combobox navigation with arrow keys,
make it pass under Wine.
---
dlls/user32/combo.c | 29 +++++------
dlls/user32/listbox.c | 2 +-
dlls/user32/tests/msg.c | 127 ++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 133 insertions(+), 25 deletions(-)
diff --git a/dlls/user32/combo.c b/dlls/user32/combo.c
index 549600e..14eebe8 100644
--- a/dlls/user32/combo.c
+++ b/dlls/user32/combo.c
@@ -884,16 +884,9 @@ static HBRUSH COMBO_PrepareColors(
}
else
{
- if (lphc->wState & CBF_EDIT)
- {
+ /* FIXME: In which cases WM_CTLCOLORLISTBOX should be sent? */
hBkgBrush = (HBRUSH)SendMessageW(lphc->owner, WM_CTLCOLOREDIT,
(WPARAM)hDC, (LPARAM)lphc->self );
- }
- else
- {
- hBkgBrush = (HBRUSH)SendMessageW(lphc->owner, WM_CTLCOLORLISTBOX,
- (WPARAM)hDC, (LPARAM)lphc->self );
- }
}
/*
@@ -1350,6 +1343,14 @@ static LRESULT COMBO_Command( LPHEADCOMBO lphc, WPARAM wParam, HWND hWnd )
TRACE("[%p]: lbox selection change [%x]\n", lphc->self, lphc->wState );
+ /* do not roll up if selection is being tracked
+ * by arrowkeys in the dropdown listbox */
+ if (!(lphc->wState & CBF_NOROLLUP))
+ {
+ CBRollUp( lphc, (HIWORD(wParam) == LBN_SELCHANGE), TRUE );
+ }
+ else lphc->wState &= ~CBF_NOROLLUP;
+
CB_NOTIFY( lphc, CBN_SELCHANGE );
if( HIWORD(wParam) == LBN_SELCHANGE)
@@ -1363,17 +1364,11 @@ static LRESULT COMBO_Command( LPHEADCOMBO lphc, WPARAM wParam, HWND hWnd )
SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1));
}
else
+ {
InvalidateRect(lphc->self, &lphc->textRect, TRUE);
+ UpdateWindow(lphc->self);
+ }
}
-
- /* do not roll up if selection is being tracked
- * by arrowkeys in the dropdown listbox */
- if( ((lphc->wState & CBF_DROPPED) && !(lphc->wState & CBF_NOROLLUP)) )
- {
- CBRollUp( lphc, (HIWORD(wParam) == LBN_SELCHANGE), TRUE );
- }
- else lphc->wState &= ~CBF_NOROLLUP;
-
break;
case LBN_SETFOCUS:
diff --git a/dlls/user32/listbox.c b/dlls/user32/listbox.c
index 7232644..0b318fa 100644
--- a/dlls/user32/listbox.c
+++ b/dlls/user32/listbox.c
@@ -2442,7 +2442,7 @@ static LRESULT LISTBOX_HandleKeyDown( LB_DESCR *descr, DWORD key )
LISTBOX_SetSelection( descr, caret, TRUE, FALSE);
if (descr->style & LBS_NOTIFY)
{
- if( descr->lphc )
+ if (descr->lphc && IsWindowVisible( descr->self ))
{
/* make sure that combo parent doesn't hide us */
descr->lphc->wState |= CBF_NOROLLUP;
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index b8d9375..ca166d8 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -43,6 +43,10 @@
#define SW_NORMALNA 0xCC /* undoc. flag in MinMaximize */
+#ifndef WM_KEYF1
+#define WM_KEYF1 0x004d
+#endif
+
#ifndef WM_SYSTIMER
#define WM_SYSTIMER 0x0118
#endif
@@ -2740,7 +2744,6 @@ static LRESULT WINAPI mdi_client_hook_proc(HWND hwnd, UINT message, WPARAM wPara
message != WM_NCPAINT &&
message != WM_SYNCPAINT &&
message != WM_ERASEBKGND &&
- message != WM_NCPAINT &&
message != WM_NCHITTEST &&
message != WM_GETTEXT &&
message != WM_MDIGETACTIVE &&
@@ -2793,7 +2796,6 @@ static LRESULT WINAPI mdi_child_wnd_proc(HWND hwnd, UINT message, WPARAM wParam,
message != WM_NCPAINT &&
message != WM_SYNCPAINT &&
message != WM_ERASEBKGND &&
- message != WM_NCPAINT &&
message != WM_NCHITTEST &&
message != WM_GETTEXT &&
message != WM_GETICON &&
@@ -2863,7 +2865,6 @@ static LRESULT WINAPI mdi_frame_wnd_proc(HWND hwnd, UINT message, WPARAM wParam,
message != WM_NCPAINT &&
message != WM_SYNCPAINT &&
message != WM_ERASEBKGND &&
- message != WM_NCPAINT &&
message != WM_NCHITTEST &&
message != WM_GETTEXT &&
message != WM_GETICON &&
@@ -4855,7 +4856,6 @@ static LRESULT CALLBACK static_hook_proc(HWND hwnd, UINT message, WPARAM wParam,
msg.lParam = lParam;
add_message(&msg);
-
defwndproc_counter++;
ret = CallWindowProcA(old_static_proc, hwnd, message, wParam, lParam);
defwndproc_counter--;
@@ -4918,6 +4918,111 @@ static void test_static_messages(void)
}
}
+/****************** ComboBox message test *************************/
+#define ID_COMBOBOX 0x000f
+
+static const struct message WmKeyDownComboSeq[] =
+{
+ { WM_KEYDOWN, sent|wparam|lparam, VK_DOWN, 0 },
+ { WM_COMMAND, sent|wparam, MAKEWPARAM(1000, LBN_SELCHANGE) },
+ { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_COMBOBOX, CBN_SELENDOK) },
+ { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_COMBOBOX, CBN_SELCHANGE) },
+ { WM_CTLCOLOREDIT, sent|parent },
+ { WM_KEYUP, sent|wparam|lparam, VK_DOWN, 0 },
+ { 0 }
+};
+
+static WNDPROC old_combobox_proc;
+
+static LRESULT CALLBACK combobox_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static long defwndproc_counter = 0;
+ LRESULT ret;
+ struct message msg;
+
+ /* do not log painting messages */
+ if (message != WM_PAINT &&
+ message != WM_NCPAINT &&
+ message != WM_SYNCPAINT &&
+ message != WM_ERASEBKGND &&
+ message != WM_NCHITTEST &&
+ message != WM_GETTEXT &&
+ message != WM_GETICON &&
+ message != WM_DEVICECHANGE)
+ {
+ trace("combo: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
+
+ msg.message = message;
+ msg.flags = sent|wparam|lparam;
+ msg.wParam = wParam;
+ msg.lParam = lParam;
+ add_message(&msg);
+ }
+
+ defwndproc_counter++;
+ ret = CallWindowProcA(old_combobox_proc, hwnd, message, wParam, lParam);
+ defwndproc_counter--;
+
+ return ret;
+}
+
+static void subclass_combobox(void)
+{
+ WNDCLASSA cls;
+
+ if (!GetClassInfoA(0, "ComboBox", &cls)) assert(0);
+
+ old_combobox_proc = cls.lpfnWndProc;
+
+ cls.hInstance = GetModuleHandle(0);
+ cls.lpfnWndProc = combobox_hook_proc;
+ cls.lpszClassName = "my_combobox_class";
+ UnregisterClass(cls.lpszClassName, cls.hInstance);
+ if (!RegisterClassA(&cls)) assert(0);
+}
+
+static void test_combobox_messages(void)
+{
+ HWND parent, combo;
+ LRESULT ret;
+
+ subclass_combobox();
+
+ parent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+ ok(parent != 0, "Failed to create parent window\n");
+ flush_sequence();
+
+ combo = CreateWindowEx(0, "my_combobox_class", "test", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
+ 0, 0, 100, 150, parent, (HMENU)ID_COMBOBOX, 0, NULL);
+ ok(combo != 0, "Failed to create combobox window\n");
+
+ UpdateWindow(combo);
+
+ ret = SendMessage(combo, WM_GETDLGCODE, 0, 0);
+ ok(ret == (DLGC_WANTCHARS | DLGC_WANTARROWS), "wrong dlg_code %08lx\n", ret);
+
+ ret = SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)"item 0");
+ ok(ret == 0, "expected 0, got %ld\n", ret);
+ ret = SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)"item 1");
+ ok(ret == 1, "expected 1, got %ld\n", ret);
+ ret = SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)"item 2");
+ ok(ret == 2, "expected 2, got %ld\n", ret);
+
+ SendMessage(combo, CB_SETCURSEL, 0, 0);
+ SetFocus(combo);
+ flush_sequence();
+
+ log_all_parent_messages++;
+ SendMessage(combo, WM_KEYDOWN, VK_DOWN, 0);
+ SendMessage(combo, WM_KEYUP, VK_DOWN, 0);
+ log_all_parent_messages--;
+ ok_sequence(WmKeyDownComboSeq, "WM_KEYDOWN/VK_DOWN on a ComboBox", FALSE);
+
+ DestroyWindow(combo);
+ DestroyWindow(parent);
+}
+
/************* painting message test ********************/
void dump_region(HRGN hrgn)
@@ -10038,6 +10143,8 @@ static LRESULT (WINAPI *listbox_orig_proc)(HWND, UINT, WPARAM, LPARAM);
static LRESULT WINAPI listbox_hook_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
{
+ static long defwndproc_counter = 0;
+ LRESULT ret;
struct message msg;
/* do not log painting messages */
@@ -10059,7 +10166,11 @@ static LRESULT WINAPI listbox_hook_proc(HWND hwnd, UINT message, WPARAM wp, LPAR
add_message(&msg);
}
- return CallWindowProcA(listbox_orig_proc, hwnd, message, wp, lp);
+ defwndproc_counter++;
+ ret = CallWindowProcA(listbox_orig_proc, hwnd, message, wp, lp);
+ defwndproc_counter--;
+
+ return ret;
}
static void check_lb_state_dbg(HWND listbox, int count, int cur_sel,
@@ -10078,7 +10189,7 @@ static void check_lb_state_dbg(HWND listbox, int count, int cur_sel,
ok_(__FILE__, line)(ret == top_index, "expected top index %d, got %ld\n", top_index, ret);
}
-static void test_listbox(void)
+static void test_listbox_messages(void)
{
HWND parent, listbox;
LRESULT ret;
@@ -10135,6 +10246,7 @@ static void test_listbox(void)
log_all_parent_messages--;
+ DestroyWindow(listbox);
DestroyWindow(parent);
}
@@ -10192,6 +10304,8 @@ START_TEST(msg)
test_mdi_messages();
test_button_messages();
test_static_messages();
+ test_listbox_messages();
+ test_combobox_messages();
test_paint_messages();
test_interthread_messages();
test_message_conversion();
@@ -10216,7 +10330,6 @@ START_TEST(msg)
test_nullCallback();
test_SetForegroundWindow();
test_dbcs_wm_char();
- test_listbox();
UnhookWindowsHookEx(hCBT_hook);
if (pUnhookWinEvent)
--
1.5.4.3
More information about the wine-patches
mailing list