include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / user32 / tests / text.c
blobd3228eae1e0165572374d8f9052cdac1103c0aaf
1 /*
2 * DrawText tests
4 * Copyright (c) 2004 Zach Gorman
5 * Copyright 2007,2016 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <assert.h>
24 #include "wine/test.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
28 #include "winerror.h"
29 #include "winnls.h"
31 #define MODIFIED(rect) (rect.left == 10 && rect.right != 100 && rect.top == 10 && rect.bottom != 100)
32 #define EMPTY(rect) (rect.left == rect.right && rect.bottom == rect.top)
34 static void test_DrawTextCalcRect(void)
36 HWND hwnd;
37 HDC hdc;
38 HFONT hFont, hOldFont;
39 LOGFONTA lf;
40 static CHAR text[] = "Example text for testing DrawText in "
41 "MM_HIENGLISH mode";
42 static WCHAR textW[] = {'W','i','d','e',' ','c','h','a','r',' ',
43 's','t','r','i','n','g','\0'};
44 static CHAR emptystring[] = "";
45 static WCHAR emptystringW[] = { 0 };
46 static CHAR wordbreak_text[] = "line1 line2";
47 static WCHAR wordbreak_textW[] = {'l','i','n','e','1',' ','l','i','n','e','2',0};
48 static WCHAR wordbreak_text_colonW[] = {'l','i','n','e','1',' ','l','i','n','e','2',' ',':',0};
49 static WCHAR wordbreak_text_csbW[] = {'l','i','n','e','1',' ','l','i','n','e','2',' ',']',0};
50 static char tabstring[] = "one\ttwo";
51 INT textlen, textheight, heightcheck;
52 RECT rect = { 0, 0, 100, 0 }, rect2;
53 BOOL ret;
54 DRAWTEXTPARAMS dtp;
55 BOOL conform_xp = TRUE;
57 /* Initialization */
58 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
59 0, 0, 200, 200, 0, 0, 0, NULL);
60 ok(hwnd != 0, "CreateWindowExA error %lu\n", GetLastError());
61 hdc = GetDC(hwnd);
62 ok(hdc != 0, "GetDC error %lu\n", GetLastError());
63 trace("hdc %p\n", hdc);
64 textlen = lstrlenA(text);
66 /* LOGFONT initialization */
67 memset(&lf, 0, sizeof(lf));
68 lf.lfCharSet = ANSI_CHARSET;
69 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
70 lf.lfWeight = FW_DONTCARE;
71 lf.lfHeight = 0; /* mapping mode dependent */
72 lf.lfQuality = DEFAULT_QUALITY;
73 lstrcpyA(lf.lfFaceName, "Arial");
75 /* DrawText in MM_HIENGLISH with DT_CALCRECT */
76 SetMapMode(hdc, MM_HIENGLISH);
77 lf.lfHeight = 100 * 9 / 72; /* 9 point */
78 hFont = CreateFontIndirectA(&lf);
79 ok(hFont != 0, "CreateFontIndirectA error %lu\n",
80 GetLastError());
81 hOldFont = SelectObject(hdc, hFont);
83 textheight = DrawTextA(hdc, text, textlen, &rect, DT_CALCRECT |
84 DT_EXTERNALLEADING | DT_WORDBREAK | DT_NOCLIP | DT_LEFT |
85 DT_NOPREFIX);
86 ok( textheight, "DrawTextA error %lu\n", GetLastError());
88 trace("MM_HIENGLISH rect.bottom %ld\n", rect.bottom);
89 ok(rect.bottom < 0, "In MM_HIENGLISH, DrawText with "
90 "DT_CALCRECT should return a negative rectangle bottom. "
91 "(bot=%ld)\n", rect.bottom);
93 SelectObject(hdc, hOldFont);
94 ret = DeleteObject(hFont);
95 ok( ret, "DeleteObject error %lu\n", GetLastError());
98 /* DrawText in MM_TEXT with DT_CALCRECT */
99 SetMapMode(hdc, MM_TEXT);
100 lf.lfHeight = -MulDiv(9, GetDeviceCaps(hdc,
101 LOGPIXELSY), 72); /* 9 point */
102 hFont = CreateFontIndirectA(&lf);
103 ok(hFont != 0, "CreateFontIndirectA error %lu\n",
104 GetLastError());
105 hOldFont = SelectObject(hdc, hFont);
107 textheight = DrawTextA(hdc, text, textlen, &rect, DT_CALCRECT |
108 DT_EXTERNALLEADING | DT_WORDBREAK | DT_NOCLIP | DT_LEFT |
109 DT_NOPREFIX);
110 ok( textheight, "DrawTextA error %lu\n", GetLastError());
112 trace("MM_TEXT rect.bottom %ld\n", rect.bottom);
113 ok(rect.bottom > 0, "In MM_TEXT, DrawText with DT_CALCRECT "
114 "should return a positive rectangle bottom. (bot=%ld)\n",
115 rect.bottom);
117 /* empty or null text should in some cases calc an empty rectangle */
119 SetRect( &rect, 10,10, 100, 100);
120 heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT, NULL );
121 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
122 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
123 ok(textheight==0,"Got textheight from DrawTextExA\n");
125 SetRect( &rect, 10,10, 100, 100);
126 textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT);
127 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
128 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
129 if (conform_xp)
130 ok(textheight==0,"Got textheight from DrawTextA\n");
131 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
133 SetRect( &rect, 10,10, 100, 100);
134 SetLastError( 0);
135 heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT, NULL );
136 ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
137 ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
139 SetRect( &rect, 10,10, 100, 100);
140 textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT);
141 ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
142 ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
143 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
145 SetRect( &rect, 10,10, 100, 100);
146 SetLastError( 0);
147 heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
148 ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
149 if (!textheight) /* Windows NT 4 */
151 if (conform_xp)
152 win_skip("XP conformity failed, skipping XP tests. Probably winNT\n");
153 conform_xp = FALSE;
155 else
156 ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
158 SetRect( &rect, 10,10, 100, 100);
159 textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT);
160 ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
161 if (conform_xp)
162 ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
163 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
165 SetRect( &rect, 10,10, 100, 100);
166 heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
167 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
168 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
169 if (conform_xp)
170 ok(textheight==0,"Got textheight from DrawTextExA\n");
172 SetRect( &rect, 10,10, 100, 100);
173 textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT);
174 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
175 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
176 if (conform_xp)
177 ok(textheight==0,"Got textheight from DrawTextA\n");
178 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
180 /* DT_SINGLELINE tests */
182 SetRect( &rect, 10,10, 100, 100);
183 heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
184 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
185 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
186 if (conform_xp)
187 ok(textheight==0,"Got textheight from DrawTextExA\n");
189 SetRect( &rect, 10,10, 100, 100);
190 textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
191 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
192 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
193 if (conform_xp)
194 ok(textheight==0,"Got textheight from DrawTextA\n");
195 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
197 SetRect( &rect, 10,10, 100, 100);
198 SetLastError( 0);
199 heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
200 ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
201 wine_dbgstr_rect(&rect));
202 ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
204 SetRect( &rect, 10,10, 100, 100);
205 textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
206 ok(!EMPTY(rect) && MODIFIED (rect), "rectangle should be modified got %s\n",
207 wine_dbgstr_rect(&rect));
208 ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
209 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
211 SetRect( &rect, 10,10, 100, 100);
212 SetLastError( 0);
213 heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
214 ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
215 wine_dbgstr_rect(&rect));
216 if (conform_xp)
217 ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
219 SetRect( &rect, 10,10, 100, 100);
220 textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
221 ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
222 wine_dbgstr_rect(&rect));
223 if (conform_xp)
224 ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
225 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
227 SetRect( &rect, 10,10, 100, 100);
228 heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
229 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
230 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
231 if (conform_xp)
232 ok(textheight==0,"Got textheight from DrawTextExA\n");
234 SetRect( &rect, 10,10, 100, 100);
235 textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
236 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
237 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
238 if (conform_xp)
239 ok(textheight==0,"Got textheight from DrawTextA\n");
240 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
242 /* further tests with 0 count, NULL and empty strings */
243 heightcheck = textheight = DrawTextA(hdc, text, 0, &rect, 0);
244 if (conform_xp)
245 ok(textheight==0,"Got textheight from DrawTextA\n");
246 textheight = DrawTextExA(hdc, text, 0, &rect, 0, NULL );
247 if (conform_xp)
248 ok(textheight==0,"Got textheight from DrawTextExA\n");
249 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
250 heightcheck = textheight = DrawTextA(hdc, emptystring, 0, &rect, 0);
251 if (conform_xp)
252 ok(textheight==0,"Got textheight from DrawTextA\n");
253 textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, NULL );
254 if (conform_xp)
255 ok(textheight==0,"Got textheight from DrawTextExA\n");
256 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
257 heightcheck = textheight = DrawTextA(hdc, NULL, 0, &rect, 0);
258 if (conform_xp)
259 ok(textheight==0,"Got textheight from DrawTextA\n");
260 textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, NULL );
261 if (conform_xp)
262 ok(textheight==0,"Got textheight from DrawTextExA\n");
263 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
264 heightcheck = textheight = DrawTextA(hdc, emptystring, -1, &rect, 0);
265 ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
266 textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, NULL );
267 ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
268 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
269 heightcheck = textheight = DrawTextA(hdc, NULL, -1, &rect, 0);
270 if (conform_xp)
271 ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
272 textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, NULL );
273 if (conform_xp)
274 ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
275 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
276 heightcheck = textheight = DrawTextA(hdc, NULL, 10, &rect, 0);
277 ok(textheight==0,"Got textheight from DrawTextA\n");
278 textheight = DrawTextExA(hdc, NULL, 10, &rect, 0, NULL );
279 ok(textheight==0,"Got textheight from DrawTextA\n");
280 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
282 /* When offset to top is zero, return 1 */
283 SetRectEmpty(&rect);
284 textheight = DrawTextExW(hdc, textW, -1, &rect, DT_SINGLELINE | DT_CALCRECT | DT_BOTTOM, NULL);
285 ok(textheight == 1, "Expect returned height:1 got:%d\n", textheight);
287 SetRect(&rect, 0, 100, 0, 100);
288 textheight = DrawTextExW(hdc, textW, -1, &rect, DT_SINGLELINE | DT_CALCRECT | DT_BOTTOM, NULL);
289 ok(textheight == 1, "Expect returned height:1 got:%d\n", textheight);
291 SetRectEmpty(&rect);
292 textheight = DrawTextExW(hdc, textW, -1, &rect, DT_SINGLELINE | DT_CALCRECT | DT_TOP, NULL);
293 /* Set top to text height and bottom zero, so bottom of drawn text to top is zero when DT_VCENTER is used */
294 SetRect(&rect, 0, textheight, 0, 0);
295 textheight = DrawTextExW(hdc, textW, -1, &rect, DT_SINGLELINE | DT_CALCRECT | DT_VCENTER, NULL);
296 ok(textheight == 1, "Expect returned height:1 got:%d\n", textheight);
298 /* invalid dtp size test */
299 dtp.cbSize = -1; /* Invalid */
300 dtp.uiLengthDrawn = 1337;
301 textheight = DrawTextExA(hdc, text, 0, &rect, 0, &dtp);
302 ok(textheight==0,"Got textheight from DrawTextExA\n");
303 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
304 dtp.uiLengthDrawn = 1337;
305 textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, &dtp);
306 ok(textheight==0,"Got textheight from DrawTextExA\n");
307 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
308 dtp.uiLengthDrawn = 1337;
309 textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, &dtp);
310 ok(textheight==0,"Got textheight from DrawTextExA\n");
311 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
312 dtp.uiLengthDrawn = 1337;
313 textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, &dtp);
314 ok(textheight==0,"Got textheight from DrawTextExA\n");
315 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
316 dtp.uiLengthDrawn = 1337;
317 textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, &dtp);
318 ok(textheight==0,"Got textheight from DrawTextExA\n");
319 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
321 /* Margin calculations */
322 dtp.cbSize = sizeof(dtp);
323 dtp.iLeftMargin = 0;
324 dtp.iRightMargin = 0;
325 SetRectEmpty(&rect);
326 DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
327 textlen = rect.right; /* Width without margin */
328 dtp.iLeftMargin = 8;
329 SetRectEmpty(&rect);
330 DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
331 ok(rect.right==dtp.iLeftMargin+textlen ,"Incorrect left margin calculated rc(%ld,%ld)\n", rect.left, rect.right);
332 dtp.iLeftMargin = 0;
333 dtp.iRightMargin = 8;
334 SetRectEmpty(&rect);
335 DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
336 ok(rect.right==dtp.iRightMargin+textlen ,"Incorrect right margin calculated rc(%ld,%ld)\n", rect.left, rect.right);
338 /* Wide char versions */
339 SetRect( &rect, 10,10, 100, 100);
340 SetLastError( 0);
341 heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT, NULL );
342 if( GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
343 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
344 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
345 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
347 SetRect( &rect, 10,10, 100, 100);
348 textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT);
349 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
350 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
351 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
352 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
354 SetRect( &rect, 10,10, 100, 100);
355 heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT, NULL );
356 ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
357 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
359 SetRect( &rect, 10,10, 100, 100);
360 textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT);
361 ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
362 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
363 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
365 SetRect( &rect, 10,10, 100, 100);
366 heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
367 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
368 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
369 if (textheight) /* windows 2000 */
371 if (conform_xp)
372 win_skip("XP conformity failed, skipping XP tests. Probably win 2000\n");
373 conform_xp = FALSE;
375 else
376 ok(textheight==0,"Got textheight from DrawTextExW\n");
378 SetRect( &rect, 10,10, 100, 100);
379 textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT);
380 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
381 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
382 if (conform_xp)
383 ok(textheight==0,"Got textheight from DrawTextW\n");
384 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
386 if (conform_xp) {
387 /* Crashes on NT4 */
388 SetRect( &rect, 10,10, 100, 100);
389 heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
390 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
391 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
392 ok(textheight==0,"Got textheight from DrawTextExW\n");
394 SetRect( &rect, 10,10, 100, 100);
395 textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT);
396 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
397 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
398 ok(textheight==0,"Got textheight from DrawTextW\n");
399 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
403 /* DT_SINGLELINE tests */
405 heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
406 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
407 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
408 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
410 SetRect( &rect, 10,10, 100, 100);
411 textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
412 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
413 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
414 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
415 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
417 SetRect( &rect, 10,10, 100, 100);
418 heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
419 ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
420 wine_dbgstr_rect(&rect));
421 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
423 SetRect( &rect, 10,10, 100, 100);
424 textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
425 ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
426 wine_dbgstr_rect(&rect));
427 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
428 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
430 if (conform_xp) {
431 /* Crashes on NT4 */
432 SetRect( &rect, 10,10, 100, 100);
433 heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
434 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
435 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
436 ok(textheight==0,"Got textheight from DrawTextExW\n");
438 SetRect( &rect, 10,10, 100, 100);
439 textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
440 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
441 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
442 ok(textheight==0,"Got textheight from DrawTextW\n");
443 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
446 SetRect( &rect, 10,10, 100, 100);
447 heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
448 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
449 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
450 if (conform_xp)
451 ok(textheight==0,"Got textheight from DrawTextExW\n");
453 SetRect( &rect, 10,10, 100, 100);
454 textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
455 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
456 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
457 if (conform_xp)
458 ok(textheight==0,"Got textheight from DrawTextW\n");
459 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
461 /* further tests with NULL and empty strings */
462 heightcheck = textheight = DrawTextW(hdc, textW, 0, &rect, 0);
463 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
464 textheight = DrawTextExW(hdc, textW, 0, &rect, 0, NULL );
465 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
466 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
467 heightcheck = textheight = DrawTextW(hdc, emptystringW, 0, &rect, 0);
468 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
469 textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, NULL );
470 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
471 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
472 heightcheck = textheight = DrawTextW(hdc, NULL, 0, &rect, 0);
473 if (conform_xp)
474 ok(textheight==0,"Got textheight from DrawTextW\n");
475 textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, NULL );
476 if (conform_xp)
477 ok(textheight==0,"Got textheight from DrawTextExW\n");
478 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
479 heightcheck = textheight = DrawTextW(hdc, emptystringW, -1, &rect, 0);
480 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
481 textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, NULL );
482 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
483 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
484 if (conform_xp) {
485 /* Crashes on NT4 */
486 heightcheck = textheight = DrawTextW(hdc, NULL, -1, &rect, 0);
487 ok(textheight==0,"Got textheight from DrawTextW\n");
488 textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, NULL );
489 ok(textheight==0,"Got textheight from DrawTextExW\n");
490 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
491 heightcheck = textheight = DrawTextW(hdc, NULL, 10, &rect, 0);
492 ok(textheight==0,"Got textheight from DrawTextW\n");
493 textheight = DrawTextExW(hdc, NULL, 10, &rect, 0, NULL );
494 ok(textheight==0,"Got textheight from DrawTextW\n");
495 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
498 dtp.cbSize = -1; /* Invalid */
499 dtp.uiLengthDrawn = 1337;
500 textheight = DrawTextExW(hdc, textW, 0, &rect, 0, &dtp);
501 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
502 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
503 dtp.uiLengthDrawn = 1337;
504 textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, &dtp);
505 if (conform_xp)
506 ok(textheight==0,"Got textheight from DrawTextExW\n");
507 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
508 dtp.uiLengthDrawn = 1337;
509 textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, &dtp);
510 if (conform_xp)
511 ok(textheight==0,"Got textheight from DrawTextExW\n");
512 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
513 dtp.uiLengthDrawn = 1337;
514 textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, &dtp);
515 ok(textheight==0,"Got textheight from DrawTextExW\n");
516 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
517 if (conform_xp) {
518 /* Crashes on NT4 */
519 dtp.uiLengthDrawn = 1337;
520 textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, &dtp);
521 ok(textheight==0,"Got textheight from DrawTextExW\n");
522 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
525 /* When passing invalid DC, other parameters must be ignored - no crashes on invalid pointers */
527 SetLastError(0xdeadbeef);
528 textheight = DrawTextExW((HDC)0xdeadbeef, (LPWSTR)0xdeadbeef, 100000, &rect, 0, 0);
529 ok(textheight == 0, "Got textheight from DrawTextExW\n");
530 ok(GetLastError() == 0xdeadbeef,"Got error %lu\n", GetLastError());
532 SetLastError(0xdeadbeef);
533 textheight = DrawTextExW((HDC)0xdeadbeef, 0, -1, (LPRECT)0xdeadbeef, DT_CALCRECT, 0);
534 ok(textheight == 0, "Got textheight from DrawTextExW\n");
535 ok(GetLastError() == 0xdeadbeef,"Got error %lu\n", GetLastError());
537 SetLastError(0xdeadbeef);
538 textheight = DrawTextExA((HDC)0xdeadbeef, 0, -1, (LPRECT)0xdeadbeef, DT_CALCRECT, 0);
539 ok(textheight == 0, "Got textheight from DrawTextExA\n");
540 ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_HANDLE,"Got error %lu\n", GetLastError());
542 if (0)
544 /* Crashes */
545 textheight = DrawTextExA((HDC)0xdeadbeef, (LPSTR)0xdeadbeef, 100, &rect, 0, 0);
549 /* More test cases from bug 12226 */
550 SetRectEmpty(&rect);
551 textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
552 ok(textheight, "DrawTextA error %lu\n", GetLastError());
553 ok(0 == rect.left, "expected 0, got %ld\n", rect.left);
554 ok(0 == rect.right, "expected 0, got %ld\n", rect.right);
555 ok(0 == rect.top, "expected 0, got %ld\n", rect.top);
556 ok(rect.bottom, "rect.bottom should not be 0\n");
558 SetRectEmpty(&rect);
559 textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
560 if (!textheight && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
562 win_skip( "DrawTextW not implemented\n" );
564 else
566 ok(textheight, "DrawTextW error %lu\n", GetLastError());
567 ok(0 == rect.left, "expected 0, got %ld\n", rect.left);
568 ok(0 == rect.right, "expected 0, got %ld\n", rect.right);
569 ok(0 == rect.top, "expected 0, got %ld\n", rect.top);
570 ok(rect.bottom, "rect.bottom should not be 0\n");
573 SetRect(&rect, 0, 0, 1, 1);
574 heightcheck = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT);
575 SetRect(&rect, 0, 0, 1, 1);
576 textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
577 ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
578 textheight, heightcheck * 2);
579 SetRect(&rect, 0, 0, 1, 1);
580 textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL);
581 ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n",
582 textheight, heightcheck * 6);
584 SetRect(&rect, 0, 0, 1, 1);
585 heightcheck = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT);
586 SetRect(&rect, 0, 0, 1, 1);
587 textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
588 ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
589 textheight, heightcheck * 2);
590 SetRect(&rect, 0, 0, 1, 1);
591 textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL);
592 ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n",
593 textheight, heightcheck * 6);
595 /* Word break tests with space before punctuation */
596 SetRect(&rect, 0, 0, 200, 1);
597 textheight = DrawTextW(hdc, wordbreak_text_colonW, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
598 ok(textheight == heightcheck, "Got unexpected textheight %d, expected %d.\n",
599 textheight, heightcheck);
601 rect2 = rect;
602 rect.right--;
604 textheight = DrawTextW(hdc, wordbreak_text_colonW, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
605 ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
606 textheight, heightcheck * 2);
607 ok(rect.right > rect2.right - 10, "Got unexpected textwdith %ld, expected larger than %ld.\n",
608 rect.right, rect2.right - 10);
610 SetRect(&rect, 0, 0, 200, 1);
611 textheight = DrawTextW(hdc, wordbreak_text_csbW, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
612 ok(textheight == heightcheck, "Got unexpected textheight %d, expected %d.\n",
613 textheight, heightcheck);
615 rect2 = rect;
616 rect.right--;
618 textheight = DrawTextW(hdc, wordbreak_text_csbW, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
619 ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
620 textheight, heightcheck * 2);
621 ok(rect.right > rect2.right - 10, "Got unexpected textwdith %ld, expected larger than %ld.\n",
622 rect.right, rect2.right - 10);
625 /* DT_TABSTOP | DT_EXPANDTABS tests */
626 SetRect( &rect, 0,0, 10, 10);
627 textheight = DrawTextA(hdc, tabstring, -1, &rect, DT_TABSTOP | DT_EXPANDTABS );
628 ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
630 SetRect( &rect, 0,0, 10, 10);
631 memset(&dtp, 0, sizeof(dtp));
632 dtp.cbSize = sizeof(dtp);
633 textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT, &dtp);
634 ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
635 ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
637 SetRect( &rect2, 0,0, 10, 10);
638 memset(&dtp, 0, sizeof(dtp));
639 dtp.cbSize = sizeof(dtp);
640 textheight = DrawTextExA(hdc, tabstring, -1, &rect2, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp);
641 ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
642 ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
643 ok(rect.left == rect2.left && rect.right != rect2.right && rect.top == rect2.top && rect.bottom == rect2.bottom,
644 "incorrect rect %s rect2 %s\n", wine_dbgstr_rect(&rect), wine_dbgstr_rect(&rect2));
646 SetRect( &rect, 0,0, 10, 10);
647 memset(&dtp, 0, sizeof(dtp));
648 dtp.cbSize = sizeof(dtp);
649 dtp.iTabLength = 8;
650 textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp);
651 ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
652 ok(dtp.iTabLength == 8, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
653 ok(rect.left == rect2.left, "unexpected value %ld, got %ld\n", rect.left, rect2.left);
654 /* XP, 2003 appear to not give the same values. */
655 ok(rect.right == rect2.right || broken(rect.right > rect2.right), "unexpected value %ld, got %ld\n",rect.right, rect2.right);
656 ok(rect.top == rect2.top, "unexpected value %ld, got %ld\n", rect.top, rect2.top);
657 ok(rect.bottom == rect2.bottom , "unexpected value %ld, got %ld\n", rect.bottom, rect2.bottom);
660 SelectObject(hdc, hOldFont);
661 ret = DeleteObject(hFont);
662 ok( ret, "DeleteObject error %lu\n", GetLastError());
664 /* Clean up */
665 ret = ReleaseDC(hwnd, hdc);
666 ok( ret, "ReleaseDC error %lu\n", GetLastError());
667 ret = DestroyWindow(hwnd);
668 ok( ret, "DestroyWindow error %lu\n", GetLastError());
671 /* replace tabs by \t */
672 static void strfmt( const char *str, char *strout)
674 unsigned int i,j ;
675 for(i=0,j=0;i<=strlen(str);i++,j++)
676 if((strout[j]=str[i])=='\t') {
677 strout[j++]='\\';
678 strout[j]='t';
683 #define TABTEST( tabval, tabcount, string, _exp) \
684 { int i; char strdisp[64];\
685 for(i=0;i<8;i++) tabs[i]=(i+1)*(tabval); \
686 extent = GetTabbedTextExtentA( hdc, string, strlen( string), (tabcount), tabs); \
687 strfmt( string, strdisp); \
688 /* trace( "Extent is %08lx\n", extent); */\
689 ok( extent == _exp, "Test case \"%s\". Text extent is 0x%lx, expected 0x%lx tab %d tabcount %d\n", \
690 strdisp, extent, _exp, tabval, tabcount); \
694 static void test_TabbedText(void)
696 HWND hwnd;
697 HDC hdc;
698 BOOL ret;
699 TEXTMETRICA tm;
700 DWORD extent;
701 INT tabs[8], cx, cy, tab, tabcount,t,align;
703 /* Initialization */
704 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
705 0, 0, 200, 200, 0, 0, 0, NULL);
706 ok(hwnd != 0, "CreateWindowExA error %lu\n", GetLastError());
707 hdc = GetDC(hwnd);
708 ok(hdc != 0, "GetDC error %lu\n", GetLastError());
710 ret = GetTextMetricsA( hdc, &tm);
711 ok( ret, "GetTextMetrics error %lu\n", GetLastError());
713 extent = GetTabbedTextExtentA( hdc, "x", 0, 1, tabs);
714 ok( extent == 0, "GetTabbedTextExtentA returned non-zero on nCount == 0\n");
716 extent = GetTabbedTextExtentA( hdc, "x", 1, 1, tabs);
717 cx = LOWORD( extent);
718 cy = HIWORD( extent);
719 trace( "cx is %d cy is %d\n", cx, cy);
721 align=1;
722 for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to
723 catch the one off errors */
724 tab = (cx *4 + t);
725 /* test the special case tabcount =1 and the general array (80 of tabs */
726 for( tabcount = 1; tabcount <= 8; tabcount +=7) {
727 TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
728 TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
729 TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab+cx, cy))
730 TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
731 TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
732 TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab+cx, cy))
733 TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab+cx, cy))
734 TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(tab+cx, cy))
735 TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(t>0 ? tab + cx : 2*tab+cx, cy))
736 TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab+cx, cy))
739 align=-1;
740 for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to
741 catch the one off errors */
742 tab = (cx *4 + t);
743 /* test the special case tabcount =1 and the general array (8) of tabs */
744 for( tabcount = 1; tabcount <= 8; tabcount +=7) {
745 TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
746 TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
747 TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab, cy))
748 TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
749 TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
750 TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab, cy))
751 TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab, cy))
752 TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(4 * cx >= tab ? 2*tab :tab, cy))
753 TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(2*tab, cy))
754 TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab, cy))
758 ReleaseDC( hwnd, hdc );
759 DestroyWindow( hwnd );
762 static void test_DrawState(void)
764 static const char text[] = "Sample text string";
765 HWND hwnd;
766 HDC hdc;
767 BOOL ret;
769 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
770 0, 0, 200, 200, 0, 0, 0, NULL);
771 assert(hwnd);
773 hdc = GetDC(hwnd);
774 assert(hdc);
776 SetLastError(0xdeadbeef);
777 ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, (LPARAM)text, strlen(text),
778 0, 0, 10, 10, DST_TEXT);
779 ok(ret, "DrawState error %lu\n", GetLastError());
781 SetLastError(0xdeadbeef);
782 ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, (LPARAM)text, 0,
783 0, 0, 10, 10, DST_TEXT);
784 ok(ret, "DrawState error %lu\n", GetLastError());
786 SetLastError(0xdeadbeef);
787 ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, strlen(text),
788 0, 0, 10, 10, DST_TEXT);
789 ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
790 ok(GetLastError() == 0xdeadbeef, "not expected error %lu\n", GetLastError());
792 SetLastError(0xdeadbeef);
793 ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, 0,
794 0, 0, 10, 10, DST_TEXT);
795 ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
796 ok(GetLastError() == 0xdeadbeef, "not expected error %lu\n", GetLastError());
798 ReleaseDC(hwnd, hdc);
799 DestroyWindow(hwnd);
802 static void test_CharToOem_OemToChar(void)
804 static const WCHAR helloWorldW[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
805 static const WCHAR emptyW[] = {0};
806 static const char helloWorld[] = "Hello World";
807 static const struct
809 BOOL src, dst, ret;
811 tests[] =
813 { FALSE, FALSE, FALSE },
814 { TRUE, FALSE, FALSE },
815 { FALSE, TRUE, FALSE },
816 { TRUE, TRUE, TRUE },
818 BOOL ret;
819 int i;
820 char oem;
821 WCHAR uni, expect;
823 for (i = 0; i < ARRAY_SIZE(tests); i++)
825 const char *expected = tests[i].ret ? helloWorld : "";
826 const char *src = tests[i].src ? helloWorld : NULL;
827 char buf[64], *dst = tests[i].dst ? buf : NULL;
829 memset(buf, 0, sizeof(buf));
830 ret = CharToOemA(src, dst);
831 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
832 ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
834 memset(buf, 0, sizeof(buf));
835 ret = CharToOemBuffA(src, dst, sizeof(helloWorld));
836 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
837 ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
839 memset(buf, 0, sizeof(buf));
840 ret = OemToCharA(src, dst);
841 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
842 ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
844 memset(buf, 0, sizeof(buf));
845 ret = OemToCharBuffA(src, dst, sizeof(helloWorld));
846 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
847 ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
850 for (i = 0; i < ARRAY_SIZE(tests); i++)
852 const char *expected = tests[i].ret ? helloWorld : "";
853 const WCHAR *src = tests[i].src ? helloWorldW : NULL;
854 char buf[64], *dst = tests[i].dst ? buf : NULL;
856 memset(buf, 0, sizeof(buf));
857 ret = CharToOemW(src, dst);
858 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
859 ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
861 memset(buf, 0, sizeof(buf));
862 ret = CharToOemBuffW(src, dst, ARRAY_SIZE(helloWorldW));
863 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
864 ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
867 for (i = 0; i < ARRAY_SIZE(tests); i++)
869 const WCHAR *expected = tests[i].ret ? helloWorldW : emptyW;
870 const char *src = tests[i].src ? helloWorld : NULL;
871 WCHAR buf[64], *dst = tests[i].dst ? buf : NULL;
873 memset(buf, 0, sizeof(buf));
874 ret = OemToCharW(src, dst);
875 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
876 ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf));
878 memset(buf, 0, sizeof(buf));
879 ret = OemToCharBuffW(src, dst, sizeof(helloWorld));
880 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
881 ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf));
884 for (i = 0; i < 0x100; i++)
886 oem = i;
887 ret = OemToCharBuffW( &oem, &uni, 1 );
888 ok( ret, "%02x: returns FALSE\n", i );
889 MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED | MB_USEGLYPHCHARS, &oem, 1, &expect, 1 );
890 ok( uni == expect, "%02x: got %04x expected %04x\n", i, uni, expect );
894 START_TEST(text)
896 test_TabbedText();
897 test_DrawTextCalcRect();
898 test_DrawState();
899 test_CharToOem_OemToChar();