push b0b97fcd59eff07f047585692fa36859b459324f
[wine/hacks.git] / dlls / gdi32 / tests / pen.c
blob8b2e41a575a202eaf7bb3c636136483560daa50a
1 /*
2 * Unit test suite for pens
4 * Copyright 2006 Dmitry Timoshkov
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <assert.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
29 #include "wine/test.h"
31 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
32 #define expect2(expected, alt, got) ok(got == expected || got == alt, \
33 "Expected %.8x or %.8x, got %.8x\n", expected, alt, got)
35 static void test_logpen(void)
37 static const struct
39 UINT style;
40 INT width;
41 COLORREF color;
42 UINT ret_style;
43 INT ret_width;
44 COLORREF ret_color;
45 } pen[] = {
46 { PS_SOLID, -123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) },
47 { PS_SOLID, 0, RGB(0x12,0x34,0x56), PS_SOLID, 0, RGB(0x12,0x34,0x56) },
48 { PS_SOLID, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) },
49 { PS_DASH, 123, RGB(0x12,0x34,0x56), PS_DASH, 123, RGB(0x12,0x34,0x56) },
50 { PS_DOT, 123, RGB(0x12,0x34,0x56), PS_DOT, 123, RGB(0x12,0x34,0x56) },
51 { PS_DASHDOT, 123, RGB(0x12,0x34,0x56), PS_DASHDOT, 123, RGB(0x12,0x34,0x56) },
52 { PS_DASHDOTDOT, 123, RGB(0x12,0x34,0x56), PS_DASHDOTDOT, 123, RGB(0x12,0x34,0x56) },
53 { PS_NULL, -123, RGB(0x12,0x34,0x56), PS_NULL, 1, 0 },
54 { PS_NULL, 123, RGB(0x12,0x34,0x56), PS_NULL, 1, 0 },
55 { PS_INSIDEFRAME, 123, RGB(0x12,0x34,0x56), PS_INSIDEFRAME, 123, RGB(0x12,0x34,0x56) },
56 { PS_USERSTYLE, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) },
57 { PS_ALTERNATE, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) }
59 INT i, size;
60 HPEN hpen;
61 LOGPEN lp;
62 EXTLOGPEN elp;
63 LOGBRUSH lb;
64 DWORD obj_type, user_style[2] = { 0xabc, 0xdef };
65 struct
67 EXTLOGPEN elp;
68 DWORD style_data[10];
69 } ext_pen;
71 for (i = 0; i < sizeof(pen)/sizeof(pen[0]); i++)
73 trace("testing style %u\n", pen[i].style);
75 /********************** cosmetic pens **********************/
76 /* CreatePenIndirect behaviour */
77 lp.lopnStyle = pen[i].style,
78 lp.lopnWidth.x = pen[i].width;
79 lp.lopnWidth.y = 11; /* just in case */
80 lp.lopnColor = pen[i].color;
81 SetLastError(0xdeadbeef);
82 hpen = CreatePenIndirect(&lp);
83 ok(hpen != 0, "CreatePen error %d\n", GetLastError());
85 obj_type = GetObjectType(hpen);
86 ok(obj_type == OBJ_PEN, "wrong object type %u\n", obj_type);
88 memset(&lp, 0xb0, sizeof(lp));
89 SetLastError(0xdeadbeef);
90 size = GetObject(hpen, sizeof(lp), &lp);
91 ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
93 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
94 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %d\n", pen[i].ret_width, lp.lopnWidth.x);
95 ok(lp.lopnWidth.y == 0, "expected 0, got %d\n", lp.lopnWidth.y);
96 ok(lp.lopnColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, lp.lopnColor);
98 DeleteObject(hpen);
100 /* CreatePen behaviour */
101 SetLastError(0xdeadbeef);
102 hpen = CreatePen(pen[i].style, pen[i].width, pen[i].color);
103 ok(hpen != 0, "CreatePen error %d\n", GetLastError());
105 obj_type = GetObjectType(hpen);
106 ok(obj_type == OBJ_PEN, "wrong object type %u\n", obj_type);
108 /* check what's the real size of the object */
109 size = GetObject(hpen, 0, NULL);
110 ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
112 /* ask for truncated data */
113 memset(&lp, 0xb0, sizeof(lp));
114 SetLastError(0xdeadbeef);
115 size = GetObject(hpen, sizeof(lp.lopnStyle), &lp);
116 ok(!size, "GetObject should fail: size %d, error %d\n", size, GetLastError());
118 /* see how larger buffer sizes are handled */
119 memset(&lp, 0xb0, sizeof(lp));
120 SetLastError(0xdeadbeef);
121 size = GetObject(hpen, sizeof(lp) * 2, &lp);
122 ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
124 /* see how larger buffer sizes are handled */
125 memset(&elp, 0xb0, sizeof(elp));
126 SetLastError(0xdeadbeef);
127 size = GetObject(hpen, sizeof(elp) * 2, &elp);
128 ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
130 memset(&lp, 0xb0, sizeof(lp));
131 SetLastError(0xdeadbeef);
132 size = GetObject(hpen, sizeof(lp), &lp);
133 ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
135 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
136 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %d\n", pen[i].ret_width, lp.lopnWidth.x);
137 ok(lp.lopnWidth.y == 0, "expected 0, got %d\n", lp.lopnWidth.y);
138 ok(lp.lopnColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, lp.lopnColor);
140 memset(&elp, 0xb0, sizeof(elp));
141 SetLastError(0xdeadbeef);
142 size = GetObject(hpen, sizeof(elp), &elp);
144 /* for some reason XP differentiates PS_NULL here */
145 if (pen[i].style == PS_NULL)
147 ok(size == sizeof(EXTLOGPEN), "GetObject returned %d, error %d\n", size, GetLastError());
148 ok(elp.elpPenStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, elp.elpPenStyle);
149 ok(elp.elpWidth == 0, "expected 0, got %u\n", elp.elpWidth);
150 ok(elp.elpColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, elp.elpColor);
151 ok(elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %u\n", elp.elpBrushStyle);
152 ok(elp.elpHatch == 0, "expected 0, got %p\n", (void *)elp.elpHatch);
153 ok(elp.elpNumEntries == 0, "expected 0, got %x\n", elp.elpNumEntries);
155 else
157 ok(size == sizeof(LOGPEN), "GetObject returned %d, error %d\n", size, GetLastError());
158 memcpy(&lp, &elp, sizeof(lp));
159 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
160 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %d\n", pen[i].ret_width, lp.lopnWidth.x);
161 ok(lp.lopnWidth.y == 0, "expected 0, got %d\n", lp.lopnWidth.y);
162 ok(lp.lopnColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, lp.lopnColor);
165 DeleteObject(hpen);
167 /********** cosmetic pens created by ExtCreatePen ***********/
168 lb.lbStyle = BS_SOLID;
169 lb.lbColor = pen[i].color;
170 lb.lbHatch = HS_CROSS; /* just in case */
171 SetLastError(0xdeadbeef);
172 hpen = ExtCreatePen(pen[i].style, pen[i].width, &lb, 2, user_style);
173 if (pen[i].style != PS_USERSTYLE)
175 ok(hpen == 0, "ExtCreatePen should fail\n");
176 ok(GetLastError() == ERROR_INVALID_PARAMETER,
177 "wrong last error value %d\n", GetLastError());
178 SetLastError(0xdeadbeef);
179 hpen = ExtCreatePen(pen[i].style, pen[i].width, &lb, 0, NULL);
180 if (pen[i].style != PS_NULL)
182 ok(hpen == 0, "ExtCreatePen with width != 1 should fail\n");
183 ok(GetLastError() == ERROR_INVALID_PARAMETER,
184 "wrong last error value %d\n", GetLastError());
186 SetLastError(0xdeadbeef);
187 hpen = ExtCreatePen(pen[i].style, 1, &lb, 0, NULL);
190 else
192 ok(hpen == 0, "ExtCreatePen with width != 1 should fail\n");
193 ok(GetLastError() == ERROR_INVALID_PARAMETER,
194 "wrong last error value %d\n", GetLastError());
195 SetLastError(0xdeadbeef);
196 hpen = ExtCreatePen(pen[i].style, 1, &lb, 2, user_style);
198 if (pen[i].style == PS_INSIDEFRAME)
200 /* This style is applicable only for geometric pens */
201 ok(hpen == 0, "ExtCreatePen should fail\n");
202 goto test_geometric_pens;
204 ok(hpen != 0, "ExtCreatePen error %d\n", GetLastError());
206 obj_type = GetObjectType(hpen);
207 /* for some reason XP differentiates PS_NULL here */
208 if (pen[i].style == PS_NULL)
209 ok(obj_type == OBJ_PEN, "wrong object type %u\n", obj_type);
210 else
211 ok(obj_type == OBJ_EXTPEN, "wrong object type %u\n", obj_type);
213 /* check what's the real size of the object */
214 SetLastError(0xdeadbeef);
215 size = GetObject(hpen, 0, NULL);
216 switch (pen[i].style)
218 case PS_NULL:
219 ok(size == sizeof(LOGPEN),
220 "GetObject returned %d, error %d\n", size, GetLastError());
221 break;
223 case PS_USERSTYLE:
224 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
225 "GetObject returned %d, error %d\n", size, GetLastError());
226 break;
228 default:
229 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
230 "GetObject returned %d, error %d\n", size, GetLastError());
231 break;
234 /* ask for truncated data */
235 memset(&elp, 0xb0, sizeof(elp));
236 SetLastError(0xdeadbeef);
237 size = GetObject(hpen, sizeof(elp.elpPenStyle), &elp);
238 ok(!size, "GetObject should fail: size %d, error %d\n", size, GetLastError());
240 /* see how larger buffer sizes are handled */
241 memset(&ext_pen, 0xb0, sizeof(ext_pen));
242 SetLastError(0xdeadbeef);
243 size = GetObject(hpen, sizeof(ext_pen), &ext_pen.elp);
244 switch (pen[i].style)
246 case PS_NULL:
247 ok(size == sizeof(LOGPEN),
248 "GetObject returned %d, error %d\n", size, GetLastError());
249 memcpy(&lp, &ext_pen.elp, sizeof(lp));
250 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
251 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %d\n", pen[i].ret_width, lp.lopnWidth.x);
252 ok(lp.lopnWidth.y == 0, "expected 0, got %d\n", lp.lopnWidth.y);
253 ok(lp.lopnColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, lp.lopnColor);
255 /* for PS_NULL it also works this way */
256 memset(&elp, 0xb0, sizeof(elp));
257 SetLastError(0xdeadbeef);
258 size = GetObject(hpen, sizeof(elp), &elp);
259 ok(size == sizeof(EXTLOGPEN),
260 "GetObject returned %d, error %d\n", size, GetLastError());
261 ok(ext_pen.elp.elpHatch == 0xb0b0b0b0, "expected 0xb0b0b0b0, got %p\n", (void *)ext_pen.elp.elpHatch);
262 ok(ext_pen.elp.elpNumEntries == 0xb0b0b0b0, "expected 0xb0b0b0b0, got %x\n", ext_pen.elp.elpNumEntries);
263 break;
265 case PS_USERSTYLE:
266 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
267 "GetObject returned %d, error %d\n", size, GetLastError());
268 ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
269 ok(ext_pen.elp.elpNumEntries == 2, "expected 0, got %x\n", ext_pen.elp.elpNumEntries);
270 ok(ext_pen.elp.elpStyleEntry[0] == 0xabc, "expected 0xabc, got %x\n", ext_pen.elp.elpStyleEntry[0]);
271 ok(ext_pen.elp.elpStyleEntry[1] == 0xdef, "expected 0xabc, got %x\n", ext_pen.elp.elpStyleEntry[1]);
272 break;
274 default:
275 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
276 "GetObject returned %d, error %d\n", size, GetLastError());
277 ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
278 ok(ext_pen.elp.elpNumEntries == 0, "expected 0, got %x\n", ext_pen.elp.elpNumEntries);
279 break;
282 if (pen[i].style == PS_USERSTYLE)
284 todo_wine
285 ok(ext_pen.elp.elpPenStyle == pen[i].style, "expected %x, got %x\n", pen[i].style, ext_pen.elp.elpPenStyle);
287 else
288 ok(ext_pen.elp.elpPenStyle == pen[i].style, "expected %x, got %x\n", pen[i].style, ext_pen.elp.elpPenStyle);
289 ok(ext_pen.elp.elpWidth == 1, "expected 1, got %x\n", ext_pen.elp.elpWidth);
290 ok(ext_pen.elp.elpColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, ext_pen.elp.elpColor);
291 ok(ext_pen.elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %x\n", ext_pen.elp.elpBrushStyle);
293 DeleteObject(hpen);
295 test_geometric_pens:
296 /********************** geometric pens **********************/
297 lb.lbStyle = BS_SOLID;
298 lb.lbColor = pen[i].color;
299 lb.lbHatch = HS_CROSS; /* just in case */
300 SetLastError(0xdeadbeef);
301 hpen = ExtCreatePen(PS_GEOMETRIC | pen[i].style, pen[i].width, &lb, 2, user_style);
302 if (pen[i].style != PS_USERSTYLE)
304 ok(hpen == 0, "ExtCreatePen should fail\n");
305 SetLastError(0xdeadbeef);
306 hpen = ExtCreatePen(PS_GEOMETRIC | pen[i].style, pen[i].width, &lb, 0, NULL);
308 if (pen[i].style == PS_ALTERNATE)
310 /* This style is applicable only for cosmetic pens */
311 ok(hpen == 0, "ExtCreatePen should fail\n");
312 continue;
314 ok(hpen != 0, "ExtCreatePen error %d\n", GetLastError());
316 obj_type = GetObjectType(hpen);
317 /* for some reason XP differentiates PS_NULL here */
318 if (pen[i].style == PS_NULL)
319 ok(obj_type == OBJ_PEN, "wrong object type %u\n", obj_type);
320 else
321 ok(obj_type == OBJ_EXTPEN, "wrong object type %u\n", obj_type);
323 /* check what's the real size of the object */
324 size = GetObject(hpen, 0, NULL);
325 switch (pen[i].style)
327 case PS_NULL:
328 ok(size == sizeof(LOGPEN),
329 "GetObject returned %d, error %d\n", size, GetLastError());
330 break;
332 case PS_USERSTYLE:
333 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
334 "GetObject returned %d, error %d\n", size, GetLastError());
335 break;
337 default:
338 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
339 "GetObject returned %d, error %d\n", size, GetLastError());
340 break;
343 /* ask for truncated data */
344 memset(&lp, 0xb0, sizeof(lp));
345 SetLastError(0xdeadbeef);
346 size = GetObject(hpen, sizeof(lp.lopnStyle), &lp);
347 ok(!size, "GetObject should fail: size %d, error %d\n", size, GetLastError());
349 memset(&lp, 0xb0, sizeof(lp));
350 SetLastError(0xdeadbeef);
351 size = GetObject(hpen, sizeof(lp), &lp);
352 /* for some reason XP differentiates PS_NULL here */
353 if (pen[i].style == PS_NULL)
355 ok(size == sizeof(LOGPEN), "GetObject returned %d, error %d\n", size, GetLastError());
356 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
357 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %d\n", pen[i].ret_width, lp.lopnWidth.x);
358 ok(lp.lopnWidth.y == 0, "expected 0, got %d\n", lp.lopnWidth.y);
359 ok(lp.lopnColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, lp.lopnColor);
361 else
362 /* XP doesn't set last error here */
363 ok(!size /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
364 "GetObject should fail: size %d, error %d\n", size, GetLastError());
366 memset(&ext_pen, 0xb0, sizeof(ext_pen));
367 SetLastError(0xdeadbeef);
368 /* buffer is too small for user styles */
369 size = GetObject(hpen, sizeof(elp), &ext_pen.elp);
370 switch (pen[i].style)
372 case PS_NULL:
373 ok(size == sizeof(EXTLOGPEN),
374 "GetObject returned %d, error %d\n", size, GetLastError());
375 ok(ext_pen.elp.elpHatch == 0, "expected 0, got %p\n", (void *)ext_pen.elp.elpHatch);
376 ok(ext_pen.elp.elpNumEntries == 0, "expected 0, got %x\n", ext_pen.elp.elpNumEntries);
378 /* for PS_NULL it also works this way */
379 SetLastError(0xdeadbeef);
380 size = GetObject(hpen, sizeof(ext_pen), &lp);
381 ok(size == sizeof(LOGPEN),
382 "GetObject returned %d, error %d\n", size, GetLastError());
383 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
384 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %d\n", pen[i].ret_width, lp.lopnWidth.x);
385 ok(lp.lopnWidth.y == 0, "expected 0, got %d\n", lp.lopnWidth.y);
386 ok(lp.lopnColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, lp.lopnColor);
387 break;
389 case PS_USERSTYLE:
390 ok(!size /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
391 "GetObject should fail: size %d, error %d\n", size, GetLastError());
392 size = GetObject(hpen, sizeof(ext_pen), &ext_pen.elp);
393 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
394 "GetObject returned %d, error %d\n", size, GetLastError());
395 ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
396 ok(ext_pen.elp.elpNumEntries == 2, "expected 0, got %x\n", ext_pen.elp.elpNumEntries);
397 ok(ext_pen.elp.elpStyleEntry[0] == 0xabc, "expected 0xabc, got %x\n", ext_pen.elp.elpStyleEntry[0]);
398 ok(ext_pen.elp.elpStyleEntry[1] == 0xdef, "expected 0xabc, got %x\n", ext_pen.elp.elpStyleEntry[1]);
399 break;
401 default:
402 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
403 "GetObject returned %d, error %d\n", size, GetLastError());
404 ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
405 ok(ext_pen.elp.elpNumEntries == 0, "expected 0, got %x\n", ext_pen.elp.elpNumEntries);
406 break;
409 /* for some reason XP differentiates PS_NULL here */
410 if (pen[i].style == PS_NULL)
411 ok(ext_pen.elp.elpPenStyle == pen[i].ret_style, "expected %x, got %x\n", pen[i].ret_style, ext_pen.elp.elpPenStyle);
412 else
414 ok(ext_pen.elp.elpPenStyle == (PS_GEOMETRIC | pen[i].style), "expected %x, got %x\n", PS_GEOMETRIC | pen[i].style, ext_pen.elp.elpPenStyle);
417 if (pen[i].style == PS_NULL)
418 ok(ext_pen.elp.elpWidth == 0, "expected 0, got %x\n", ext_pen.elp.elpWidth);
419 else
420 ok(ext_pen.elp.elpWidth == pen[i].ret_width, "expected %u, got %x\n", pen[i].ret_width, ext_pen.elp.elpWidth);
421 ok(ext_pen.elp.elpColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, ext_pen.elp.elpColor);
422 ok(ext_pen.elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %x\n", ext_pen.elp.elpBrushStyle);
424 DeleteObject(hpen);
428 static unsigned int atoi2(const char *s)
430 unsigned int ret = 0;
431 while(*s) ret = (ret << 1) | (*s++ == '1');
432 return ret;
435 #define TEST_LINE(x1, x2, z) \
436 { int buf = 0; \
437 SetBitmapBits(bmp, sizeof(buf), &buf); \
438 MoveToEx(hdc, x1, 0, NULL); \
439 LineTo(hdc, x2, 0); \
440 GetBitmapBits(bmp, sizeof(buf), &buf); \
441 expect(atoi2(z), buf); }
443 static void test_ps_alternate(void)
445 HDC hdc;
446 HBITMAP bmp;
447 HPEN pen;
448 LOGBRUSH lb;
450 lb.lbStyle = BS_SOLID;
451 lb.lbColor = RGB(0xff,0xff,0xff);
453 SetLastError(0xdeadbeef);
454 pen = ExtCreatePen(PS_COSMETIC|PS_ALTERNATE, 1, &lb, 0, NULL);
455 if(pen == NULL && GetLastError() == 0xdeadbeef) {
456 skip("looks like 9x, skipping PS_ALTERNATE tests\n");
457 return;
459 ok(pen != NULL, "gle=%d\n", GetLastError());
460 hdc = CreateCompatibleDC(NULL);
461 ok(hdc != NULL, "gle=%d\n", GetLastError());
462 bmp = CreateBitmap(8, 1, 1, 1, NULL);
463 ok(bmp != NULL, "gle=%d\n", GetLastError());
464 ok(SelectObject(hdc, bmp) != NULL, "gle=%d\n", GetLastError());
465 ok(SelectObject(hdc, pen) != NULL, "gle=%d\n", GetLastError());
466 ok(SetBkMode(hdc, TRANSPARENT), "gle=%d\n", GetLastError());
468 TEST_LINE(0, 1, "10000000")
469 TEST_LINE(0, 2, "10000000")
470 TEST_LINE(0, 3, "10100000")
471 TEST_LINE(0, 4, "10100000")
472 TEST_LINE(1, 4, "01010000")
473 TEST_LINE(1, 5, "01010000")
474 TEST_LINE(4, 8, "00001010")
476 DeleteObject(pen);
477 DeleteObject(bmp);
478 DeleteDC(hdc);
481 static void test_ps_userstyle(void)
483 static DWORD style[17] = {0, 2, 0, 4, 5, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 17};
484 static DWORD bad_style[5] = {0, 0, 0, 0, 0};
485 static DWORD bad_style2[5] = {4, 7, 8, 3, -1};
487 LOGBRUSH lb;
488 HPEN pen;
489 INT size, i;
491 struct
493 EXTLOGPEN elp;
494 DWORD style_data[15];
495 } ext_pen;
497 lb.lbColor = 0x00ff0000;
498 lb.lbStyle = BS_SOLID;
499 lb.lbHatch = 0;
501 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 3, NULL);
502 ok(pen == 0, "ExtCreatePen should fail\n");
503 expect(ERROR_INVALID_PARAMETER, GetLastError());
504 DeleteObject(pen);
505 SetLastError(0xdeadbeef);
507 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 0, style);
508 ok(pen == 0, "ExtCreatePen should fail\n");
509 expect2(0xdeadbeef, ERROR_INVALID_PARAMETER, GetLastError());
510 DeleteObject(pen);
511 SetLastError(0xdeadbeef);
513 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 17, style);
514 ok(pen == 0, "ExtCreatePen should fail\n");
515 expect(ERROR_INVALID_PARAMETER, GetLastError());
516 DeleteObject(pen);
517 SetLastError(0xdeadbeef);
519 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, -1, style);
520 ok(pen == 0, "ExtCreatePen should fail\n");
521 expect(0xdeadbeef, GetLastError());
522 DeleteObject(pen);
523 SetLastError(0xdeadbeef);
525 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 5, bad_style);
526 ok(pen == 0, "ExtCreatePen should fail\n");
527 expect(ERROR_INVALID_PARAMETER, GetLastError());
528 DeleteObject(pen);
529 SetLastError(0xdeadbeef);
531 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 5, bad_style2);
532 ok(pen == 0, "ExtCreatePen should fail\n");
533 expect(ERROR_INVALID_PARAMETER, GetLastError());
534 DeleteObject(pen);
535 SetLastError(0xdeadbeef);
537 pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 16, style);
538 ok(pen != 0, "ExtCreatePen should not fail\n");
540 size = GetObject(pen, sizeof(ext_pen), &ext_pen);
541 expect(88, size);
543 for(i = 0; i < 16; i++)
544 expect(style[i], ext_pen.elp.elpStyleEntry[i]);
546 DeleteObject(pen);
549 START_TEST(pen)
551 test_logpen();
552 test_ps_alternate();
553 test_ps_userstyle();