Edit control: Fix text placement and test cases

Michael Kaufmann hallo at michael-kaufmann.ch
Wed Aug 24 16:56:39 CDT 2005


The text placement tests by Lauri Tulmin in dlls/user/tests/edit.c 
created edit controls without a parent window and without the WS_POPUP 
style. I've discovered that when a window is created with style and 
extended style set to zero, it gets the WS_CAPTION, WS_CLIPSIBLINGS and 
WS_EX_WINDOWEDGE styles (on Windows and WINE).
But because WS_CAPTION == WS_BORDER | WS_DLGFRAME, the edit control 
thinks that it has a border. And so the tests don't work as expected. 
Windows doesn't paint the border, WINE does. But it doesn't really 
matter, nobody uses edit controls this way.

I've created new tests that put the edit control in a parent window or 
that set the WS_POPUP style. I've also fixed the wrong text placement 
code, it's simpler now.

Changelog:
  - Fix text placement
  - Paint the border correctly if it's size is bigger than 1 pixel
  - Don't paint text over the border
  - Fix the edit control placement tests: Put the edit box in a parent 
window
  - Tidied up the edit control tests

-------------- next part --------------
Index: dlls/user/edit.c
===================================================================
RCS file: /home/wine/wine/dlls/user/edit.c,v
retrieving revision 1.36
diff -u -r1.36 edit.c
--- dlls/user/edit.c	10 Aug 2005 10:59:19 -0000	1.36
+++ dlls/user/edit.c	24 Aug 2005 21:25:08 -0000
@@ -2294,28 +2294,33 @@
 static void EDIT_SetRectNP(EDITSTATE *es, LPRECT rc)
 {
 	LONG_PTR ExStyle;
-
-	CopyRect(&es->format_rect, rc);
+	INT bw, bh;
 	ExStyle = GetWindowLongPtrW(es->hwndSelf, GWL_EXSTYLE);
-	if ((es->style & WS_POPUP) && !(ExStyle & WS_EX_CLIENTEDGE)) {
-		if (es->style & WS_BORDER) {
-			INT bw = GetSystemMetrics(SM_CXBORDER) + 1;
-			es->format_rect.left += bw;
-			es->format_rect.right -= bw;
-			if (es->line_height + 2 * bw <=
-		    	es->format_rect.bottom - es->format_rect.top) {
-				es->format_rect.top += bw;
-				es->format_rect.bottom -= bw;
-			}
-		}
-	} else {
-		if (es->line_height + 2 <=
-			es->format_rect.bottom - es->format_rect.top) {
+	
+	CopyRect(&es->format_rect, rc);
+	
+	if (ExStyle & WS_EX_CLIENTEDGE) {
+		es->format_rect.left++;
+		es->format_rect.right--;
+		
+		if (es->format_rect.bottom - es->format_rect.top
+		    >= es->line_height + 2)
+		{
 			es->format_rect.top++;
 			es->format_rect.bottom--;
 		}
-		es->format_rect.left++;
-		es->format_rect.right--;
+	}
+	else if (es->style & WS_BORDER) {
+		bw = GetSystemMetrics(SM_CXBORDER) + 1;
+		bh = GetSystemMetrics(SM_CYBORDER) + 1;
+		es->format_rect.left += bw;
+		es->format_rect.right -= bw;
+		if (es->format_rect.bottom - es->format_rect.top
+		  >= es->line_height + 2 * bh)
+		{
+		    es->format_rect.top += bh;
+		    es->format_rect.bottom -= bh;
+		}
 	}
 	
 	es->format_rect.left += es->left_margin;
@@ -4712,6 +4717,7 @@
 	RECT rcRgn;
 	HBRUSH brush;
 	HBRUSH old_brush;
+	INT bw, bh;
 	BOOL rev = es->bEnableState &&
 				((es->flags & EF_FOCUSED) ||
 					(es->style & ES_NOHIDESEL));
@@ -4725,20 +4731,32 @@
 
 	/* paint the border and the background */
 	IntersectClipRect(dc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
+	
 	if(es->style & WS_BORDER) {
+		bw = GetSystemMetrics(SM_CXBORDER);
+		bh = GetSystemMetrics(SM_CYBORDER);
 		rc = rcClient;
 		if(es->style & ES_MULTILINE) {
-			if(es->style & WS_HSCROLL) rc.bottom++;
-			if(es->style & WS_VSCROLL) rc.right++;
+			if(es->style & WS_HSCROLL) rc.bottom+=bh;
+			if(es->style & WS_VSCROLL) rc.right+=bw;
 		}
-		old_brush = SelectObject(dc, brush);
-		Rectangle(dc, rc.left, rc.top, rc.right, rc.bottom);
+		
+		/* Draw the frame. Same code as in nonclient.c */
+		old_brush = SelectObject(dc, GetSysColorBrush(COLOR_WINDOWFRAME));
+		PatBlt(dc, rc.left, rc.top, rc.right - rc.left, bh, PATCOPY);
+		PatBlt(dc, rc.left, rc.top, bw, rc.bottom - rc.top, PATCOPY);
+		PatBlt(dc, rc.left, rc.bottom - 1, rc.right - rc.left, -bw, PATCOPY);
+		PatBlt(dc, rc.right - 1, rc.top, -bw, rc.bottom - rc.top, PATCOPY);
 		SelectObject(dc, old_brush);
+		
+		/* Keep the border clean */
+		IntersectClipRect(dc, rc.left+bw, rc.top+bh,
+		    max(rc.right-bw, rc.left+bw), max(rc.bottom-bh, rc.top+bh));
 	}
-	else {
-		GetClipBox(dc, &rc);
-		FillRect(dc, &rc, brush);
-	}
+	
+	GetClipBox(dc, &rc);
+	FillRect(dc, &rc, brush);
+
 	IntersectClipRect(dc, es->format_rect.left,
 				es->format_rect.top,
 				es->format_rect.right,
Index: dlls/user/tests/edit.c
===================================================================
RCS file: /home/wine/wine/dlls/user/tests/edit.c,v
retrieving revision 1.11
diff -u -r1.11 edit.c
--- dlls/user/tests/edit.c	5 Jul 2005 14:04:25 -0000	1.11
+++ dlls/user/tests/edit.c	24 Aug 2005 21:25:09 -0000
@@ -38,9 +38,11 @@
 
 static struct edit_notify notifications;
 
-static char szEditTest2Name[] = "Edit Test 2 window class";
 static HINSTANCE hinst;
 static HWND hwndET2;
+static char szEditTest2Class[] = "EditTest2Class";
+static char szEditTest3Class[] = "EditTest3Class";
+static char szEditTextPositionClass[] = "EditTextPositionWindowClass";
 
 static HWND create_editcontrol (DWORD style, DWORD exstyle)
 {
@@ -48,16 +50,59 @@
 
     handle = CreateWindowEx(exstyle,
 			  "EDIT",
-			  NULL,
+			  "Test Text",
 			  ES_AUTOHSCROLL | ES_AUTOVSCROLL | style,
 			  10, 10, 300, 300,
-			  NULL, NULL, NULL, NULL);
+			  NULL, NULL, hinst, NULL);
     assert (handle);
     if (winetest_interactive)
 	ShowWindow (handle, SW_SHOW);
     return handle;
 }
 
+static HWND create_child_editcontrol (DWORD style, DWORD exstyle)
+{
+    HWND parentWnd;
+    HWND editWnd;
+    RECT rect;
+    
+    rect.left = 0;
+    rect.top = 0;
+    rect.right = 300;
+    rect.bottom = 300;
+    assert(AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE));
+    
+    parentWnd = CreateWindowEx(0,
+                            szEditTextPositionClass,
+                            "Edit Test",
+                            WS_OVERLAPPEDWINDOW,
+                            CW_USEDEFAULT, CW_USEDEFAULT,
+                            rect.right - rect.left, rect.bottom - rect.top,
+                            NULL, NULL, hinst, NULL);
+    assert(parentWnd);
+
+    editWnd = CreateWindowEx(exstyle,
+                            "EDIT",
+                            "Test Text",
+                            WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | style,
+                            0, 0, 300, 300,
+                            parentWnd, NULL, hinst, NULL);
+    assert(editWnd);
+    if (winetest_interactive)
+        ShowWindow (parentWnd, SW_SHOW);
+    return editWnd;
+}
+
+static void destroy_child_editcontrol (HWND hwndEdit)
+{
+    if (GetParent(hwndEdit))
+        DestroyWindow(GetParent(hwndEdit));
+    else {
+        trace("Edit control has no parent!\n");
+        DestroyWindow(hwndEdit);
+    }
+}
+
 static LONG get_edit_style (HWND hwnd)
 {
     return GetWindowLongA( hwnd, GWL_STYLE ) & (
@@ -87,30 +132,29 @@
 
     GetWindowRect(Wnd, &WindowRect);
     GetClientRect(Wnd, &ClientRect);
-    SetWindowPos(Wnd, NULL, WindowRect.left, WindowRect.top,
+    SetWindowPos(Wnd, NULL, 0, 0,
                  WindowRect.right - WindowRect.left,
-                 Height + (WindowRect.bottom - WindowRect.top) - (ClientRect.bottom - ClientRect.top),
-                 SWP_NOMOVE | SWP_NOZORDER);
-}
-
-#define edit_pos_ok(exp, got, txt) \
-    ok(exp == got, "wrong " #txt " expected %d got %ld\n", exp, got);
-
-#define edit_todo_pos_ok(exp, got, txt, todo) \
-    if (todo) todo_wine { edit_pos_ok(exp, got, txt); } \
-    else edit_pos_ok(exp, got, txt)
+                 Height + (WindowRect.bottom - WindowRect.top) -
+                 (ClientRect.bottom - ClientRect.top),
+                 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
+
+    /* Workaround for a bug in Windows' edit control
+       (multi-line mode) */
+    GetWindowRect(Wnd, &WindowRect);             
+    SetWindowPos(Wnd, NULL, 0, 0,
+                 WindowRect.right - WindowRect.left + 1,
+                 WindowRect.bottom - WindowRect.top + 1,
+                 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
+    SetWindowPos(Wnd, NULL, 0, 0,
+                 WindowRect.right - WindowRect.left,
+                 WindowRect.bottom - WindowRect.top,
+                 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
 
-#define check_pos(hwEdit, set_height, test_top, test_height, test_left, todo_top, todo_height, todo_left) \
-do { \
-    RECT format_rect; \
-    int left_margin; \
-    set_client_height(hwEdit, set_height); \
-    SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
-    left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \
-    edit_todo_pos_ok(test_top, format_rect.top, vertical position, todo_top); \
-    edit_todo_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height, todo_height); \
-    edit_todo_pos_ok(test_left, format_rect.left - left_margin, left, todo_left); \
-} while(0)
+    GetClientRect(Wnd, &ClientRect);
+    ok(ClientRect.bottom - ClientRect.top == Height,
+        "The client height should be %ld, but is %ld\n",
+        (long)Height, (long)(ClientRect.bottom - ClientRect.top));
+}
 
 static void test_edit_control_1(void)
 {
@@ -118,9 +162,6 @@
     MSG msMessage;
     int i;
     LONG r;
-    HFONT Font, OldFont;
-    HDC Dc;
-    TEXTMETRIC Metrics;
 
     msMessage.message = WM_KEYDOWN;
 
@@ -175,260 +216,6 @@
 	    "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %lx\n", r);
     }
     DestroyWindow (hwEdit);
-
-    /* Get a stock font for which we can determine the metrics */
-    Font = GetStockObject(SYSTEM_FONT);
-    assert(NULL != Font);
-    Dc = GetDC(NULL);
-    assert(NULL != Dc);
-    OldFont = SelectObject(Dc, Font);
-    assert(NULL != OldFont);
-    if (! GetTextMetrics(Dc, &Metrics))
-    {
-	assert(FALSE);
-    }
-    SelectObject(Dc, OldFont);
-    ReleaseDC(NULL, Dc);
-
-    trace("EDIT: Text position\n");
-    hwEdit = create_editcontrol(0, 0);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_BORDER, 0);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 1, 1, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 1, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 1, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(0, WS_EX_CLIENTEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_BORDER, WS_EX_CLIENTEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(0, WS_EX_WINDOWEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_BORDER, WS_EX_WINDOWEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 1, 1, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 1, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 1, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(0, WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_BORDER, WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_POPUP, 0);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 0, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 0, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 0, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 0, Metrics.tmHeight    , 0, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 0, Metrics.tmHeight    , 0, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, 0);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 2, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 2, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 0, Metrics.tmHeight    , 2, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  3, 0, Metrics.tmHeight    , 2, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 2, Metrics.tmHeight    , 2, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 2, Metrics.tmHeight    , 2, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_POPUP, WS_EX_CLIENTEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_POPUP, WS_EX_WINDOWEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 0, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 0, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 0, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 0, Metrics.tmHeight    , 0, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 0, Metrics.tmHeight    , 0, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 0, Metrics.tmHeight    , 0, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, WS_EX_WINDOWEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 2, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 2, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 0, Metrics.tmHeight    , 2, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  3, 0, Metrics.tmHeight    , 2, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 2, Metrics.tmHeight    , 2, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 2, Metrics.tmHeight    , 2, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_POPUP, WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(0, ES_MULTILINE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_BORDER, ES_MULTILINE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 1, 1, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 1, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 1, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(0, ES_MULTILINE | WS_EX_CLIENTEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_BORDER, ES_MULTILINE | WS_EX_CLIENTEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(0, ES_MULTILINE | WS_EX_WINDOWEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_BORDER, ES_MULTILINE | WS_EX_WINDOWEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 1, 1, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 1, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 1, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(0, ES_MULTILINE | WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
-
-    hwEdit = create_editcontrol(WS_BORDER, ES_MULTILINE | WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
-    SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
-    check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
-    DestroyWindow(hwEdit);
 }
 
 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
@@ -443,7 +230,7 @@
     char szLocalString[MAXLEN];
 
     /* Create main and edit windows. */
-    hwndMain = CreateWindow(szEditTest2Name, "ET2", WS_OVERLAPPEDWINDOW,
+    hwndMain = CreateWindow(szEditTest2Class, "ET2", WS_OVERLAPPEDWINDOW,
                             0, 0, 200, 200, NULL, NULL, hinst, NULL);
     assert(hwndMain);
     if (winetest_interactive)
@@ -496,24 +283,6 @@
     return DefWindowProc(hwnd, iMsg, wParam, lParam);
 }
 
-static BOOL RegisterWindowClasses (void)
-{
-    WNDCLASSA cls;
-    cls.style = 0;
-    cls.lpfnWndProc = ET2_WndProc;
-    cls.cbClsExtra = 0;
-    cls.cbWndExtra = 0;
-    cls.hInstance = hinst;
-    cls.hIcon = NULL;
-    cls.hCursor = LoadCursorA (NULL, IDC_ARROW);
-    cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
-    cls.lpszMenuName = NULL;
-    cls.lpszClassName = szEditTest2Name;
-    if (!RegisterClassA (&cls)) return FALSE;
-
-    return TRUE;
-}
-
 static void zero_notify(void)
 {
     notifications.en_change = 0;
@@ -555,7 +324,6 @@
  */
 static void test_edit_control_3(void)
 {
-    WNDCLASSA cls;
     HWND hWnd;
     HWND hParent;
     int len;
@@ -564,21 +332,8 @@
 
     trace("EDIT: Test notifications\n");
 
-    cls.style = 0;
-    cls.lpfnWndProc = edit3_wnd_procA;
-    cls.cbClsExtra = 0;
-    cls.cbWndExtra = 0;
-    cls.hInstance = GetModuleHandleA(0);
-    cls.hIcon = 0;
-    cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
-    cls.hbrBackground = GetStockObject(WHITE_BRUSH);
-    cls.lpszMenuName = NULL;
-    cls.lpszClassName = "ParentWindowClass";
-
-    assert(RegisterClassA(&cls));
-
     hParent = CreateWindowExA(0,
-              "ParentWindowClass",
+              szEditTest3Class,
               NULL,
               0,
               CW_USEDEFAULT, CW_USEDEFAULT, 10, 10,
@@ -974,15 +729,210 @@
     DestroyWindow (hwEdit);
 }
 
+#define edit_pos_ok(exp, got, txt) \
+    ok(exp == got, "wrong " #txt " expected %d got %ld\n", exp, got);
+
+#define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
+do { \
+    RECT format_rect; \
+    int left_margin; \
+    set_client_height(hwEdit, set_height); \
+    SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
+    left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \
+    edit_pos_ok(test_top, format_rect.top, vertical position); \
+    edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
+    edit_pos_ok(test_left, format_rect.left - left_margin, left); \
+} while(0)
+
+void test_text_position_style(DWORD style)
+{
+    HWND hwEdit;
+    HFONT font, oldFont;
+    HDC dc;
+    TEXTMETRIC metrics;
+    INT b, bm, b2, b3;
+    BOOL single_line = !(style & ES_MULTILINE);
+
+    b = GetSystemMetrics(SM_CYBORDER) + 1;
+    b2 = 2 * b;
+    b3 = 3 * b;
+    bm = b2 - 1;
+    
+    /* Get a stock font for which we can determine the metrics */
+    assert(font = GetStockObject(SYSTEM_FONT));
+    assert(dc = GetDC(NULL));
+    oldFont = SelectObject(dc, font);
+    assert(GetTextMetrics(dc, &metrics));    
+    SelectObject(dc, oldFont);
+    ReleaseDC(NULL, dc);
+    
+    /* Windows' edit control has some bugs in multi-line mode:
+     * - Sometimes the format rectangle doesn't get updated
+     *   (see workaround in set_client_height())
+     * - If the height of the control is smaller than the height of a text
+     *   line, the format rectangle is still as high as a text line
+     *   (higher than the client rectangle) and the caret is not shown
+     */
+    
+    /* Edit controls that are in a parent window */
+       
+    hwEdit = create_child_editcontrol(style, 0);
+    SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
+    if (single_line)
+    check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 0);
+    check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 0);
+    check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 0);
+    check_pos(hwEdit, metrics.tmHeight +  2, 0, metrics.tmHeight    , 0);
+    check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight    , 0);
+    destroy_child_editcontrol(hwEdit);
+
+    hwEdit = create_child_editcontrol(style | WS_BORDER, 0);
+    SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
+    if (single_line)
+    check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, b);
+    check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , b);
+    check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , b);
+    check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight    , b);
+    check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight    , b);
+    check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight    , b);
+    destroy_child_editcontrol(hwEdit);
+
+    hwEdit = create_child_editcontrol(style, WS_EX_CLIENTEDGE);
+    SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
+    if (single_line)
+    check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
+    check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
+    check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
+    check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
+    check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
+    destroy_child_editcontrol(hwEdit);
+
+    hwEdit = create_child_editcontrol(style | WS_BORDER, WS_EX_CLIENTEDGE);
+    SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
+    if (single_line)
+    check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
+    check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
+    check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
+    check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
+    check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
+    destroy_child_editcontrol(hwEdit);
+
+
+    /* Edit controls that are popup windows */
+    
+    hwEdit = create_editcontrol(style | WS_POPUP, 0);
+    SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
+    if (single_line)
+    check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 0);
+    check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 0);
+    check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 0);
+    check_pos(hwEdit, metrics.tmHeight +  2, 0, metrics.tmHeight    , 0);
+    check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight    , 0);
+    DestroyWindow(hwEdit);
+
+    hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, 0);
+    SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
+    if (single_line)
+    check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, b);
+    check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , b);
+    check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , b);
+    check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight    , b);
+    check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight    , b);
+    check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight    , b);
+    DestroyWindow(hwEdit);
+
+    hwEdit = create_editcontrol(style | WS_POPUP, WS_EX_CLIENTEDGE);
+    SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
+    if (single_line)
+    check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
+    check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
+    check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
+    check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
+    check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
+    DestroyWindow(hwEdit);
+
+    hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE);
+    SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
+    if (single_line)
+    check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
+    check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
+    check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
+    check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
+    check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
+    DestroyWindow(hwEdit);
+}
+
+void test_text_position(void)
+{
+    trace("EDIT: Text position (Single line)\n");
+    test_text_position_style(0);
+    trace("EDIT: Text position (Multi line)\n");
+    test_text_position_style(ES_MULTILINE);
+}
+
+static BOOL RegisterWindowClasses (void)
+{
+    WNDCLASSA test2;
+    WNDCLASSA test3;
+    WNDCLASSA text_position;
+    
+    test2.style = 0;
+    test2.lpfnWndProc = ET2_WndProc;
+    test2.cbClsExtra = 0;
+    test2.cbWndExtra = 0;
+    test2.hInstance = hinst;
+    test2.hIcon = NULL;
+    test2.hCursor = LoadCursorA (NULL, IDC_ARROW);
+    test2.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+    test2.lpszMenuName = NULL;
+    test2.lpszClassName = szEditTest2Class;
+    if (!RegisterClassA(&test2)) return FALSE;
+
+    test3.style = 0;
+    test3.lpfnWndProc = edit3_wnd_procA;
+    test3.cbClsExtra = 0;
+    test3.cbWndExtra = 0;
+    test3.hInstance = hinst;
+    test3.hIcon = 0;
+    test3.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
+    test3.hbrBackground = GetStockObject(WHITE_BRUSH);
+    test3.lpszMenuName = NULL;
+    test3.lpszClassName = szEditTest3Class;
+    if (!RegisterClassA(&test3)) return FALSE;
+
+    text_position.style = CS_HREDRAW | CS_VREDRAW;
+    text_position.cbClsExtra = 0;
+    text_position.cbWndExtra = 0;
+    text_position.hInstance = hinst;
+    text_position.hIcon = NULL;
+    text_position.hCursor = LoadCursorA(NULL, MAKEINTRESOURCEA(IDC_ARROW));
+    text_position.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
+    text_position.lpszMenuName = NULL;
+    text_position.lpszClassName = szEditTextPositionClass;
+    text_position.lpfnWndProc = DefWindowProc;
+    if (!RegisterClassA(&text_position)) return FALSE;
+
+    return TRUE;
+}
+
+static void UnregisterWindowClasses (void)
+{
+    UnregisterClassA(szEditTest2Class, hinst);
+    UnregisterClassA(szEditTest3Class, hinst);
+    UnregisterClassA(szEditTextPositionClass, hinst);
+}
+
 START_TEST(edit)
 {
-    hinst = GetModuleHandleA (NULL);
-    if (!RegisterWindowClasses())
-        assert(0);
+    hinst = GetModuleHandleA(NULL);
+    assert(RegisterWindowClasses());
 
     test_edit_control_1();
     test_edit_control_2();
     test_edit_control_3();
     test_edit_control_4();
     test_margins();
+    test_text_position();
+    
+    UnregisterWindowClasses();
 }


More information about the wine-patches mailing list