1 /*
2  * DrawText tests
3  *
4  * Copyright (c) 2004 Zach Gorman
5  * Copyright 2007,2016 Dmitry Timoshkov
6  *
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.
11  *
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.
16  *
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
20  */
21 
22 #include <assert.h>
23 
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"
30 
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)
33 
34 static void test_DrawTextCalcRect(void)
35 {
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 char tabstring[] = "one\ttwo";
49     INT textlen, textheight, heightcheck;
50     RECT rect = { 0, 0, 100, 0 }, rect2;
51     BOOL ret;
52     DRAWTEXTPARAMS dtp;
53     BOOL conform_xp = TRUE;
54 
55     /* Initialization */
56     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
57                            0, 0, 200, 200, 0, 0, 0, NULL);
58     ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
59     hdc = GetDC(hwnd);
60     ok(hdc != 0, "GetDC error %u\n", GetLastError());
61     trace("hdc %p\n", hdc);
62     textlen = lstrlenA(text);
63 
64     /* LOGFONT initialization */
65     memset(&lf, 0, sizeof(lf));
66     lf.lfCharSet = ANSI_CHARSET;
67     lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
68     lf.lfWeight = FW_DONTCARE;
69     lf.lfHeight = 0; /* mapping mode dependent */
70     lf.lfQuality = DEFAULT_QUALITY;
71     lstrcpyA(lf.lfFaceName, "Arial");
72 
73     /* DrawText in MM_HIENGLISH with DT_CALCRECT */
74     SetMapMode(hdc, MM_HIENGLISH);
75     lf.lfHeight = 100 * 9 / 72; /* 9 point */
76     hFont = CreateFontIndirectA(&lf);
77     ok(hFont != 0, "CreateFontIndirectA error %u\n",
78        GetLastError());
79     hOldFont = SelectObject(hdc, hFont);
80 
81     textheight = DrawTextA(hdc, text, textlen, &rect, DT_CALCRECT |
82        DT_EXTERNALLEADING | DT_WORDBREAK | DT_NOCLIP | DT_LEFT |
83        DT_NOPREFIX);
84     ok( textheight, "DrawTextA error %u\n", GetLastError());
85 
86     trace("MM_HIENGLISH rect.bottom %d\n", rect.bottom);
87     ok(rect.bottom < 0, "In MM_HIENGLISH, DrawText with "
88        "DT_CALCRECT should return a negative rectangle bottom. "
89        "(bot=%d)\n", rect.bottom);
90 
91     SelectObject(hdc, hOldFont);
92     ret = DeleteObject(hFont);
93     ok( ret, "DeleteObject error %u\n", GetLastError());
94 
95 
96     /* DrawText in MM_TEXT with DT_CALCRECT */
97     SetMapMode(hdc, MM_TEXT);
98     lf.lfHeight = -MulDiv(9, GetDeviceCaps(hdc,
99        LOGPIXELSY), 72); /* 9 point */
100     hFont = CreateFontIndirectA(&lf);
101     ok(hFont != 0, "CreateFontIndirectA error %u\n",
102        GetLastError());
103     hOldFont = SelectObject(hdc, hFont);
104 
105     textheight = DrawTextA(hdc, text, textlen, &rect, DT_CALCRECT |
106        DT_EXTERNALLEADING | DT_WORDBREAK | DT_NOCLIP | DT_LEFT |
107        DT_NOPREFIX);
108     ok( textheight, "DrawTextA error %u\n", GetLastError());
109 
110     trace("MM_TEXT rect.bottom %d\n", rect.bottom);
111     ok(rect.bottom > 0, "In MM_TEXT, DrawText with DT_CALCRECT "
112        "should return a positive rectangle bottom. (bot=%d)\n",
113        rect.bottom);
114 
115     /* empty or null text should in some cases calc an empty rectangle */
116 
117     SetRect( &rect, 10,10, 100, 100);
118     heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT, NULL );
119     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
120         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
121     ok(textheight==0,"Got textheight from DrawTextExA\n");
122 
123     SetRect( &rect, 10,10, 100, 100);
124     textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT);
125     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
126         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
127     if (conform_xp)
128         ok(textheight==0,"Got textheight from DrawTextA\n");
129     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
130 
131     SetRect( &rect, 10,10, 100, 100);
132     SetLastError( 0);
133     heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT, NULL );
134     ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
135     ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
136 
137     SetRect( &rect, 10,10, 100, 100);
138     textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT);
139     ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
140     ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
141     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
142 
143     SetRect( &rect, 10,10, 100, 100);
144     SetLastError( 0);
145     heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
146     ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
147     if (!textheight) /* Windows NT 4 */
148     {
149         if (conform_xp)
150             win_skip("XP conformity failed, skipping XP tests. Probably winNT\n");
151         conform_xp = FALSE;
152     }
153     else
154         ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
155 
156     SetRect( &rect, 10,10, 100, 100);
157     textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT);
158     ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
159     if (conform_xp)
160         ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
161     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
162 
163     SetRect( &rect, 10,10, 100, 100);
164     heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
165     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
166         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
167     if (conform_xp)
168         ok(textheight==0,"Got textheight from DrawTextExA\n");
169 
170     SetRect( &rect, 10,10, 100, 100);
171     textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT);
172     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
173         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
174     if (conform_xp)
175         ok(textheight==0,"Got textheight from DrawTextA\n");
176     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
177 
178     /* DT_SINGLELINE tests */
179 
180     SetRect( &rect, 10,10, 100, 100);
181     heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
182     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
183         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
184     if (conform_xp)
185         ok(textheight==0,"Got textheight from DrawTextExA\n");
186 
187     SetRect( &rect, 10,10, 100, 100);
188     textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
189     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
190         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
191     if (conform_xp)
192         ok(textheight==0,"Got textheight from DrawTextA\n");
193     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
194 
195     SetRect( &rect, 10,10, 100, 100);
196     SetLastError( 0);
197     heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
198     ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
199        wine_dbgstr_rect(&rect));
200     ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
201 
202     SetRect( &rect, 10,10, 100, 100);
203     textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
204     ok(!EMPTY(rect) && MODIFIED (rect), "rectangle should be modified got %s\n",
205        wine_dbgstr_rect(&rect));
206     ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
207     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
208 
209     SetRect( &rect, 10,10, 100, 100);
210     SetLastError( 0);
211     heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
212     ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
213        wine_dbgstr_rect(&rect));
214     if (conform_xp)
215         ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
216 
217     SetRect( &rect, 10,10, 100, 100);
218     textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
219     ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
220        wine_dbgstr_rect(&rect));
221     if (conform_xp)
222         ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
223     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
224 
225     SetRect( &rect, 10,10, 100, 100);
226     heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
227     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
228         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
229     if (conform_xp)
230         ok(textheight==0,"Got textheight from DrawTextExA\n");
231 
232     SetRect( &rect, 10,10, 100, 100);
233     textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
234     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
235         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
236     if (conform_xp)
237         ok(textheight==0,"Got textheight from DrawTextA\n");
238     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
239 
240     /* further tests with  0 count, NULL and empty strings */
241     heightcheck = textheight = DrawTextA(hdc, text, 0, &rect, 0);
242     if (conform_xp)
243         ok(textheight==0,"Got textheight from DrawTextA\n");
244     textheight = DrawTextExA(hdc, text, 0, &rect, 0, NULL );
245     if (conform_xp)
246         ok(textheight==0,"Got textheight from DrawTextExA\n");
247     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
248     heightcheck = textheight = DrawTextA(hdc, emptystring, 0, &rect, 0);
249     if (conform_xp)
250         ok(textheight==0,"Got textheight from DrawTextA\n");
251     textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, NULL );
252     if (conform_xp)
253         ok(textheight==0,"Got textheight from DrawTextExA\n");
254     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
255     heightcheck = textheight = DrawTextA(hdc, NULL, 0, &rect, 0);
256     if (conform_xp)
257         ok(textheight==0,"Got textheight from DrawTextA\n");
258     textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, NULL );
259     if (conform_xp)
260         ok(textheight==0,"Got textheight from DrawTextExA\n");
261     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
262     heightcheck = textheight = DrawTextA(hdc, emptystring, -1, &rect, 0);
263     ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
264     textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, NULL );
265     ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
266     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
267     heightcheck = textheight = DrawTextA(hdc, NULL, -1, &rect, 0);
268     if (conform_xp)
269         ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
270     textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, NULL );
271     if (conform_xp)
272         ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
273     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
274     heightcheck = textheight = DrawTextA(hdc, NULL, 10, &rect, 0);
275     ok(textheight==0,"Got textheight from DrawTextA\n");
276     textheight = DrawTextExA(hdc, NULL, 10, &rect, 0, NULL );
277     ok(textheight==0,"Got textheight from DrawTextA\n");
278     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
279 
280 
281     /* invalid dtp size test */
282     dtp.cbSize = -1; /* Invalid */
283     dtp.uiLengthDrawn = 1337;
284     textheight = DrawTextExA(hdc, text, 0, &rect, 0, &dtp);
285     ok(textheight==0,"Got textheight from DrawTextExA\n");
286     ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
287     dtp.uiLengthDrawn = 1337;
288     textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, &dtp);
289     ok(textheight==0,"Got textheight from DrawTextExA\n");
290     ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
291     dtp.uiLengthDrawn = 1337;
292     textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, &dtp);
293     ok(textheight==0,"Got textheight from DrawTextExA\n");
294     ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
295     dtp.uiLengthDrawn = 1337;
296     textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, &dtp);
297     ok(textheight==0,"Got textheight from DrawTextExA\n");
298     ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
299     dtp.uiLengthDrawn = 1337;
300     textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, &dtp);
301     ok(textheight==0,"Got textheight from DrawTextExA\n");
302     ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
303 
304     /* Margin calculations */
305     dtp.cbSize = sizeof(dtp);
306     dtp.iLeftMargin = 0;
307     dtp.iRightMargin = 0;
308     SetRectEmpty(&rect);
309     DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
310     textlen = rect.right; /* Width without margin */
311     dtp.iLeftMargin = 8;
312     SetRectEmpty(&rect);
313     DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
314     ok(rect.right==dtp.iLeftMargin+textlen  ,"Incorrect left margin calculated  rc(%d,%d)\n", rect.left, rect.right);
315     dtp.iLeftMargin = 0;
316     dtp.iRightMargin = 8;
317     SetRectEmpty(&rect);
318     DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
319     ok(rect.right==dtp.iRightMargin+textlen  ,"Incorrect right margin calculated rc(%d,%d)\n", rect.left, rect.right);
320 
321     /* Wide char versions */
322     SetRect( &rect, 10,10, 100, 100);
323     SetLastError( 0);
324     heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT, NULL );
325     if( GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
326         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
327             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
328         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
329 
330         SetRect( &rect, 10,10, 100, 100);
331         textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT);
332         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
333             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
334         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
335         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
336 
337         SetRect( &rect, 10,10, 100, 100);
338         heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT, NULL );
339         ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
340         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
341 
342         SetRect( &rect, 10,10, 100, 100);
343         textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT);
344         ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
345         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
346         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
347 
348         SetRect( &rect, 10,10, 100, 100);
349         heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
350         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
351             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
352         if (textheight) /* windows 2000 */
353         {
354             if (conform_xp)
355                 win_skip("XP conformity failed, skipping XP tests. Probably win 2000\n");
356             conform_xp = FALSE;
357         }
358         else
359             ok(textheight==0,"Got textheight from DrawTextExW\n");
360 
361         SetRect( &rect, 10,10, 100, 100);
362         textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT);
363         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
364             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
365         if (conform_xp)
366             ok(textheight==0,"Got textheight from DrawTextW\n");
367         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
368 
369         if (conform_xp) {
370             /* Crashes on NT4 */
371             SetRect( &rect, 10,10, 100, 100);
372             heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
373             ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
374                 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
375             ok(textheight==0,"Got textheight from DrawTextExW\n");
376 
377             SetRect( &rect, 10,10, 100, 100);
378             textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT);
379             ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
380                 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
381             ok(textheight==0,"Got textheight from DrawTextW\n");
382             ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
383         }
384 
385 
386         /* DT_SINGLELINE tests */
387 
388         heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
389         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
390             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
391         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
392 
393         SetRect( &rect, 10,10, 100, 100);
394         textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
395         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
396             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
397         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
398         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
399 
400         SetRect( &rect, 10,10, 100, 100);
401         heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
402         ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
403            wine_dbgstr_rect(&rect));
404         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
405 
406         SetRect( &rect, 10,10, 100, 100);
407         textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
408         ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
409            wine_dbgstr_rect(&rect));
410         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
411         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
412 
413         if (conform_xp) {
414             /* Crashes on NT4 */
415             SetRect( &rect, 10,10, 100, 100);
416             heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
417             ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
418                 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
419             ok(textheight==0,"Got textheight from DrawTextExW\n");
420 
421             SetRect( &rect, 10,10, 100, 100);
422             textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
423             ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
424                 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
425             ok(textheight==0,"Got textheight from DrawTextW\n");
426             ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
427         }
428 
429         SetRect( &rect, 10,10, 100, 100);
430         heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
431         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
432             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
433         if (conform_xp)
434             ok(textheight==0,"Got textheight from DrawTextExW\n");
435 
436         SetRect( &rect, 10,10, 100, 100);
437         textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
438         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
439             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
440         if (conform_xp)
441             ok(textheight==0,"Got textheight from DrawTextW\n");
442         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
443 
444         /* further tests with NULL and empty strings */
445         heightcheck = textheight = DrawTextW(hdc, textW, 0, &rect, 0);
446         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
447         textheight = DrawTextExW(hdc, textW, 0, &rect, 0, NULL );
448         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
449         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
450         heightcheck = textheight = DrawTextW(hdc, emptystringW, 0, &rect, 0);
451         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
452         textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, NULL );
453         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
454         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
455         heightcheck = textheight = DrawTextW(hdc, NULL, 0, &rect, 0);
456         if (conform_xp)
457             ok(textheight==0,"Got textheight from DrawTextW\n");
458         textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, NULL );
459         if (conform_xp)
460             ok(textheight==0,"Got textheight from DrawTextExW\n");
461         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
462         heightcheck = textheight = DrawTextW(hdc, emptystringW, -1, &rect, 0);
463         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
464         textheight = DrawTextExW(hdc, emptystringW, -1, &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         if (conform_xp) {
468             /* Crashes on NT4 */
469             heightcheck = textheight = DrawTextW(hdc, NULL, -1, &rect, 0);
470             ok(textheight==0,"Got textheight from DrawTextW\n");
471             textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, NULL );
472             ok(textheight==0,"Got textheight from DrawTextExW\n");
473             ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
474             heightcheck = textheight = DrawTextW(hdc, NULL, 10, &rect, 0);
475             ok(textheight==0,"Got textheight from DrawTextW\n");
476             textheight = DrawTextExW(hdc, NULL, 10, &rect, 0, NULL );
477             ok(textheight==0,"Got textheight from DrawTextW\n");
478             ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
479         }
480 
481         dtp.cbSize = -1; /* Invalid */
482         dtp.uiLengthDrawn = 1337;
483         textheight = DrawTextExW(hdc, textW, 0, &rect, 0, &dtp);
484         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
485         ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
486         dtp.uiLengthDrawn = 1337;
487         textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, &dtp);
488         if (conform_xp)
489             ok(textheight==0,"Got textheight from DrawTextExW\n");
490         ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
491         dtp.uiLengthDrawn = 1337;
492         textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, &dtp);
493         if (conform_xp)
494             ok(textheight==0,"Got textheight from DrawTextExW\n");
495         ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
496         dtp.uiLengthDrawn = 1337;
497         textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, &dtp);
498         ok(textheight==0,"Got textheight from DrawTextExW\n");
499         ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
500         if (conform_xp) {
501             /* Crashes on NT4 */
502             dtp.uiLengthDrawn = 1337;
503             textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, &dtp);
504             ok(textheight==0,"Got textheight from DrawTextExW\n");
505             ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
506         }
507     }
508 
509     /* More test cases from bug 12226 */
510     SetRectEmpty(&rect);
511     textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
512     ok(textheight, "DrawTextA error %u\n", GetLastError());
513     ok(0 == rect.left, "expected 0, got %d\n", rect.left);
514     ok(0 == rect.right, "expected 0, got %d\n", rect.right);
515     ok(0 == rect.top, "expected 0, got %d\n", rect.top);
516     ok(rect.bottom, "rect.bottom should not be 0\n");
517 
518     SetRectEmpty(&rect);
519     textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
520     if (!textheight && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
521     {
522         win_skip( "DrawTextW not implemented\n" );
523     }
524     else
525     {
526         ok(textheight, "DrawTextW error %u\n", GetLastError());
527         ok(0 == rect.left, "expected 0, got %d\n", rect.left);
528         ok(0 == rect.right, "expected 0, got %d\n", rect.right);
529         ok(0 == rect.top, "expected 0, got %d\n", rect.top);
530         ok(rect.bottom, "rect.bottom should not be 0\n");
531     }
532 
533     SetRect(&rect, 0, 0, 1, 1);
534     heightcheck = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT);
535     SetRect(&rect, 0, 0, 1, 1);
536     textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
537     ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
538        textheight, heightcheck * 2);
539     SetRect(&rect, 0, 0, 1, 1);
540     textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL);
541     ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n",
542        textheight, heightcheck * 6);
543 
544     SetRect(&rect, 0, 0, 1, 1);
545     heightcheck = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT);
546     SetRect(&rect, 0, 0, 1, 1);
547     textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
548     ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
549        textheight, heightcheck * 2);
550     SetRect(&rect, 0, 0, 1, 1);
551     textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL);
552     ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n",
553        textheight, heightcheck * 6);
554 
555     /* DT_TABSTOP | DT_EXPANDTABS tests */
556     SetRect( &rect, 0,0, 10, 10);
557     textheight = DrawTextA(hdc, tabstring, -1, &rect, DT_TABSTOP | DT_EXPANDTABS );
558     ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
559 
560     SetRect( &rect, 0,0, 10, 10);
561     memset(&dtp, 0, sizeof(dtp));
562     dtp.cbSize = sizeof(dtp);
563     textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT, &dtp);
564     ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
565     ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
566 
567     SetRect( &rect2, 0,0, 10, 10);
568     memset(&dtp, 0, sizeof(dtp));
569     dtp.cbSize = sizeof(dtp);
570     textheight = DrawTextExA(hdc, tabstring, -1, &rect2, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp);
571     ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
572     ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
573     ok(rect.left == rect2.left && rect.right != rect2.right && rect.top == rect2.top && rect.bottom == rect2.bottom,
574        "incorrect rect %s rect2 %s\n", wine_dbgstr_rect(&rect), wine_dbgstr_rect(&rect2));
575 
576     SetRect( &rect, 0,0, 10, 10);
577     memset(&dtp, 0, sizeof(dtp));
578     dtp.cbSize = sizeof(dtp);
579     dtp.iTabLength = 8;
580     textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp);
581     ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
582     ok(dtp.iTabLength == 8, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
583     ok(rect.left == rect2.left, "unexpected value %d, got %d\n", rect.left, rect2.left);
584     /* XP, 2003 appear to not give the same values. */
585     ok(rect.right == rect2.right || broken(rect.right > rect2.right), "unexpected value %d, got %d\n",rect.right, rect2.right);
586     ok(rect.top == rect2.top, "unexpected value %d, got %d\n", rect.top, rect2.top);
587     ok(rect.bottom == rect2.bottom , "unexpected value %d, got %d\n", rect.bottom, rect2.bottom);
588 
589 
590     SelectObject(hdc, hOldFont);
591     ret = DeleteObject(hFont);
592     ok( ret, "DeleteObject error %u\n", GetLastError());
593 
594     /* Clean up */
595     ret = ReleaseDC(hwnd, hdc);
596     ok( ret, "ReleaseDC error %u\n", GetLastError());
597     ret = DestroyWindow(hwnd);
598     ok( ret, "DestroyWindow error %u\n", GetLastError());
599 }
600 
601 /* replace tabs by \t */
602 static void strfmt( const char *str, char *strout)
603 {
604     unsigned int i,j ;
605     for(i=0,j=0;i<=strlen(str);i++,j++)
606         if((strout[j]=str[i])=='\t') {
607             strout[j++]='\\';
608             strout[j]='t';
609         }
610 }
611 
612 
613 #define TABTEST( tabval, tabcount, string, _exp) \
614 { int i; char strdisp[64];\
615     for(i=0;i<8;i++) tabs[i]=(i+1)*(tabval); \
616     extent = GetTabbedTextExtentA( hdc, string, strlen( string), (tabcount), tabs); \
617     strfmt( string, strdisp); \
618  /*   trace( "Extent is %08lx\n", extent); */\
619     ok( extent == _exp, "Test case \"%s\". Text extent is 0x%x, expected 0x%x tab %d tabcount %d\n", \
620         strdisp, extent, _exp, tabval, tabcount); \
621 } \
622 
623 
624 static void test_TabbedText(void)
625 {
626     HWND hwnd;
627     HDC hdc;
628     BOOL ret;
629     TEXTMETRICA tm;
630     DWORD extent;
631     INT tabs[8], cx, cy, tab, tabcount,t,align;
632 
633     /* Initialization */
634     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
635                            0, 0, 200, 200, 0, 0, 0, NULL);
636     ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
637     hdc = GetDC(hwnd);
638     ok(hdc != 0, "GetDC error %u\n", GetLastError());
639 
640     ret = GetTextMetricsA( hdc, &tm);
641     ok( ret, "GetTextMetrics error %u\n", GetLastError());
642 
643     extent = GetTabbedTextExtentA( hdc, "x", 0, 1, tabs);
644     ok( extent == 0, "GetTabbedTextExtentA returned non-zero on nCount == 0\n");
645 
646     extent = GetTabbedTextExtentA( hdc, "x", 1, 1, tabs);
647     cx = LOWORD( extent);
648     cy = HIWORD( extent);
649     trace( "cx is %d cy is %d\n", cx, cy);
650 
651     align=1;
652     for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to
653                                catch the one off errors */
654         tab =  (cx *4 + t);
655         /* test the special case tabcount =1 and the general array (80 of tabs */
656         for( tabcount = 1; tabcount <= 8; tabcount +=7) {
657             TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
658             TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
659             TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab+cx, cy))
660             TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
661             TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
662             TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab+cx, cy))
663             TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab+cx, cy))
664             TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(tab+cx, cy))
665             TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(t>0 ? tab + cx : 2*tab+cx, cy))
666             TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab+cx, cy))
667         }
668     }
669     align=-1;
670     for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to
671                                catch the one off errors */
672         tab =  (cx *4 + t);
673         /* test the special case tabcount =1 and the general array (8) of tabs */
674         for( tabcount = 1; tabcount <= 8; tabcount +=7) {
675             TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
676             TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
677             TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab, cy))
678             TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
679             TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
680             TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab, cy))
681             TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab, cy))
682             TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(4 * cx >= tab ? 2*tab :tab, cy))
683             TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(2*tab, cy))
684             TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab, cy))
685         }
686     }
687 
688     ReleaseDC( hwnd, hdc );
689     DestroyWindow( hwnd );
690 }
691 
692 static void test_DrawState(void)
693 {
694     static const char text[] = "Sample text string";
695     HWND hwnd;
696     HDC hdc;
697     BOOL ret;
698 
699     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
700                            0, 0, 200, 200, 0, 0, 0, NULL);
701     assert(hwnd);
702 
703     hdc = GetDC(hwnd);
704     assert(hdc);
705 
706     SetLastError(0xdeadbeef);
707     ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, (LPARAM)text, strlen(text),
708                     0, 0, 10, 10, DST_TEXT);
709     ok(ret, "DrawState error %u\n", GetLastError());
710 
711     SetLastError(0xdeadbeef);
712     ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, (LPARAM)text, 0,
713                     0, 0, 10, 10, DST_TEXT);
714     ok(ret, "DrawState error %u\n", GetLastError());
715 
716     SetLastError(0xdeadbeef);
717     ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, strlen(text),
718                     0, 0, 10, 10, DST_TEXT);
719     ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
720     ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError());
721 
722     SetLastError(0xdeadbeef);
723     ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, 0,
724                     0, 0, 10, 10, DST_TEXT);
725     ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
726     ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError());
727 
728     ReleaseDC(hwnd, hdc);
729     DestroyWindow(hwnd);
730 }
731 
732 static void test_CharToOem_OemToChar(void)
733 {
734     static const WCHAR helloWorldW[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
735     static const WCHAR emptyW[] = {0};
736     static const char helloWorld[] = "Hello World";
737     static const struct
738     {
739         BOOL src, dst, ret;
740     }
741     tests[] =
742     {
743         { FALSE, FALSE, FALSE },
744         { TRUE,  FALSE, FALSE },
745         { FALSE, TRUE,  FALSE },
746         { TRUE,  TRUE,  TRUE  },
747     };
748     BOOL ret;
749     int i;
750     char oem;
751     WCHAR uni, expect;
752 
753     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
754     {
755         const char *expected = tests[i].ret ? helloWorld : "";
756         const char *src = tests[i].src ? helloWorld : NULL;
757         char buf[64], *dst = tests[i].dst ? buf : NULL;
758 
759         memset(buf, 0, sizeof(buf));
760         ret = CharToOemA(src, dst);
761         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
762         ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
763 
764         memset(buf, 0, sizeof(buf));
765         ret = CharToOemBuffA(src, dst, sizeof(helloWorld));
766         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
767         ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
768 
769         memset(buf, 0, sizeof(buf));
770         ret = OemToCharA(src, dst);
771         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
772         ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
773 
774         memset(buf, 0, sizeof(buf));
775         ret = OemToCharBuffA(src, dst, sizeof(helloWorld));
776         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
777         ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
778     }
779 
780     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
781     {
782         const char *expected = tests[i].ret ? helloWorld : "";
783         const WCHAR *src = tests[i].src ? helloWorldW : NULL;
784         char buf[64], *dst = tests[i].dst ? buf : NULL;
785 
786         memset(buf, 0, sizeof(buf));
787         ret = CharToOemW(src, dst);
788         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
789         ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
790 
791         memset(buf, 0, sizeof(buf));
792         ret = CharToOemBuffW(src, dst, sizeof(helloWorldW)/sizeof(WCHAR));
793         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
794         ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
795     }
796 
797     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
798     {
799         const WCHAR *expected = tests[i].ret ? helloWorldW : emptyW;
800         const char *src = tests[i].src ? helloWorld : NULL;
801         WCHAR buf[64], *dst = tests[i].dst ? buf : NULL;
802 
803         memset(buf, 0, sizeof(buf));
804         ret = OemToCharW(src, dst);
805         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
806         ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf));
807 
808         memset(buf, 0, sizeof(buf));
809         ret = OemToCharBuffW(src, dst, sizeof(helloWorld));
810         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
811         ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf));
812     }
813 
814     for (i = 0; i < 0x100; i++)
815     {
816         oem = i;
817         ret = OemToCharBuffW( &oem, &uni, 1 );
818         ok( ret, "%02x: returns FALSE\n", i );
819         MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED | MB_USEGLYPHCHARS, &oem, 1, &expect, 1 );
820         ok( uni == expect, "%02x: got %04x expected %04x\n", i, uni, expect );
821     }
822 }
823 
824 START_TEST(text)
825 {
826     test_TabbedText();
827     test_DrawTextCalcRect();
828     test_DrawState();
829     test_CharToOem_OemToChar();
830 }
831