Added more pipe tests.
[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 static char szEditTest2Name[] = "Edit Test 2 window class";
36 static HINSTANCE hinst;
37 static HWND hwndET2;
38
39 HWND create_editcontrol (DWORD style, DWORD exstyle)
40 {
41     HWND handle;
42
43     handle = CreateWindowEx(exstyle,
44                           "EDIT",
45                           NULL,
46                           ES_AUTOHSCROLL | ES_AUTOVSCROLL | style,
47                           10, 10, 300, 300,
48                           NULL, NULL, NULL, NULL);
49     assert (handle);
50     if (winetest_interactive)
51         ShowWindow (handle, SW_SHOW);
52     return handle;
53 }
54
55 static LONG get_edit_style (HWND hwnd)
56 {
57     return GetWindowLongA( hwnd, GWL_STYLE ) & (
58         ES_LEFT |
59 /* FIXME: not implemented
60         ES_CENTER |
61         ES_RIGHT |
62         ES_OEMCONVERT |
63 */
64         ES_MULTILINE |
65         ES_UPPERCASE |
66         ES_LOWERCASE |
67         ES_PASSWORD |
68         ES_AUTOVSCROLL |
69         ES_AUTOHSCROLL |
70         ES_NOHIDESEL |
71         ES_COMBO |
72         ES_READONLY |
73         ES_WANTRETURN |
74         ES_NUMBER
75         );
76 }
77
78 static void set_client_height(HWND Wnd, unsigned Height)
79 {
80     RECT ClientRect, WindowRect;
81
82     GetWindowRect(Wnd, &WindowRect);
83     GetClientRect(Wnd, &ClientRect);
84     SetWindowPos(Wnd, NULL, WindowRect.left, WindowRect.top,
85                  WindowRect.right - WindowRect.left,
86                  Height + (WindowRect.bottom - WindowRect.top) - (ClientRect.bottom - ClientRect.top),
87                  SWP_NOMOVE | SWP_NOZORDER);
88 }
89
90 static void test_edit_control_1(void)
91 {
92     HWND hwEdit;
93     MSG msMessage;
94     int i;
95     LONG r;
96     HFONT Font, OldFont;
97     HDC Dc;
98     TEXTMETRIC Metrics;
99     RECT FormatRect;
100
101     msMessage.message = WM_KEYDOWN;
102
103     trace("EDIT: Single line\n");
104     hwEdit = create_editcontrol(0, 0);
105     r = get_edit_style(hwEdit);
106     ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL), "Wrong style expected 0xc0 got: 0x%lx\n", r); 
107     for (i=0;i<65535;i++)
108     {
109         msMessage.wParam = i;
110         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
111         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
112             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %lx\n", r);
113     }
114     DestroyWindow (hwEdit);
115
116     trace("EDIT: Single line want returns\n");
117     hwEdit = create_editcontrol(ES_WANTRETURN, 0);
118     r = get_edit_style(hwEdit);
119     ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN), "Wrong style expected 0x10c0 got: 0x%lx\n", r); 
120     for (i=0;i<65535;i++)
121     {
122         msMessage.wParam = i;
123         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
124         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
125             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %lx\n", r);
126     }
127     DestroyWindow (hwEdit);
128
129     trace("EDIT: Multiline line\n");
130     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL, 0);
131     r = get_edit_style(hwEdit);
132     ok(r == (ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0xc4 got: 0x%lx\n", r); 
133     for (i=0;i<65535;i++)
134     {
135         msMessage.wParam = i;
136         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
137         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
138             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %lx\n", r);
139     }
140     DestroyWindow (hwEdit);
141
142     trace("EDIT: Multi line want returns\n");
143     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL | ES_WANTRETURN, 0);
144     r = get_edit_style(hwEdit);
145     ok(r == (ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0x10c4 got: 0x%lx\n", r); 
146     for (i=0;i<65535;i++)
147     {
148         msMessage.wParam = i;
149         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
150         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
151             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %lx\n", r);
152     }
153     DestroyWindow (hwEdit);
154
155     /* Get a stock font for which we can determine the metrics */
156     Font = GetStockObject(SYSTEM_FONT);
157     assert(NULL != Font);
158     Dc = GetDC(NULL);
159     assert(NULL != Dc);
160     OldFont = SelectObject(Dc, Font);
161     assert(NULL != OldFont);
162     if (! GetTextMetrics(Dc, &Metrics))
163     {
164         assert(FALSE);
165     }
166     SelectObject(Dc, OldFont);
167     ReleaseDC(NULL, Dc);
168
169     trace("EDIT: vertical text position\n");
170     hwEdit = create_editcontrol(WS_POPUP, 0);
171     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
172     set_client_height(hwEdit, Metrics.tmHeight - 1);
173     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
174     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
175     ok(Metrics.tmHeight - 1 == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight - 1, FormatRect.bottom - FormatRect.top);
176     set_client_height(hwEdit, Metrics.tmHeight);
177     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
178     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
179     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
180     set_client_height(hwEdit, Metrics.tmHeight + 1);
181     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
182     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
183     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
184     set_client_height(hwEdit, Metrics.tmHeight + 2);
185     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
186     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
187     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
188     set_client_height(hwEdit, Metrics.tmHeight + 10);
189     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
190     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
191     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
192     DestroyWindow(hwEdit);
193
194     hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, 0);
195     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
196     set_client_height(hwEdit, Metrics.tmHeight - 1);
197     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
198     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
199     ok(Metrics.tmHeight - 1 == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight - 1, FormatRect.bottom - FormatRect.top);
200     set_client_height(hwEdit, Metrics.tmHeight);
201     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
202     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
203     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
204     set_client_height(hwEdit, Metrics.tmHeight + 2);
205     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
206     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
207     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
208     set_client_height(hwEdit, Metrics.tmHeight + 3);
209     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
210     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
211     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
212     set_client_height(hwEdit, Metrics.tmHeight + 4);
213     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
214     ok(2 == FormatRect.top, "wrong vertical position expected 2 got %ld\n", FormatRect.top);
215     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
216     set_client_height(hwEdit, Metrics.tmHeight + 10);
217     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
218     ok(2 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
219     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
220     DestroyWindow(hwEdit);
221
222     hwEdit = create_editcontrol(WS_POPUP, WS_EX_CLIENTEDGE);
223     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
224     set_client_height(hwEdit, Metrics.tmHeight - 1);
225     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
226     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
227     ok(Metrics.tmHeight - 1 == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight - 1, FormatRect.bottom - FormatRect.top);
228     set_client_height(hwEdit, Metrics.tmHeight);
229     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
230     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
231     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
232     set_client_height(hwEdit, Metrics.tmHeight + 1);
233     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
234     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
235     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
236     set_client_height(hwEdit, Metrics.tmHeight + 2);
237     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
238     ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top);
239     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
240     set_client_height(hwEdit, Metrics.tmHeight + 4);
241     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
242     ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top);
243     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
244     set_client_height(hwEdit, Metrics.tmHeight + 10);
245     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
246     ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top);
247     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
248     DestroyWindow(hwEdit);
249
250     hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE);
251     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
252     set_client_height(hwEdit, Metrics.tmHeight - 1);
253     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
254     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
255     ok(Metrics.tmHeight - 1 == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight - 1, FormatRect.bottom - FormatRect.top);
256     set_client_height(hwEdit, Metrics.tmHeight);
257     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
258     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
259     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
260     set_client_height(hwEdit, Metrics.tmHeight + 1);
261     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
262     ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top);
263     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
264     set_client_height(hwEdit, Metrics.tmHeight + 2);
265     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
266     ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top);
267     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
268     set_client_height(hwEdit, Metrics.tmHeight + 4);
269     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
270     ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top);
271     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
272     set_client_height(hwEdit, Metrics.tmHeight + 10);
273     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect);
274     ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top);
275     ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top);
276     DestroyWindow(hwEdit);
277 }
278
279 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
280  * selection.  This test checks that the first 'select all' doesn't generate
281  * an UPDATE message which can escape and (via a handler) change the
282  * selection, which would cause WM_SETTEXT to break.  This old bug
283  * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
284  */
285 static void test_edit_control_2(void)
286 {
287     HWND hwndMain;
288     char szLocalString[MAXLEN];
289
290     /* Create main and edit windows. */
291     hwndMain = CreateWindow(szEditTest2Name, "ET2", WS_OVERLAPPEDWINDOW,
292                             0, 0, 200, 200, NULL, NULL, hinst, NULL);
293     assert(hwndMain);
294     if (winetest_interactive)
295         ShowWindow (hwndMain, SW_SHOW);
296
297     hwndET2 = CreateWindow("EDIT", NULL,
298                            WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,
299                            0, 0, 150, 50, /* important this not be 0 size. */
300                            hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL);
301     assert(hwndET2);
302     if (winetest_interactive)
303         ShowWindow (hwndET2, SW_SHOW);
304
305     trace("EDIT: SETTEXT atomicity\n");
306     /* Send messages to "type" in the word 'foo'. */
307     SendMessage(hwndET2, WM_CHAR, 'f', 1);
308     SendMessage(hwndET2, WM_CHAR, 'o', 1);
309     SendMessage(hwndET2, WM_CHAR, 'o', 1);
310     /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
311     GetWindowText(hwndET2, szLocalString, MAXLEN);
312     ok(lstrcmp(szLocalString, "bar")==0,
313        "Wrong contents of edit: %s\n", szLocalString);
314
315     /* OK, done! */
316     DestroyWindow (hwndET2);
317     DestroyWindow (hwndMain);
318 }
319
320 static void ET2_check_change() {
321    char szLocalString[MAXLEN];
322    /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
323    GetWindowText(hwndET2, szLocalString, MAXLEN);
324    if (lstrcmp(szLocalString, "foo")==0) {
325        lstrcpy(szLocalString, "bar");
326        SendMessage(hwndET2, WM_SETTEXT, 0, (LPARAM) szLocalString);
327    }
328    /* always leave the cursor at the end. */
329    SendMessage(hwndET2, EM_SETSEL, MAXLEN - 1, MAXLEN - 1);
330 }
331 static void ET2_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
332 {
333     if (id==ID_EDITTEST2 && codeNotify == EN_UPDATE)
334         ET2_check_change();
335 }
336 static LRESULT CALLBACK ET2_WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
337 {
338     switch (iMsg) {
339         HANDLE_MSG(hwnd, WM_COMMAND, ET2_OnCommand);
340     }
341     return DefWindowProc(hwnd, iMsg, wParam, lParam);
342 }
343
344 static BOOL RegisterWindowClasses (void)
345 {
346     WNDCLASSA cls;
347     cls.style = 0;
348     cls.lpfnWndProc = ET2_WndProc;
349     cls.cbClsExtra = 0;
350     cls.cbWndExtra = 0;
351     cls.hInstance = hinst;
352     cls.hIcon = NULL;
353     cls.hCursor = LoadCursorA (NULL, IDC_ARROW);
354     cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
355     cls.lpszMenuName = NULL;
356     cls.lpszClassName = szEditTest2Name;
357     if (!RegisterClassA (&cls)) return FALSE;
358
359     return TRUE;
360 }
361
362 START_TEST(edit)
363 {
364     hinst = GetModuleHandleA (NULL);
365     if (!RegisterWindowClasses())
366         assert(0);
367
368     test_edit_control_1();
369     test_edit_control_2();
370 }