Add a test for some edit control behaviours, make it pass under Wine
Dmitry Timoshkov
dmitry at baikal.ru
Tue Nov 15 23:57:44 CST 2005
Hello,
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
Add a test for some edit control behaviours, make it pass under Wine.
diff -up cvs/hq/wine/dlls/user/edit.c wine/dlls/user/edit.c
--- cvs/hq/wine/dlls/user/edit.c 2005-11-10 11:28:36.000000000 +0800
+++ wine/dlls/user/edit.c 2005-11-16 13:48:02.000000000 +0800
@@ -389,6 +389,7 @@ static DWORD get_app_version(void)
static HBRUSH EDIT_NotifyCtlColor(EDITSTATE *es, HDC hdc)
{
+ HBRUSH hbrush;
UINT msg;
if ( get_app_version() >= 0x40000 && (!es->bEnableState || (es->style & ES_READONLY)))
@@ -397,7 +398,10 @@ static HBRUSH EDIT_NotifyCtlColor(EDITST
msg = WM_CTLCOLOREDIT;
/* why do we notify to es->hwndParent, and we send this one to GetParent()? */
- return (HBRUSH)SendMessageW(GetParent(es->hwndSelf), msg, (WPARAM)hdc, (LPARAM)es->hwndSelf);
+ hbrush = (HBRUSH)SendMessageW(GetParent(es->hwndSelf), msg, (WPARAM)hdc, (LPARAM)es->hwndSelf);
+ if (!hbrush)
+ hbrush = (HBRUSH)DefWindowProcW(GetParent(es->hwndSelf), msg, (WPARAM)hdc, (LPARAM)es->hwndSelf);
+ return hbrush;
}
static inline LRESULT DefWindowProcT(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode)
@@ -4132,7 +4136,7 @@ static LRESULT EDIT_WM_Destroy(EDITSTATE
static LRESULT EDIT_WM_EraseBkGnd(EDITSTATE *es, HDC dc)
{
/* we do the proper erase in EDIT_WM_Paint */
- return -1;
+ return 1;
}
@@ -4500,8 +4504,8 @@ static LRESULT EDIT_WM_LButtonDblClk(EDI
INT li;
INT ll;
- if (!(es->flags & EF_FOCUSED))
- return 0;
+ es->bCaptureState = TRUE;
+ SetCapture(es->hwndSelf);
l = EDIT_EM_LineFromChar(es, e);
li = EDIT_EM_LineIndex(es, l);
@@ -4510,6 +4514,8 @@ static LRESULT EDIT_WM_LButtonDblClk(EDI
e = li + EDIT_CallWordBreakProc(es, li, e - li, ll, WB_RIGHT);
EDIT_EM_SetSel(es, s, e, FALSE);
EDIT_EM_ScrollCaret(es);
+ es->region_posx = es->region_posy = 0;
+ SetTimer(es->hwndSelf, 0, 100, NULL);
return 0;
}
@@ -4524,10 +4530,6 @@ static LRESULT EDIT_WM_LButtonDown(EDITS
INT e;
BOOL after_wrap;
- SetFocus(es->hwndSelf);
- if (!(es->flags & EF_FOCUSED))
- return 0;
-
es->bCaptureState = TRUE;
SetCapture(es->hwndSelf);
EDIT_ConfinePoint(es, &x, &y);
@@ -4536,6 +4538,10 @@ static LRESULT EDIT_WM_LButtonDown(EDITS
EDIT_EM_ScrollCaret(es);
es->region_posx = es->region_posy = 0;
SetTimer(es->hwndSelf, 0, 100, NULL);
+
+ if (!(es->flags & EF_FOCUSED))
+ SetFocus(es->hwndSelf);
+
return 0;
}
@@ -4728,8 +4734,7 @@ static void EDIT_WM_Paint(EDITSTATE *es,
GetClientRect(es->hwndSelf, &rcClient);
/* get the background brush */
- if (!(brush = EDIT_NotifyCtlColor(es, dc)))
- brush = (HBRUSH)GetStockObject(WHITE_BRUSH);
+ brush = EDIT_NotifyCtlColor(es, dc);
/* paint the border and the background */
IntersectClipRect(dc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
@@ -4769,7 +4774,6 @@ static void EDIT_WM_Paint(EDITSTATE *es,
}
if (es->font)
old_font = SelectObject(dc, es->font);
- EDIT_NotifyCtlColor(es, dc);
if (!es->bEnableState)
SetTextColor(dc, GetSysColor(COLOR_GRAYTEXT));
@@ -4826,11 +4830,21 @@ static void EDIT_WM_Paste(EDITSTATE *es)
static void EDIT_WM_SetFocus(EDITSTATE *es)
{
es->flags |= EF_FOCUSED;
+
+ if (!(es->style & ES_NOHIDESEL))
+ EDIT_InvalidateText(es, es->selection_start, es->selection_end);
+
+ /* single line edit updates itself */
+ if (!(es->style & ES_MULTILINE))
+ {
+ HDC hdc = GetDC(es->hwndSelf);
+ EDIT_WM_Paint(es, hdc);
+ ReleaseDC(es->hwndSelf, hdc);
+ }
+
CreateCaret(es->hwndSelf, 0, 2, es->line_height);
EDIT_SetCaretPos(es, es->selection_end,
es->flags & EF_AFTER_WRAP);
- if(!(es->style & ES_NOHIDESEL))
- EDIT_InvalidateText(es, es->selection_start, es->selection_end);
ShowCaret(es->hwndSelf);
EDIT_NOTIFY_PARENT(es, EN_SETFOCUS);
}
diff -up cvs/hq/wine/dlls/user/tests/msg.c wine/dlls/user/tests/msg.c
--- cvs/hq/wine/dlls/user/tests/msg.c 2005-11-15 14:07:00.000000000 +0800
+++ wine/dlls/user/tests/msg.c 2005-11-16 13:40:49.000000000 +0800
@@ -5066,6 +5066,7 @@ static LRESULT CALLBACK cbt_hook_proc(in
!lstrcmpiA(buf, "MDI_client_class") ||
!lstrcmpiA(buf, "MDI_child_class") ||
!lstrcmpiA(buf, "my_button_class") ||
+ !lstrcmpiA(buf, "my_edit_class") ||
!lstrcmpiA(buf, "static") ||
!lstrcmpiA(buf, "#32770"))
{
@@ -5111,6 +5112,7 @@ static void CALLBACK win_event_proc(HWIN
!lstrcmpiA(buf, "MDI_client_class") ||
!lstrcmpiA(buf, "MDI_child_class") ||
!lstrcmpiA(buf, "my_button_class") ||
+ !lstrcmpiA(buf, "my_edit_class") ||
!lstrcmpiA(buf, "static") ||
!lstrcmpiA(buf, "#32770"))
{
@@ -6221,6 +6223,233 @@ static void test_SendMessageTimeout(void
}
+/****************** edit message test *************************/
+#define ID_EDIT 0x1234
+static const struct message sl_edit_setfocus[] =
+{
+ { HCBT_SETFOCUS, hook },
+ { WM_IME_SETCONTEXT, sent|wparam|optional, 1 },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_SETFOCUS, sent|wparam, 0 },
+ { WM_CTLCOLOREDIT, sent|parent },
+ { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_EDIT, EN_SETFOCUS) },
+ { 0 }
+};
+static const struct message ml_edit_setfocus[] =
+{
+ { HCBT_SETFOCUS, hook },
+ { WM_IME_SETCONTEXT, sent|wparam|optional, 1 },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_SETFOCUS, sent|wparam, 0 },
+ { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_EDIT, EN_SETFOCUS) },
+ { 0 }
+};
+static const struct message sl_edit_killfocus[] =
+{
+ { HCBT_SETFOCUS, hook },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_KILLFOCUS, sent|wparam, 0 },
+ { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_EDIT, EN_KILLFOCUS) },
+ { WM_IME_SETCONTEXT, sent|wparam|optional, 0 },
+ { 0 }
+};
+static const struct message sl_edit_lbutton_dblclk[] =
+{
+ { WM_LBUTTONDBLCLK, sent },
+ { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
+ { 0 }
+};
+static const struct message sl_edit_lbutton_down[] =
+{
+ { WM_LBUTTONDOWN, sent|wparam|lparam, 0, 0 },
+ { HCBT_SETFOCUS, hook },
+ { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
+ { WM_CTLCOLOREDIT, sent|parent },
+ { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_EDIT, EN_SETFOCUS) },
+ { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
+ { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { 0 }
+};
+static const struct message ml_edit_lbutton_down[] =
+{
+ { WM_LBUTTONDOWN, sent|wparam|lparam, 0, 0 },
+ { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
+ { HCBT_SETFOCUS, hook },
+ { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
+ { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_EDIT, EN_SETFOCUS) },
+ { 0 }
+};
+static const struct message sl_edit_lbutton_up[] =
+{
+ { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
+ { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_CAPTURECHANGED, sent|defwinproc },
+ { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
+ { 0 }
+};
+static const struct message ml_edit_lbutton_up[] =
+{
+ { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
+ { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_CAPTURECHANGED, sent|defwinproc },
+ { 0 }
+};
+
+static WNDPROC old_edit_proc;
+
+static LRESULT CALLBACK edit_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static long defwndproc_counter = 0;
+ LRESULT ret;
+ struct message msg;
+
+ trace("edit: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
+
+ /* explicitly ignore WM_GETICON message */
+ if (message == WM_GETICON) return 0;
+
+ msg.message = message;
+ msg.flags = sent|wparam|lparam;
+ if (defwndproc_counter) msg.flags |= defwinproc;
+ msg.wParam = wParam;
+ msg.lParam = lParam;
+ add_message(&msg);
+
+ defwndproc_counter++;
+ ret = CallWindowProcA(old_edit_proc, hwnd, message, wParam, lParam);
+ defwndproc_counter--;
+
+ return ret;
+}
+
+static void subclass_edit(void)
+{
+ WNDCLASSA cls;
+
+ if (!GetClassInfoA(0, "edit", &cls)) assert(0);
+
+ old_edit_proc = cls.lpfnWndProc;
+
+ cls.hInstance = GetModuleHandle(0);
+ cls.lpfnWndProc = edit_hook_proc;
+ cls.lpszClassName = "my_edit_class";
+ if (!RegisterClassA(&cls)) assert(0);
+}
+
+static void test_edit_messages(void)
+{
+ HWND hwnd, parent;
+ DWORD dlg_code;
+
+ subclass_edit();
+ log_all_parent_messages++;
+
+ 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");
+
+ /* test single line edit */
+ hwnd = CreateWindowExA(0, "my_edit_class", "test", WS_CHILD,
+ 0, 0, 80, 20, parent, (HMENU)ID_EDIT, 0, NULL);
+ ok(hwnd != 0, "Failed to create edit window\n");
+
+ dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0);
+ ok(dlg_code == (DLGC_WANTCHARS|DLGC_HASSETSEL|DLGC_WANTARROWS), "wrong dlg_code %08lx\n", dlg_code);
+
+ ShowWindow(hwnd, SW_SHOW);
+ UpdateWindow(hwnd);
+ SetFocus(0);
+ flush_sequence();
+
+ SetFocus(hwnd);
+ ok_sequence(sl_edit_setfocus, "SetFocus(hwnd) on an edit", FALSE);
+
+ SetFocus(0);
+ ok_sequence(sl_edit_killfocus, "SetFocus(0) on an edit", FALSE);
+
+ SetFocus(0);
+ ReleaseCapture();
+ flush_sequence();
+
+ SendMessageA(hwnd, WM_LBUTTONDBLCLK, 0, 0);
+ ok_sequence(sl_edit_lbutton_dblclk, "WM_LBUTTONDBLCLK on an edit", FALSE);
+
+ SetFocus(0);
+ ReleaseCapture();
+ flush_sequence();
+
+ SendMessageA(hwnd, WM_LBUTTONDOWN, 0, 0);
+ ok_sequence(sl_edit_lbutton_down, "WM_LBUTTONDOWN on an edit", FALSE);
+
+ SendMessageA(hwnd, WM_LBUTTONUP, 0, 0);
+ ok_sequence(sl_edit_lbutton_up, "WM_LBUTTONUP on an edit", FALSE);
+
+ DestroyWindow(hwnd);
+
+ /* test multiline edit */
+ hwnd = CreateWindowExA(0, "my_edit_class", "test", WS_CHILD | ES_MULTILINE,
+ 0, 0, 80, 20, parent, (HMENU)ID_EDIT, 0, NULL);
+ ok(hwnd != 0, "Failed to create edit window\n");
+
+ dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0);
+ ok(dlg_code == (DLGC_WANTCHARS|DLGC_HASSETSEL|DLGC_WANTARROWS|DLGC_WANTALLKEYS),
+ "wrong dlg_code %08lx\n", dlg_code);
+
+ ShowWindow(hwnd, SW_SHOW);
+ UpdateWindow(hwnd);
+ SetFocus(0);
+ flush_sequence();
+
+ SetFocus(hwnd);
+ ok_sequence(ml_edit_setfocus, "SetFocus(hwnd) on multiline edit", FALSE);
+
+ SetFocus(0);
+ ok_sequence(sl_edit_killfocus, "SetFocus(0) on multiline edit", FALSE);
+
+ SetFocus(0);
+ ReleaseCapture();
+ flush_sequence();
+
+ SendMessageA(hwnd, WM_LBUTTONDBLCLK, 0, 0);
+ ok_sequence(sl_edit_lbutton_dblclk, "WM_LBUTTONDBLCLK on multiline edit", FALSE);
+
+ SetFocus(0);
+ ReleaseCapture();
+ flush_sequence();
+
+ SendMessageA(hwnd, WM_LBUTTONDOWN, 0, 0);
+ ok_sequence(ml_edit_lbutton_down, "WM_LBUTTONDOWN on multiline edit", FALSE);
+
+ SendMessageA(hwnd, WM_LBUTTONUP, 0, 0);
+ ok_sequence(ml_edit_lbutton_up, "WM_LBUTTONUP on multiline edit", FALSE);
+
+ DestroyWindow(hwnd);
+ DestroyWindow(parent);
+
+ log_all_parent_messages--;
+}
+
+/**************************** End of Edit test ******************************/
+
START_TEST(msg)
{
BOOL ret;
@@ -6277,6 +6506,7 @@ START_TEST(msg)
test_DestroyWindow();
test_DispatchMessage();
test_SendMessageTimeout();
+ test_edit_messages();
UnhookWindowsHookEx(hCBT_hook);
if (pUnhookWinEvent)
More information about the wine-patches
mailing list