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