Fix declarations.
[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 static 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 #define edit_pos_ok(exp, got, txt) \
97     ok(exp == got, "wrong " #txt " expected %d got %ld\n", exp, got);
98
99 #define edit_todo_pos_ok(exp, got, txt, todo) \
100     if (todo) todo_wine { edit_pos_ok(exp, got, txt); } \
101     else edit_pos_ok(exp, got, txt)
102
103 #define check_pos(hwEdit, set_height, test_top, test_height, test_left, todo_top, todo_height, todo_left) \
104 do { \
105     RECT format_rect; \
106     int left_margin; \
107     set_client_height(hwEdit, set_height); \
108     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
109     left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \
110     edit_todo_pos_ok(test_top, format_rect.top, vertical position, todo_top); \
111     edit_todo_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height, todo_height); \
112     edit_todo_pos_ok(test_left, format_rect.left - left_margin, left, todo_left); \
113 } while(0)
114
115 static void test_edit_control_1(void)
116 {
117     HWND hwEdit;
118     MSG msMessage;
119     int i;
120     LONG r;
121     HFONT Font, OldFont;
122     HDC Dc;
123     TEXTMETRIC Metrics;
124
125     msMessage.message = WM_KEYDOWN;
126
127     trace("EDIT: Single line\n");
128     hwEdit = create_editcontrol(0, 0);
129     r = get_edit_style(hwEdit);
130     ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL), "Wrong style expected 0xc0 got: 0x%lx\n", r); 
131     for (i=0;i<65535;i++)
132     {
133         msMessage.wParam = i;
134         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
135         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
136             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %lx\n", r);
137     }
138     DestroyWindow (hwEdit);
139
140     trace("EDIT: Single line want returns\n");
141     hwEdit = create_editcontrol(ES_WANTRETURN, 0);
142     r = get_edit_style(hwEdit);
143     ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN), "Wrong style expected 0x10c0 got: 0x%lx\n", r); 
144     for (i=0;i<65535;i++)
145     {
146         msMessage.wParam = i;
147         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
148         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
149             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %lx\n", r);
150     }
151     DestroyWindow (hwEdit);
152
153     trace("EDIT: Multiline line\n");
154     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL, 0);
155     r = get_edit_style(hwEdit);
156     ok(r == (ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0xc4 got: 0x%lx\n", r); 
157     for (i=0;i<65535;i++)
158     {
159         msMessage.wParam = i;
160         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
161         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
162             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %lx\n", r);
163     }
164     DestroyWindow (hwEdit);
165
166     trace("EDIT: Multi line want returns\n");
167     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL | ES_WANTRETURN, 0);
168     r = get_edit_style(hwEdit);
169     ok(r == (ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0x10c4 got: 0x%lx\n", r); 
170     for (i=0;i<65535;i++)
171     {
172         msMessage.wParam = i;
173         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
174         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
175             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %lx\n", r);
176     }
177     DestroyWindow (hwEdit);
178
179     /* Get a stock font for which we can determine the metrics */
180     Font = GetStockObject(SYSTEM_FONT);
181     assert(NULL != Font);
182     Dc = GetDC(NULL);
183     assert(NULL != Dc);
184     OldFont = SelectObject(Dc, Font);
185     assert(NULL != OldFont);
186     if (! GetTextMetrics(Dc, &Metrics))
187     {
188         assert(FALSE);
189     }
190     SelectObject(Dc, OldFont);
191     ReleaseDC(NULL, Dc);
192
193     trace("EDIT: Text position\n");
194     hwEdit = create_editcontrol(0, 0);
195     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
196     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
197     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
198     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
199     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
200     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
201     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
202     DestroyWindow(hwEdit);
203
204     hwEdit = create_editcontrol(WS_BORDER, 0);
205     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
206     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 1, 1, 0);
207     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 1, 0, 0);
208     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 1, 0, 0);
209     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
210     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
211     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
212     DestroyWindow(hwEdit);
213
214     hwEdit = create_editcontrol(0, WS_EX_CLIENTEDGE);
215     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
216     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
217     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
218     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
219     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
220     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
221     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
222     DestroyWindow(hwEdit);
223
224     hwEdit = create_editcontrol(WS_BORDER, WS_EX_CLIENTEDGE);
225     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
226     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
227     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
228     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
229     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
230     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
231     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
232     DestroyWindow(hwEdit);
233
234     hwEdit = create_editcontrol(0, WS_EX_WINDOWEDGE);
235     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
236     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
237     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
238     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
239     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
240     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
241     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
242     DestroyWindow(hwEdit);
243
244     hwEdit = create_editcontrol(WS_BORDER, WS_EX_WINDOWEDGE);
245     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
246     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 1, 1, 0);
247     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 1, 0, 0);
248     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 1, 0, 0);
249     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
250     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
251     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
252     DestroyWindow(hwEdit);
253
254     hwEdit = create_editcontrol(0, WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
255     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
256     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
257     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
258     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
259     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
260     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
261     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
262     DestroyWindow(hwEdit);
263
264     hwEdit = create_editcontrol(WS_BORDER, WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
265     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
266     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
267     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
268     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
269     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
270     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
271     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
272     DestroyWindow(hwEdit);
273
274     hwEdit = create_editcontrol(WS_POPUP, 0);
275     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
276     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 0, 0, 0, 0);
277     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 0, 0, 0, 0);
278     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 0, 0, 0, 0);
279     check_pos(hwEdit, Metrics.tmHeight +  2, 0, Metrics.tmHeight    , 0, 0, 0, 0);
280     check_pos(hwEdit, Metrics.tmHeight + 10, 0, Metrics.tmHeight    , 0, 0, 0, 0);
281     DestroyWindow(hwEdit);
282
283     hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, 0);
284     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
285     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 2, 0, 0, 0);
286     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 2, 0, 0, 0);
287     check_pos(hwEdit, Metrics.tmHeight +  2, 0, Metrics.tmHeight    , 2, 0, 0, 0);
288     check_pos(hwEdit, Metrics.tmHeight +  3, 0, Metrics.tmHeight    , 2, 0, 0, 0);
289     check_pos(hwEdit, Metrics.tmHeight +  4, 2, Metrics.tmHeight    , 2, 0, 0, 0);
290     check_pos(hwEdit, Metrics.tmHeight + 10, 2, Metrics.tmHeight    , 2, 0, 0, 0);
291     DestroyWindow(hwEdit);
292
293     hwEdit = create_editcontrol(WS_POPUP, WS_EX_CLIENTEDGE);
294     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
295     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
296     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
297     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
298     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
299     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
300     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
301     DestroyWindow(hwEdit);
302
303     hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE);
304     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
305     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
306     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
307     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
308     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
309     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
310     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
311     DestroyWindow(hwEdit);
312
313     hwEdit = create_editcontrol(WS_POPUP, WS_EX_WINDOWEDGE);
314     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
315     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 0, 0, 0, 0);
316     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 0, 0, 0, 0);
317     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 0, 0, 0, 0);
318     check_pos(hwEdit, Metrics.tmHeight +  2, 0, Metrics.tmHeight    , 0, 0, 0, 0);
319     check_pos(hwEdit, Metrics.tmHeight +  4, 0, Metrics.tmHeight    , 0, 0, 0, 0);
320     check_pos(hwEdit, Metrics.tmHeight + 10, 0, Metrics.tmHeight    , 0, 0, 0, 0);
321     DestroyWindow(hwEdit);
322
323     hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, WS_EX_WINDOWEDGE);
324     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
325     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 2, 0, 0, 0);
326     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 2, 0, 0, 0);
327     check_pos(hwEdit, Metrics.tmHeight +  2, 0, Metrics.tmHeight    , 2, 0, 0, 0);
328     check_pos(hwEdit, Metrics.tmHeight +  3, 0, Metrics.tmHeight    , 2, 0, 0, 0);
329     check_pos(hwEdit, Metrics.tmHeight +  4, 2, Metrics.tmHeight    , 2, 0, 0, 0);
330     check_pos(hwEdit, Metrics.tmHeight + 10, 2, Metrics.tmHeight    , 2, 0, 0, 0);
331     DestroyWindow(hwEdit);
332
333     hwEdit = create_editcontrol(WS_POPUP, WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
334     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
335     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
336     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
337     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
338     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
339     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
340     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
341     DestroyWindow(hwEdit);
342
343     hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
344     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
345     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
346     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
347     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
348     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
349     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
350     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
351     DestroyWindow(hwEdit);
352
353     hwEdit = create_editcontrol(0, ES_MULTILINE);
354     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
355     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
356     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
357     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
358     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
359     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
360     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
361     DestroyWindow(hwEdit);
362
363     hwEdit = create_editcontrol(WS_BORDER, ES_MULTILINE);
364     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
365     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 1, 1, 0);
366     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 1, 0, 0);
367     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 1, 0, 0);
368     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
369     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
370     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
371     DestroyWindow(hwEdit);
372
373     hwEdit = create_editcontrol(0, ES_MULTILINE | WS_EX_CLIENTEDGE);
374     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
375     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
376     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
377     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
378     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
379     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
380     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
381     DestroyWindow(hwEdit);
382
383     hwEdit = create_editcontrol(WS_BORDER, ES_MULTILINE | WS_EX_CLIENTEDGE);
384     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
385     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
386     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
387     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
388     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
389     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
390     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
391     DestroyWindow(hwEdit);
392
393     hwEdit = create_editcontrol(0, ES_MULTILINE | WS_EX_WINDOWEDGE);
394     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
395     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
396     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
397     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
398     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
399     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
400     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
401     DestroyWindow(hwEdit);
402
403     hwEdit = create_editcontrol(WS_BORDER, ES_MULTILINE | WS_EX_WINDOWEDGE);
404     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
405     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 1, 1, 0);
406     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 1, 0, 0);
407     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 1, 0, 0);
408     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
409     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
410     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
411     DestroyWindow(hwEdit);
412
413     hwEdit = create_editcontrol(0, ES_MULTILINE | WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
414     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
415     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
416     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
417     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
418     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
419     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
420     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
421     DestroyWindow(hwEdit);
422
423     hwEdit = create_editcontrol(WS_BORDER, ES_MULTILINE | WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
424     SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE);
425     check_pos(hwEdit, Metrics.tmHeight -  1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0);
426     check_pos(hwEdit, Metrics.tmHeight     , 0, Metrics.tmHeight    , 1, 0, 0, 0);
427     check_pos(hwEdit, Metrics.tmHeight +  1, 0, Metrics.tmHeight    , 1, 0, 0, 0);
428     check_pos(hwEdit, Metrics.tmHeight +  2, 1, Metrics.tmHeight    , 1, 0, 0, 0);
429     check_pos(hwEdit, Metrics.tmHeight +  4, 1, Metrics.tmHeight    , 1, 0, 0, 0);
430     check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight    , 1, 0, 0, 0);
431     DestroyWindow(hwEdit);
432 }
433
434 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
435  * selection.  This test checks that the first 'select all' doesn't generate
436  * an UPDATE message which can escape and (via a handler) change the
437  * selection, which would cause WM_SETTEXT to break.  This old bug
438  * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
439  */
440 static void test_edit_control_2(void)
441 {
442     HWND hwndMain;
443     char szLocalString[MAXLEN];
444
445     /* Create main and edit windows. */
446     hwndMain = CreateWindow(szEditTest2Name, "ET2", WS_OVERLAPPEDWINDOW,
447                             0, 0, 200, 200, NULL, NULL, hinst, NULL);
448     assert(hwndMain);
449     if (winetest_interactive)
450         ShowWindow (hwndMain, SW_SHOW);
451
452     hwndET2 = CreateWindow("EDIT", NULL,
453                            WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,
454                            0, 0, 150, 50, /* important this not be 0 size. */
455                            hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL);
456     assert(hwndET2);
457     if (winetest_interactive)
458         ShowWindow (hwndET2, SW_SHOW);
459
460     trace("EDIT: SETTEXT atomicity\n");
461     /* Send messages to "type" in the word 'foo'. */
462     SendMessage(hwndET2, WM_CHAR, 'f', 1);
463     SendMessage(hwndET2, WM_CHAR, 'o', 1);
464     SendMessage(hwndET2, WM_CHAR, 'o', 1);
465     /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
466     GetWindowText(hwndET2, szLocalString, MAXLEN);
467     ok(lstrcmp(szLocalString, "bar")==0,
468        "Wrong contents of edit: %s\n", szLocalString);
469
470     /* OK, done! */
471     DestroyWindow (hwndET2);
472     DestroyWindow (hwndMain);
473 }
474
475 static void ET2_check_change() {
476    char szLocalString[MAXLEN];
477    /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
478    GetWindowText(hwndET2, szLocalString, MAXLEN);
479    if (lstrcmp(szLocalString, "foo")==0) {
480        lstrcpy(szLocalString, "bar");
481        SendMessage(hwndET2, WM_SETTEXT, 0, (LPARAM) szLocalString);
482    }
483    /* always leave the cursor at the end. */
484    SendMessage(hwndET2, EM_SETSEL, MAXLEN - 1, MAXLEN - 1);
485 }
486 static void ET2_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
487 {
488     if (id==ID_EDITTEST2 && codeNotify == EN_UPDATE)
489         ET2_check_change();
490 }
491 static LRESULT CALLBACK ET2_WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
492 {
493     switch (iMsg) {
494         HANDLE_MSG(hwnd, WM_COMMAND, ET2_OnCommand);
495     }
496     return DefWindowProc(hwnd, iMsg, wParam, lParam);
497 }
498
499 static BOOL RegisterWindowClasses (void)
500 {
501     WNDCLASSA cls;
502     cls.style = 0;
503     cls.lpfnWndProc = ET2_WndProc;
504     cls.cbClsExtra = 0;
505     cls.cbWndExtra = 0;
506     cls.hInstance = hinst;
507     cls.hIcon = NULL;
508     cls.hCursor = LoadCursorA (NULL, IDC_ARROW);
509     cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
510     cls.lpszMenuName = NULL;
511     cls.lpszClassName = szEditTest2Name;
512     if (!RegisterClassA (&cls)) return FALSE;
513
514     return TRUE;
515 }
516
517 static void zero_notify(void)
518 {
519     notifications.en_change = 0;
520     notifications.en_maxtext = 0;
521     notifications.en_update = 0;
522 }
523
524 #define test_notify(enchange, enmaxtext, enupdate) \
525     ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
526     "got %d\n", enchange, notifications.en_change); \
527     ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
528     "got %d\n", enmaxtext, notifications.en_maxtext); \
529     ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
530     "got %d\n", enupdate, notifications.en_update)
531
532
533 static LRESULT CALLBACK edit3_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
534 {
535     switch (msg) {
536         case WM_COMMAND:
537             switch (HIWORD(wParam)) {
538                 case EN_MAXTEXT:
539                     notifications.en_maxtext++;
540                     break;
541                 case EN_UPDATE:
542                     notifications.en_update++;
543                     break;
544                 case EN_CHANGE:
545                     notifications.en_change++;
546                     break;
547             }
548             break;
549     }
550     return DefWindowProcA(hWnd, msg, wParam, lParam);
551 }
552
553 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notificatisons sent in response
554  * to these messages.
555  */
556 static void test_edit_control_3(void)
557 {
558     WNDCLASSA cls;
559     HWND hWnd;
560     HWND hParent;
561     int len;
562     static const char *str = "this is a long string.";
563     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.";
564
565     trace("EDIT: Test notifications\n");
566
567     cls.style = 0;
568     cls.lpfnWndProc = edit3_wnd_procA;
569     cls.cbClsExtra = 0;
570     cls.cbWndExtra = 0;
571     cls.hInstance = GetModuleHandleA(0);
572     cls.hIcon = 0;
573     cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
574     cls.hbrBackground = GetStockObject(WHITE_BRUSH);
575     cls.lpszMenuName = NULL;
576     cls.lpszClassName = "ParentWindowClass";
577
578     assert(RegisterClassA(&cls));
579
580     hParent = CreateWindowExA(0,
581               "ParentWindowClass",
582               NULL,
583               0,
584               CW_USEDEFAULT, CW_USEDEFAULT, 10, 10,
585               NULL, NULL, NULL, NULL);
586     assert(hParent);
587
588     trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
589     hWnd = CreateWindowExA(0,
590               "EDIT",
591               NULL,
592               0,
593               10, 10, 50, 50,
594               hParent, NULL, NULL, NULL);
595     assert(hWnd);
596
597     zero_notify();
598     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
599     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
600     ok(lstrlenA(str) > len, "text should have been truncated\n");
601     test_notify(1, 1, 1);
602
603     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
604     zero_notify();
605     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
606     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
607     ok(1 == len, "wrong text length, expected 1, got %d\n", len);
608     test_notify(1, 0, 1);
609
610     zero_notify();
611     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
612     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
613     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
614     test_notify(1, 0, 1);
615
616     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
617
618     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
619     zero_notify();
620     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
621     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
622     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
623     test_notify(1, 1, 1);
624
625     zero_notify();
626     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
627     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
628     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
629     test_notify(1, 0, 1);
630
631     DestroyWindow(hWnd);
632
633     trace("EDIT: Single line, ES_AUTOHSCROLL\n");
634     hWnd = CreateWindowExA(0,
635               "EDIT",
636               NULL,
637               ES_AUTOHSCROLL,
638               10, 10, 50, 50,
639               hParent, NULL, NULL, NULL);
640     assert(hWnd);
641
642     zero_notify();
643     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
644     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
645     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
646     test_notify(1, 0, 1);
647
648     zero_notify();
649     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
650     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
651     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
652     test_notify(1, 0, 1);
653
654     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
655
656     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
657     zero_notify();
658     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
659     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
660     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
661     test_notify(1, 1, 1);
662
663     zero_notify();
664     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
665     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
666     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
667     test_notify(1, 0, 1);
668
669     DestroyWindow(hWnd);
670
671     trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
672     hWnd = CreateWindowExA(0,
673               "EDIT",
674               NULL,
675               ES_MULTILINE,
676               10, 10, 50, 50,
677               hParent, NULL, NULL, NULL);
678     assert(hWnd);
679
680     zero_notify();
681     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
682     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
683     ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
684     test_notify(1, 1, 1);
685
686     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
687     zero_notify();
688     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
689     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
690     ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
691     test_notify(1, 0, 1);
692
693     zero_notify();
694     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
695     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
696     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
697     test_notify(0, 0, 0);
698
699     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
700
701     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
702     zero_notify();
703     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
704     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
705     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
706     test_notify(1, 1, 1);
707
708     zero_notify();
709     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
710     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
711     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
712     test_notify(0, 0, 0);
713
714     DestroyWindow(hWnd);
715
716     trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
717     hWnd = CreateWindowExA(0,
718               "EDIT",
719               NULL,
720               ES_MULTILINE | ES_AUTOHSCROLL,
721               10, 10, 50, 50,
722               hParent, NULL, NULL, NULL);
723     assert(hWnd);
724
725     zero_notify();
726     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
727     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
728     ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
729     test_notify(1, 1, 1);
730
731     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
732     zero_notify();
733     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
734     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
735     ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
736     test_notify(1, 0, 1);
737
738     zero_notify();
739     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
740     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
741     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
742     test_notify(0, 0, 0);
743
744     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
745
746     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
747     zero_notify();
748     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
749     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
750     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
751     test_notify(1, 1, 1);
752
753     zero_notify();
754     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
755     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
756     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
757     test_notify(0, 0, 0);
758
759     DestroyWindow(hWnd);
760
761     trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
762     hWnd = CreateWindowExA(0,
763               "EDIT",
764               NULL,
765               ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
766               10, 10, 50, 50,
767               hParent, NULL, NULL, NULL);
768     assert(hWnd);
769
770     zero_notify();
771     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
772     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
773     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
774     test_notify(1, 0, 1);
775
776     zero_notify();
777     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
778     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
779     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
780     test_notify(0, 0, 0);
781
782     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
783
784     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
785     zero_notify();
786     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
787     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
788     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
789     test_notify(1, 1, 1);
790
791     zero_notify();
792     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
793     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
794     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
795     test_notify(0, 0, 0);
796
797     DestroyWindow(hWnd);
798 }
799
800 /* Test EM_CHARFROMPOS and EM_POSFROMCHAR
801  */
802 static void test_edit_control_4(void)
803 {
804     HWND hwEdit;
805     int lo, hi, mid;
806     int ret;
807     int i;
808
809     trace("EDIT: Test EM_CHARFROMPOS and EM_POSFROMCHAR\n");
810     hwEdit = create_editcontrol(0, 0);
811     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
812     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
813     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
814     mid = lo + (hi - lo) / 2;
815
816     for (i = lo; i < mid; i++) {
817        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
818        ok(0 == ret, "expected 0 got %d\n", ret);
819     }
820     for (i = mid; i <= hi; i++) {
821        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
822        ok(1 == ret, "expected 1 got %d\n", ret);
823     }
824     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
825     ok(-1 == ret, "expected -1 got %d\n", ret);
826     DestroyWindow(hwEdit);
827
828     hwEdit = create_editcontrol(ES_RIGHT, 0);
829     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
830     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
831     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
832     mid = lo + (hi - lo) / 2;
833
834     for (i = lo; i < mid; i++) {
835        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
836        ok(0 == ret, "expected 0 got %d\n", ret);
837     }
838     for (i = mid; i <= hi; i++) {
839        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
840        ok(1 == ret, "expected 1 got %d\n", ret);
841     }
842     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
843     ok(-1 == ret, "expected -1 got %d\n", ret);
844     DestroyWindow(hwEdit);
845
846     hwEdit = create_editcontrol(ES_CENTER, 0);
847     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
848     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
849     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
850     mid = lo + (hi - lo) / 2;
851
852     for (i = lo; i < mid; i++) {
853        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
854        ok(0 == ret, "expected 0 got %d\n", ret);
855     }
856     for (i = mid; i <= hi; i++) {
857        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
858        ok(1 == ret, "expected 1 got %d\n", ret);
859     }
860     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
861     ok(-1 == ret, "expected -1 got %d\n", ret);
862     DestroyWindow(hwEdit);
863
864     hwEdit = create_editcontrol(ES_MULTILINE, 0);
865     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
866     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
867     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
868     mid = lo + (hi - lo) / 2;
869
870     for (i = lo; i < mid; i++) {
871        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
872        ok(0 == ret, "expected 0 got %d\n", ret);
873     }
874     for (i = mid; i <= hi; i++) {
875        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
876        ok(1 == ret, "expected 1 got %d\n", ret);
877     }
878     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
879     ok(-1 == ret, "expected -1 got %d\n", ret);
880     DestroyWindow(hwEdit);
881
882     hwEdit = create_editcontrol(ES_MULTILINE | ES_RIGHT, 0);
883     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
884     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
885     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
886     mid = lo + (hi - lo) / 2;
887
888     for (i = lo; i < mid; i++) {
889        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
890        ok(0 == ret, "expected 0 got %d\n", ret);
891     }
892     for (i = mid; i <= hi; i++) {
893        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
894        ok(1 == ret, "expected 1 got %d\n", ret);
895     }
896     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
897     ok(-1 == ret, "expected -1 got %d\n", ret);
898     DestroyWindow(hwEdit);
899
900     hwEdit = create_editcontrol(ES_MULTILINE | ES_CENTER, 0);
901     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
902     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
903     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
904     mid = lo + (hi - lo) / 2;
905
906     for (i = lo; i < mid; i++) {
907        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
908        ok(0 == ret, "expected 0 got %d\n", ret);
909     }
910     for (i = mid; i <= hi; i++) {
911        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
912        ok(1 == ret, "expected 1 got %d\n", ret);
913     }
914     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
915     ok(-1 == ret, "expected -1 got %d\n", ret);
916     DestroyWindow(hwEdit);
917 }
918
919 START_TEST(edit)
920 {
921     hinst = GetModuleHandleA (NULL);
922     if (!RegisterWindowClasses())
923         assert(0);
924
925     test_edit_control_1();
926     test_edit_control_2();
927     test_edit_control_3();
928     test_edit_control_4();
929 }