Don't open device if already open.
[wine] / dlls / user / tests / edit.c
1 /* Unit test suite for edit control.
2  *
3  * Copyright 2004 Vitaliy Margolen
4  * Copyright 2005 C. Scott Ananian
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <assert.h>
22 #include <windows.h>
23 #include <windowsx.h>
24 #include <commctrl.h>
25
26 #include "wine/test.h"
27
28 #ifndef ES_COMBO
29 #define ES_COMBO 0x200
30 #endif
31
32 #define ID_EDITTEST2 99
33 #define MAXLEN 200
34
35 struct edit_notify {
36     int en_change, en_maxtext, en_update;
37 };
38
39 static struct edit_notify notifications;
40
41 static char szEditTest2Name[] = "Edit Test 2 window class";
42 static HINSTANCE hinst;
43 static HWND hwndET2;
44
45 HWND create_editcontrol (DWORD style, DWORD exstyle)
46 {
47     HWND handle;
48
49     handle = CreateWindowEx(exstyle,
50                           "EDIT",
51                           NULL,
52                           ES_AUTOHSCROLL | ES_AUTOVSCROLL | style,
53                           10, 10, 300, 300,
54                           NULL, NULL, NULL, NULL);
55     assert (handle);
56     if (winetest_interactive)
57         ShowWindow (handle, SW_SHOW);
58     return handle;
59 }
60
61 static LONG get_edit_style (HWND hwnd)
62 {
63     return GetWindowLongA( hwnd, GWL_STYLE ) & (
64         ES_LEFT |
65 /* FIXME: not implemented
66         ES_CENTER |
67         ES_RIGHT |
68         ES_OEMCONVERT |
69 */
70         ES_MULTILINE |
71         ES_UPPERCASE |
72         ES_LOWERCASE |
73         ES_PASSWORD |
74         ES_AUTOVSCROLL |
75         ES_AUTOHSCROLL |
76         ES_NOHIDESEL |
77         ES_COMBO |
78         ES_READONLY |
79         ES_WANTRETURN |
80         ES_NUMBER
81         );
82 }
83
84 static void set_client_height(HWND Wnd, unsigned Height)
85 {
86     RECT ClientRect, WindowRect;
87
88     GetWindowRect(Wnd, &WindowRect);
89     GetClientRect(Wnd, &ClientRect);
90     SetWindowPos(Wnd, NULL, WindowRect.left, WindowRect.top,
91                  WindowRect.right - WindowRect.left,
92                  Height + (WindowRect.bottom - WindowRect.top) - (ClientRect.bottom - ClientRect.top),
93                  SWP_NOMOVE | SWP_NOZORDER);
94 }
95
96 static void test_edit_control_1(void)
97 {
98     HWND hwEdit;
99     MSG msMessage;
100     int i;
101     LONG r;
102     HFONT Font, OldFont;
103     HDC Dc;
104     TEXTMETRIC Metrics;
105     RECT FormatRect;
106
107     msMessage.message = WM_KEYDOWN;
108
109     trace("EDIT: Single line\n");
110     hwEdit = create_editcontrol(0, 0);
111     r = get_edit_style(hwEdit);
112     ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL), "Wrong style expected 0xc0 got: 0x%lx\n", r); 
113     for (i=0;i<65535;i++)
114     {
115         msMessage.wParam = i;
116         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
117         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
118             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %lx\n", r);
119     }
120     DestroyWindow (hwEdit);
121
122     trace("EDIT: Single line want returns\n");
123     hwEdit = create_editcontrol(ES_WANTRETURN, 0);
124     r = get_edit_style(hwEdit);
125     ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN), "Wrong style expected 0x10c0 got: 0x%lx\n", r); 
126     for (i=0;i<65535;i++)
127     {
128         msMessage.wParam = i;
129         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
130         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
131             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %lx\n", r);
132     }
133     DestroyWindow (hwEdit);
134
135     trace("EDIT: Multiline line\n");
136     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL, 0);
137     r = get_edit_style(hwEdit);
138     ok(r == (ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0xc4 got: 0x%lx\n", r); 
139     for (i=0;i<65535;i++)
140     {
141         msMessage.wParam = i;
142         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
143         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
144             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %lx\n", r);
145     }
146     DestroyWindow (hwEdit);
147
148     trace("EDIT: Multi line want returns\n");
149     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL | ES_WANTRETURN, 0);
150     r = get_edit_style(hwEdit);
151     ok(r == (ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0x10c4 got: 0x%lx\n", r); 
152     for (i=0;i<65535;i++)
153     {
154         msMessage.wParam = i;
155         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
156         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
157             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %lx\n", r);
158     }
159     DestroyWindow (hwEdit);
160
161     /* Get a stock font for which we can determine the metrics */
162     Font = GetStockObject(SYSTEM_FONT);
163     assert(NULL != Font);
164     Dc = GetDC(NULL);
165     assert(NULL != Dc);
166     OldFont = SelectObject(Dc, Font);
167     assert(NULL != OldFont);
168     if (! GetTextMetrics(Dc, &Metrics))
169     {
170         assert(FALSE);
171     }
172     SelectObject(Dc, OldFont);
173     ReleaseDC(NULL, Dc);
174
175     trace("EDIT: vertical text position\n");
176     hwEdit = create_editcontrol(WS_POPUP, 0);
177     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
178     set_client_height(hwEdit, Metrics.tmHeight - 1);
179     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
180     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
181     ok(Metrics.tmHeight - 1 == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight - 1, FormatRect.bottom - FormatRect.top);
182     set_client_height(hwEdit, Metrics.tmHeight);
183     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
184     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
185     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
186     set_client_height(hwEdit, Metrics.tmHeight + 1);
187     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
188     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
189     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
190     set_client_height(hwEdit, Metrics.tmHeight + 2);
191     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
192     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
193     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
194     set_client_height(hwEdit, Metrics.tmHeight + 10);
195     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
196     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
197     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
198     DestroyWindow(hwEdit);
199
200     hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, 0);
201     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
202     set_client_height(hwEdit, Metrics.tmHeight - 1);
203     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
204     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
205     ok(Metrics.tmHeight - 1 == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight - 1, FormatRect.bottom - FormatRect.top);
206     set_client_height(hwEdit, Metrics.tmHeight);
207     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
208     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
209     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
210     set_client_height(hwEdit, Metrics.tmHeight + 2);
211     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
212     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
213     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
214     set_client_height(hwEdit, Metrics.tmHeight + 3);
215     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
216     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
217     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
218     set_client_height(hwEdit, Metrics.tmHeight + 4);
219     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
220     ok(2 == FormatRect.top, "wrong vertical position expected 2 got %ld\n", FormatRect.top);
221     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
222     set_client_height(hwEdit, Metrics.tmHeight + 10);
223     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
224     ok(2 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
225     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
226     DestroyWindow(hwEdit);
227
228     hwEdit = create_editcontrol(WS_POPUP, WS_EX_CLIENTEDGE);
229     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
230     set_client_height(hwEdit, Metrics.tmHeight - 1);
231     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
232     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
233     ok(Metrics.tmHeight - 1 == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight - 1, FormatRect.bottom - FormatRect.top);
234     set_client_height(hwEdit, Metrics.tmHeight);
235     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
236     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
237     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
238     set_client_height(hwEdit, Metrics.tmHeight + 1);
239     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
240     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
241     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
242     set_client_height(hwEdit, Metrics.tmHeight + 2);
243     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
244     ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top);
245     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
246     set_client_height(hwEdit, Metrics.tmHeight + 4);
247     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
248     ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top);
249     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
250     set_client_height(hwEdit, Metrics.tmHeight + 10);
251     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
252     ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top);
253     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
254     DestroyWindow(hwEdit);
255
256     hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE);
257     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
258     set_client_height(hwEdit, Metrics.tmHeight - 1);
259     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
260     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
261     ok(Metrics.tmHeight - 1 == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight - 1, FormatRect.bottom - FormatRect.top);
262     set_client_height(hwEdit, Metrics.tmHeight);
263     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
264     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
265     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
266     set_client_height(hwEdit, Metrics.tmHeight + 1);
267     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
268     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
269     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
270     set_client_height(hwEdit, Metrics.tmHeight + 2);
271     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
272     ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top);
273     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
274     set_client_height(hwEdit, Metrics.tmHeight + 4);
275     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
276     ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top);
277     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
278     set_client_height(hwEdit, Metrics.tmHeight + 10);
279     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
280     ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top);
281     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
282     DestroyWindow(hwEdit);
283 }
284
285 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
286  * selection.  This test checks that the first 'select all' doesn't generate
287  * an UPDATE message which can escape and (via a handler) change the
288  * selection, which would cause WM_SETTEXT to break.  This old bug
289  * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
290  */
291 static void test_edit_control_2(void)
292 {
293     HWND hwndMain;
294     char szLocalString[MAXLEN];
295
296     /* Create main and edit windows. */
297     hwndMain = CreateWindow(szEditTest2Name, "ET2", WS_OVERLAPPEDWINDOW,
298                             0, 0, 200, 200, NULL, NULL, hinst, NULL);
299     assert(hwndMain);
300     if (winetest_interactive)
301         ShowWindow (hwndMain, SW_SHOW);
302
303     hwndET2 = CreateWindow("EDIT", NULL,
304                            WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,
305                            0, 0, 150, 50, /* important this not be 0 size. */
306                            hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL);
307     assert(hwndET2);
308     if (winetest_interactive)
309         ShowWindow (hwndET2, SW_SHOW);
310
311     trace("EDIT: SETTEXT atomicity\n");
312     /* Send messages to "type" in the word 'foo'. */
313     SendMessage(hwndET2, WM_CHAR, 'f', 1);
314     SendMessage(hwndET2, WM_CHAR, 'o', 1);
315     SendMessage(hwndET2, WM_CHAR, 'o', 1);
316     /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
317     GetWindowText(hwndET2, szLocalString, MAXLEN);
318     ok(lstrcmp(szLocalString, "bar")==0,
319        "Wrong contents of edit: %s\n", szLocalString);
320
321     /* OK, done! */
322     DestroyWindow (hwndET2);
323     DestroyWindow (hwndMain);
324 }
325
326 static void ET2_check_change() {
327    char szLocalString[MAXLEN];
328    /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
329    GetWindowText(hwndET2, szLocalString, MAXLEN);
330    if (lstrcmp(szLocalString, "foo")==0) {
331        lstrcpy(szLocalString, "bar");
332        SendMessage(hwndET2, WM_SETTEXT, 0, (LPARAM) szLocalString);
333    }
334    /* always leave the cursor at the end. */
335    SendMessage(hwndET2, EM_SETSEL, MAXLEN - 1, MAXLEN - 1);
336 }
337 static void ET2_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
338 {
339     if (id==ID_EDITTEST2 && codeNotify == EN_UPDATE)
340         ET2_check_change();
341 }
342 static LRESULT CALLBACK ET2_WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
343 {
344     switch (iMsg) {
345         HANDLE_MSG(hwnd, WM_COMMAND, ET2_OnCommand);
346     }
347     return DefWindowProc(hwnd, iMsg, wParam, lParam);
348 }
349
350 static BOOL RegisterWindowClasses (void)
351 {
352     WNDCLASSA cls;
353     cls.style = 0;
354     cls.lpfnWndProc = ET2_WndProc;
355     cls.cbClsExtra = 0;
356     cls.cbWndExtra = 0;
357     cls.hInstance = hinst;
358     cls.hIcon = NULL;
359     cls.hCursor = LoadCursorA (NULL, IDC_ARROW);
360     cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
361     cls.lpszMenuName = NULL;
362     cls.lpszClassName = szEditTest2Name;
363     if (!RegisterClassA (&cls)) return FALSE;
364
365     return TRUE;
366 }
367
368 static void zero_notify(void)
369 {
370     notifications.en_change = 0;
371     notifications.en_maxtext = 0;
372     notifications.en_update = 0;
373 }
374
375 #define test_notify(enchange, enmaxtext, enupdate) \
376     ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
377     "got %d\n", enchange, notifications.en_change); \
378     ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
379     "got %d\n", enmaxtext, notifications.en_maxtext); \
380     ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
381     "got %d\n", enupdate, notifications.en_update)
382
383
384 static LRESULT CALLBACK edit3_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
385 {
386     switch (msg) {
387         case WM_COMMAND:
388             switch (HIWORD(wParam)) {
389                 case EN_MAXTEXT:
390                     notifications.en_maxtext++;
391                     break;
392                 case EN_UPDATE:
393                     notifications.en_update++;
394                     break;
395                 case EN_CHANGE:
396                     notifications.en_change++;
397                     break;
398             }
399             break;
400     }
401     return DefWindowProcA(hWnd, msg, wParam, lParam);
402 }
403
404
405 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notificatisons sent in response
406  * to these messages.
407  */
408 static void test_edit_control_3(void)
409 {
410     WNDCLASSA cls;
411     HWND hWnd;
412     HWND hParent;
413     int len;
414     static const char *str = "this is a long string.";
415     static const char *str2 = "this is a long string.\r\nthis is a long string.\r\nthis is a long string.\r\nthis is a long string.";
416
417     trace("EDIT: Test notifications\n");
418
419     cls.style = 0;
420     cls.lpfnWndProc = edit3_wnd_procA;
421     cls.cbClsExtra = 0;
422     cls.cbWndExtra = 0;
423     cls.hInstance = GetModuleHandleA(0);
424     cls.hIcon = 0;
425     cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
426     cls.hbrBackground = GetStockObject(WHITE_BRUSH);
427     cls.lpszMenuName = NULL;
428     cls.lpszClassName = "ParentWindowClass";
429
430     assert(RegisterClassA(&cls));
431
432     hParent = CreateWindowExA(0,
433               "ParentWindowClass",
434               NULL,
435               0,
436               CW_USEDEFAULT, CW_USEDEFAULT, 10, 10,
437               NULL, NULL, NULL, NULL);
438     assert(hParent);
439
440     trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
441     hWnd = CreateWindowExA(0,
442               "EDIT",
443               NULL,
444               0,
445               10, 10, 50, 50,
446               hParent, NULL, NULL, NULL);
447     assert(hWnd);
448
449     zero_notify();
450     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
451     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
452     ok(lstrlenA(str) > len, "text should have been truncated\n");
453     test_notify(1, 1, 1);
454
455     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
456     zero_notify();
457     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
458     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
459     ok(1 == len, "wrong text length, expected 1, got %d\n", len);
460     test_notify(1, 0, 1);
461
462     zero_notify();
463     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
464     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
465     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
466     test_notify(1, 0, 1);
467
468     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
469
470     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
471     zero_notify();
472     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
473     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
474     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
475     test_notify(1, 1, 1);
476
477     zero_notify();
478     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
479     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
480     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
481     test_notify(1, 0, 1);
482
483     DestroyWindow(hWnd);
484
485     trace("EDIT: Single line, ES_AUTOHSCROLL\n");
486     hWnd = CreateWindowExA(0,
487               "EDIT",
488               NULL,
489               ES_AUTOHSCROLL,
490               10, 10, 50, 50,
491               hParent, NULL, NULL, NULL);
492     assert(hWnd);
493
494     zero_notify();
495     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
496     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
497     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
498     test_notify(1, 0, 1);
499
500     zero_notify();
501     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
502     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
503     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
504     test_notify(1, 0, 1);
505
506     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
507
508     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
509     zero_notify();
510     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
511     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
512     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
513     test_notify(1, 1, 1);
514
515     zero_notify();
516     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
517     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
518     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
519     test_notify(1, 0, 1);
520
521     DestroyWindow(hWnd);
522
523     trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
524     hWnd = CreateWindowExA(0,
525               "EDIT",
526               NULL,
527               ES_MULTILINE,
528               10, 10, 50, 50,
529               hParent, NULL, NULL, NULL);
530     assert(hWnd);
531
532     zero_notify();
533     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
534     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
535     ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
536     test_notify(1, 1, 1);
537
538     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
539     zero_notify();
540     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
541     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
542     ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
543     test_notify(1, 0, 1);
544
545     zero_notify();
546     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
547     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
548     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
549     test_notify(0, 0, 0);
550
551     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
552
553     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
554     zero_notify();
555     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
556     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
557     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
558     test_notify(1, 1, 1);
559
560     zero_notify();
561     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
562     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
563     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
564     test_notify(0, 0, 0);
565
566     DestroyWindow(hWnd);
567
568     trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
569     hWnd = CreateWindowExA(0,
570               "EDIT",
571               NULL,
572               ES_MULTILINE | ES_AUTOHSCROLL,
573               10, 10, 50, 50,
574               hParent, NULL, NULL, NULL);
575     assert(hWnd);
576
577     zero_notify();
578     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
579     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
580     ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
581     test_notify(1, 1, 1);
582
583     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
584     zero_notify();
585     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
586     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
587     ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
588     test_notify(1, 0, 1);
589
590     zero_notify();
591     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
592     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
593     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
594     test_notify(0, 0, 0);
595
596     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
597
598     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
599     zero_notify();
600     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
601     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
602     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
603     test_notify(1, 1, 1);
604
605     zero_notify();
606     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
607     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
608     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
609     test_notify(0, 0, 0);
610
611     DestroyWindow(hWnd);
612
613     trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
614     hWnd = CreateWindowExA(0,
615               "EDIT",
616               NULL,
617               ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
618               10, 10, 50, 50,
619               hParent, NULL, NULL, NULL);
620     assert(hWnd);
621
622     zero_notify();
623     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
624     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
625     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
626     test_notify(1, 0, 1);
627
628     zero_notify();
629     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
630     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
631     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
632     test_notify(0, 0, 0);
633
634     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
635
636     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
637     zero_notify();
638     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
639     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
640     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
641     test_notify(1, 1, 1);
642
643     zero_notify();
644     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
645     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
646     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
647     test_notify(0, 0, 0);
648
649     DestroyWindow(hWnd);
650 }
651
652 START_TEST(edit)
653 {
654     hinst = GetModuleHandleA (NULL);
655     if (!RegisterWindowClasses())
656         assert(0);
657
658     test_edit_control_1();
659     test_edit_control_2();
660     test_edit_control_3();
661 }