source: trunk/src/user32/uitools.cpp@ 2560

Last change on this file since 2560 was 2560, checked in by sandervl, 26 years ago

Call DrawTextA in uitools.cpp, not Open32's DrawText.

File size: 66.4 KB
Line 
1/* $Id: uitools.cpp,v 1.22 2000-01-29 14:23:33 sandervl Exp $ */
2/*
3 * User Interface Functions
4 *
5 * Copyright 1997 Dimitrie O. Paun
6 * Copyright 1997 Bertho A. Stultiens
7 * Copyright 1999 Achim Hasenmueller
8 * Copyright 1999 Christoph Bratschi
9 * Copyright 1999 Rene Pronk
10 *
11 * WINE version: 990923
12 */
13
14#include "winuser.h"
15#include "user32.h"
16#include "win32wbase.h"
17
18static const WORD wPattern_AA55[8] = { 0xaaaa, 0x5555, 0xaaaa, 0x5555,
19 0xaaaa, 0x5555, 0xaaaa, 0x5555 };
20
21/* These tables are used in:
22 * UITOOLS_DrawDiagEdge()
23 * UITOOLS_DrawRectEdge()
24 */
25static const char LTInnerNormal[] = {
26 -1, -1, -1, -1,
27 -1, COLOR_BTNHIGHLIGHT, COLOR_BTNHIGHLIGHT, -1,
28 -1, COLOR_3DDKSHADOW, COLOR_3DDKSHADOW, -1,
29 -1, -1, -1, -1
30};
31
32static const char LTOuterNormal[] = {
33 -1, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1,
34 COLOR_BTNHIGHLIGHT, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1,
35 COLOR_3DDKSHADOW, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1,
36 -1, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1
37};
38
39static const char RBInnerNormal[] = {
40 -1, -1, -1, -1,
41 -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, -1,
42 -1, COLOR_3DLIGHT, COLOR_3DLIGHT, -1,
43 -1, -1, -1, -1
44};
45
46static const char RBOuterNormal[] = {
47 -1, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1,
48 COLOR_BTNSHADOW, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1,
49 COLOR_3DLIGHT, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1,
50 -1, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1
51};
52
53static const char LTInnerSoft[] = {
54 -1, -1, -1, -1,
55 -1, COLOR_3DLIGHT, COLOR_3DLIGHT, -1,
56 -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, -1,
57 -1, -1, -1, -1
58};
59
60static const char LTOuterSoft[] = {
61 -1, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1,
62 COLOR_3DLIGHT, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1,
63 COLOR_BTNSHADOW, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1,
64 -1, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1
65};
66
67#define RBInnerSoft RBInnerNormal /* These are the same */
68#define RBOuterSoft RBOuterNormal
69
70static const char LTRBOuterMono[] = {
71 -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
72 COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
73 COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
74 COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
75};
76
77static const char LTRBInnerMono[] = {
78 -1, -1, -1, -1,
79 -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW,
80 -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW,
81 -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW,
82};
83
84static const char LTRBOuterFlat[] = {
85 -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW,
86 COLOR_WINDOWFRAME, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW,
87 COLOR_WINDOWFRAME, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW,
88 COLOR_WINDOWFRAME, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW,
89};
90
91static const char LTRBInnerFlat[] = {
92 -1, -1, -1, -1,
93 -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
94 -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
95 -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
96};
97
98/***********************************************************************
99 * UITOOLS_DrawDiagEdge
100 *
101 * Same as DrawEdge invoked with BF_DIAGONAL
102 *
103 * 03-Dec-1997: Changed by Bertho Stultiens
104 *
105 * See also comments with UITOOLS_DrawRectEdge()
106 */
107static BOOL UITOOLS95_DrawDiagEdge(HDC hdc, LPRECT rc,
108 UINT uType, UINT uFlags)
109{
110 POINT Points[4];
111 char InnerI, OuterI;
112 HPEN InnerPen, OuterPen;
113 POINT SavePoint;
114 HPEN SavePen;
115 int spx, spy;
116 int epx, epy;
117 int Width = rc->right - rc->left;
118 int Height= rc->bottom - rc->top;
119 int SmallDiam = Width > Height ? Height : Width;
120 BOOL retval = !( ((uType & BDR_INNER) == BDR_INNER
121 || (uType & BDR_OUTER) == BDR_OUTER)
122 && !(uFlags & (BF_FLAT|BF_MONO)) );
123 int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0)
124 + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0);
125
126 if (IsRectEmpty(rc)) return retval; //nothing to do
127
128 /* Init some vars */
129 OuterPen = InnerPen = (HPEN)GetStockObject(NULL_PEN);
130 SavePen = (HPEN)SelectObject(hdc, InnerPen);
131 spx = spy = epx = epy = 0; /* Satisfy the compiler... */
132
133 /* Determine the colors of the edges */
134 if(uFlags & BF_MONO)
135 {
136 InnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)];
137 OuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)];
138 }
139 else if(uFlags & BF_FLAT)
140 {
141 InnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)];
142 OuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)];
143 }
144 else if(uFlags & BF_SOFT)
145 {
146 if(uFlags & BF_BOTTOM)
147 {
148 InnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
149 OuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
150 }
151 else
152 {
153 InnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
154 OuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
155 }
156 }
157 else
158 {
159 if(uFlags & BF_BOTTOM)
160 {
161 InnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
162 OuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
163 }
164 else
165 {
166 InnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
167 OuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
168 }
169 }
170
171 if(InnerI != -1) InnerPen = GetSysColorPen(InnerI);
172 if(OuterI != -1) OuterPen = GetSysColorPen(OuterI);
173
174 MoveToEx(hdc, 0, 0, &SavePoint);
175
176 /* Don't ask me why, but this is what is visible... */
177 /* This must be possible to do much simpler, but I fail to */
178 /* see the logic in the MS implementation (sigh...). */
179 /* So, this might look a bit brute force here (and it is), but */
180 /* it gets the job done;) */
181
182 switch(uFlags & BF_RECT)
183 {
184 case 0:
185 case BF_LEFT:
186 case BF_BOTTOM:
187 case BF_BOTTOMLEFT:
188 /* Left bottom endpoint */
189 epx = rc->left-1;
190 spx = epx + SmallDiam;
191 epy = rc->bottom;
192 spy = epy - SmallDiam;
193 break;
194
195 case BF_TOPLEFT:
196 case BF_BOTTOMRIGHT:
197 /* Left top endpoint */
198 epx = rc->left-1;
199 spx = epx + SmallDiam;
200 epy = rc->top-1;
201 spy = epy + SmallDiam;
202 break;
203
204 case BF_TOP:
205 case BF_RIGHT:
206 case BF_TOPRIGHT:
207 case BF_RIGHT|BF_LEFT:
208 case BF_RIGHT|BF_LEFT|BF_TOP:
209 case BF_BOTTOM|BF_TOP:
210 case BF_BOTTOM|BF_TOP|BF_LEFT:
211 case BF_BOTTOMRIGHT|BF_LEFT:
212 case BF_BOTTOMRIGHT|BF_TOP:
213 case BF_RECT:
214 /* Right top endpoint */
215 spx = rc->left;
216 epx = spx + SmallDiam;
217 spy = rc->bottom-1;
218 epy = spy - SmallDiam;
219 break;
220 }
221
222 MoveToEx(hdc, spx, spy, NULL);
223 SelectObject(hdc, OuterPen);
224 LineTo(hdc, epx, epy);
225
226 SelectObject(hdc, InnerPen);
227
228 switch(uFlags & (BF_RECT|BF_DIAGONAL))
229 {
230 case BF_DIAGONAL_ENDBOTTOMLEFT:
231 case (BF_DIAGONAL|BF_BOTTOM):
232 case BF_DIAGONAL:
233 case (BF_DIAGONAL|BF_LEFT):
234 MoveToEx(hdc, spx-1, spy, NULL);
235 LineTo(hdc, epx, epy-1);
236 Points[0].x = spx-add;
237 Points[0].y = spy;
238 Points[1].x = rc->left;
239 Points[1].y = rc->top;
240 Points[2].x = epx+1;
241 Points[2].y = epy-1-add;
242 Points[3] = Points[2];
243 break;
244
245 case BF_DIAGONAL_ENDBOTTOMRIGHT:
246 MoveToEx(hdc, spx-1, spy, NULL);
247 LineTo(hdc, epx, epy+1);
248 Points[0].x = spx-add;
249 Points[0].y = spy;
250 Points[1].x = rc->left;
251 Points[1].y = rc->bottom-1;
252 Points[2].x = epx+1;
253 Points[2].y = epy+1+add;
254 Points[3] = Points[2];
255 break;
256
257 case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP):
258 case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP|BF_LEFT):
259 case BF_DIAGONAL_ENDTOPRIGHT:
260 case (BF_DIAGONAL|BF_RIGHT|BF_TOP|BF_LEFT):
261 MoveToEx(hdc, spx+1, spy, NULL);
262 LineTo(hdc, epx, epy+1);
263 Points[0].x = epx-1;
264 Points[0].y = epy+1+add;
265 Points[1].x = rc->right-1;
266 Points[1].y = rc->top+add;
267 Points[2].x = rc->right-1;
268 Points[2].y = rc->bottom-1;
269 Points[3].x = spx+add;
270 Points[3].y = spy;
271 break;
272
273 case BF_DIAGONAL_ENDTOPLEFT:
274 MoveToEx(hdc, spx, spy-1, NULL);
275 LineTo(hdc, epx+1, epy);
276 Points[0].x = epx+1+add;
277 Points[0].y = epy+1;
278 Points[1].x = rc->right-1;
279 Points[1].y = rc->top;
280 Points[2].x = rc->right-1;
281 Points[2].y = rc->bottom-1-add;
282 Points[3].x = spx;
283 Points[3].y = spy-add;
284 break;
285
286 case (BF_DIAGONAL|BF_TOP):
287 case (BF_DIAGONAL|BF_BOTTOM|BF_TOP):
288 case (BF_DIAGONAL|BF_BOTTOM|BF_TOP|BF_LEFT):
289 MoveToEx(hdc, spx+1, spy-1, NULL);
290 LineTo(hdc, epx, epy);
291 Points[0].x = epx-1;
292 Points[0].y = epy+1;
293 Points[1].x = rc->right-1;
294 Points[1].y = rc->top;
295 Points[2].x = rc->right-1;
296 Points[2].y = rc->bottom-1-add;
297 Points[3].x = spx+add;
298 Points[3].y = spy-add;
299 break;
300
301 case (BF_DIAGONAL|BF_RIGHT):
302 case (BF_DIAGONAL|BF_RIGHT|BF_LEFT):
303 case (BF_DIAGONAL|BF_RIGHT|BF_LEFT|BF_BOTTOM):
304 MoveToEx(hdc, spx, spy, NULL);
305 LineTo(hdc, epx-1, epy+1);
306 Points[0].x = spx;
307 Points[0].y = spy;
308 Points[1].x = rc->left;
309 Points[1].y = rc->top+add;
310 Points[2].x = epx-1-add;
311 Points[2].y = epy+1+add;
312 Points[3] = Points[2];
313 break;
314 }
315
316 /* Fill the interior if asked */
317 if((uFlags & BF_MIDDLE) && retval)
318 {
319 HBRUSH hbsave;
320 HBRUSH hb = GetSysColorBrush(uFlags & BF_MONO ? COLOR_WINDOW
321 :COLOR_BTNFACE);
322 HPEN hpsave;
323 HPEN hp = GetSysColorPen(uFlags & BF_MONO ? COLOR_WINDOW
324 : COLOR_BTNFACE);
325 hbsave = (HBRUSH)SelectObject(hdc, hb);
326 hpsave = (HPEN)SelectObject(hdc, hp);
327 Polygon(hdc, Points, 4);
328 SelectObject(hdc, hbsave);
329 SelectObject(hdc, hpsave);
330 }
331
332 /* Adjust rectangle if asked */
333 if(uFlags & BF_ADJUST)
334 {
335 if(uFlags & BF_LEFT) rc->left += add;
336 if(uFlags & BF_RIGHT) rc->right -= add;
337 if(uFlags & BF_TOP) rc->top += add;
338 if(uFlags & BF_BOTTOM) rc->bottom -= add;
339 }
340
341 /* Cleanup */
342 SelectObject(hdc, SavePen);
343 MoveToEx(hdc, SavePoint.x, SavePoint.y, NULL);
344
345 return retval;
346}
347
348/***********************************************************************
349 * UITOOLS_DrawRectEdge
350 *
351 * Same as DrawEdge invoked without BF_DIAGONAL
352 *
353 * 23-Nov-1997: Changed by Bertho Stultiens
354 *
355 * Well, I started testing this and found out that there are a few things
356 * that weren't quite as win95. The following rewrite should reproduce
357 * win95 results completely.
358 * The colorselection is table-driven to avoid awfull if-statements.
359 * The table below show the color settings.
360 *
361 * Pen selection table for uFlags = 0
362 *
363 * uType | LTI | LTO | RBI | RBO
364 * ------+-------+-------+-------+-------
365 * 0000 | x | x | x | x
366 * 0001 | x | 22 | x | 21
367 * 0010 | x | 16 | x | 20
368 * 0011 | x | x | x | x
369 * ------+-------+-------+-------+-------
370 * 0100 | x | 20 | x | 16
371 * 0101 | 20 | 22 | 16 | 21
372 * 0110 | 20 | 16 | 16 | 20
373 * 0111 | x | x | x | x
374 * ------+-------+-------+-------+-------
375 * 1000 | x | 21 | x | 22
376 * 1001 | 21 | 22 | 22 | 21
377 * 1010 | 21 | 16 | 22 | 20
378 * 1011 | x | x | x | x
379 * ------+-------+-------+-------+-------
380 * 1100 | x | x | x | x
381 * 1101 | x | x (22)| x | x (21)
382 * 1110 | x | x (16)| x | x (20)
383 * 1111 | x | x | x | x
384 *
385 * Pen selection table for uFlags = BF_SOFT
386 *
387 * uType | LTI | LTO | RBI | RBO
388 * ------+-------+-------+-------+-------
389 * 0000 | x | x | x | x
390 * 0001 | x | 20 | x | 21
391 * 0010 | x | 21 | x | 20
392 * 0011 | x | x | x | x
393 * ------+-------+-------+-------+-------
394 * 0100 | x | 22 | x | 16
395 * 0101 | 22 | 20 | 16 | 21
396 * 0110 | 22 | 21 | 16 | 20
397 * 0111 | x | x | x | x
398 * ------+-------+-------+-------+-------
399 * 1000 | x | 16 | x | 22
400 * 1001 | 16 | 20 | 22 | 21
401 * 1010 | 16 | 21 | 22 | 20
402 * 1011 | x | x | x | x
403 * ------+-------+-------+-------+-------
404 * 1100 | x | x | x | x
405 * 1101 | x | x (20)| x | x (21)
406 * 1110 | x | x (21)| x | x (20)
407 * 1111 | x | x | x | x
408 *
409 * x = don't care; (n) = is what win95 actually uses
410 * LTI = left Top Inner line
411 * LTO = left Top Outer line
412 * RBI = Right Bottom Inner line
413 * RBO = Right Bottom Outer line
414 * 15 = COLOR_BTNFACE
415 * 16 = COLOR_BTNSHADOW
416 * 20 = COLOR_BTNHIGHLIGHT
417 * 21 = COLOR_3DDKSHADOW
418 * 22 = COLOR_3DLIGHT
419 */
420
421
422static BOOL UITOOLS95_DrawRectEdge(HDC hdc, LPRECT rc,
423 UINT uType, UINT uFlags)
424{
425 char LTInnerI, LTOuterI;
426 char RBInnerI, RBOuterI;
427 HPEN LTInnerPen, LTOuterPen;
428 HPEN RBInnerPen, RBOuterPen;
429 RECT InnerRect = *rc;
430 POINT SavePoint;
431 HPEN SavePen;
432 int LBpenplus = 0;
433 int LTpenplus = 0;
434 int RTpenplus = 0;
435 int RBpenplus = 0;
436 BOOL retval = !( ((uType & BDR_INNER) == BDR_INNER
437 || (uType & BDR_OUTER) == BDR_OUTER)
438 && !(uFlags & (BF_FLAT|BF_MONO)) );
439
440 if (IsRectEmpty(rc)) return retval; //nothing to do
441
442 /* Init some vars */
443 LTInnerPen = LTOuterPen = RBInnerPen = RBOuterPen = (HPEN)GetStockObject(NULL_PEN);
444 SavePen = (HPEN)SelectObject(hdc, LTInnerPen);
445
446 /* Determine the colors of the edges */
447 if(uFlags & BF_MONO)
448 {
449 LTInnerI = RBInnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)];
450 LTOuterI = RBOuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)];
451 }
452 else if(uFlags & BF_FLAT)
453 {
454 LTInnerI = RBInnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)];
455 LTOuterI = RBOuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)];
456
457 /* Bertho Stultiens states above that this function exactly matches win95
458 * In win98 BF_FLAT rectangels have an inner border same color as the
459 * middle (COLOR_BTNFACE). I believe it's the same for win95 but since
460 * I don't know I go with Bertho and just sets it for win98 until proven
461 * otherwise.
462 * Dennis Björklund, 10 June, 99
463 */
464 if(LTInnerI != -1 )
465 LTInnerI = RBInnerI = COLOR_BTNFACE;
466 }
467 else if(uFlags & BF_SOFT)
468 {
469 LTInnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
470 LTOuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
471 RBInnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
472 RBOuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
473 }
474 else
475 {
476 LTInnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
477 LTOuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
478 RBInnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
479 RBOuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
480 }
481
482 if((uFlags & BF_BOTTOMLEFT) == BF_BOTTOMLEFT) LBpenplus = 1;
483 if((uFlags & BF_TOPRIGHT) == BF_TOPRIGHT) RTpenplus = 1;
484 if((uFlags & BF_BOTTOMRIGHT) == BF_BOTTOMRIGHT) RBpenplus = 1;
485 if((uFlags & BF_TOPLEFT) == BF_TOPLEFT) LTpenplus = 1;
486
487 if(LTInnerI != -1) LTInnerPen = GetSysColorPen(LTInnerI);
488 if(LTOuterI != -1) LTOuterPen = GetSysColorPen(LTOuterI);
489 if(RBInnerI != -1) RBInnerPen = GetSysColorPen(RBInnerI);
490 if(RBOuterI != -1) RBOuterPen = GetSysColorPen(RBOuterI);
491
492 MoveToEx(hdc, 0, 0, &SavePoint);
493
494 /* Draw the outer edge */
495 SelectObject(hdc, LTOuterPen);
496 if(uFlags & BF_TOP)
497 {
498 MoveToEx(hdc, InnerRect.left, InnerRect.top, NULL);
499 LineTo(hdc, InnerRect.right, InnerRect.top);
500 }
501 if(uFlags & BF_LEFT)
502 {
503 MoveToEx(hdc, InnerRect.left, InnerRect.top, NULL);
504 LineTo(hdc, InnerRect.left, InnerRect.bottom);
505 }
506
507 SelectObject(hdc, RBOuterPen);
508 if(uFlags & BF_BOTTOM)
509 {
510 MoveToEx(hdc, InnerRect.right-1, InnerRect.bottom-1, NULL);
511 LineTo(hdc, InnerRect.left-1, InnerRect.bottom-1);
512 }
513 if(uFlags & BF_RIGHT)
514 {
515 MoveToEx(hdc, InnerRect.right-1, InnerRect.bottom-1, NULL);
516 LineTo(hdc, InnerRect.right-1, InnerRect.top-1);
517 }
518
519 /* Draw the inner edge */
520 SelectObject(hdc, LTInnerPen);
521 if(uFlags & BF_TOP)
522 {
523 MoveToEx(hdc, InnerRect.left+LTpenplus, InnerRect.top+1, NULL);
524 LineTo(hdc, InnerRect.right-RTpenplus, InnerRect.top+1);
525 }
526 if(uFlags & BF_LEFT)
527 {
528 MoveToEx(hdc, InnerRect.left+1, InnerRect.top+LTpenplus, NULL);
529 LineTo(hdc, InnerRect.left+1, InnerRect.bottom-LBpenplus);
530 }
531 SelectObject(hdc, RBInnerPen);
532 if(uFlags & BF_BOTTOM)
533 {
534 MoveToEx(hdc, InnerRect.right-1-RBpenplus, InnerRect.bottom-2, NULL);
535 LineTo(hdc, InnerRect.left-1+LBpenplus, InnerRect.bottom-2);
536 }
537 if(uFlags & BF_RIGHT)
538 {
539 MoveToEx(hdc, InnerRect.right-2, InnerRect.bottom-1-RBpenplus, NULL);
540 LineTo(hdc, InnerRect.right-2, InnerRect.top-1+RTpenplus);
541 }
542
543 if( ((uFlags & BF_MIDDLE) && retval) || (uFlags & BF_ADJUST) )
544 {
545 int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0)
546 + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0);
547
548 if(uFlags & BF_LEFT) InnerRect.left += add;
549 if(uFlags & BF_RIGHT) InnerRect.right -= add;
550 if(uFlags & BF_TOP) InnerRect.top += add;
551 if(uFlags & BF_BOTTOM) InnerRect.bottom -= add;
552
553 if((uFlags & BF_MIDDLE) && retval)
554 {
555 FillRect(hdc, &InnerRect, GetSysColorBrush(uFlags & BF_MONO ?
556 COLOR_WINDOW : COLOR_BTNFACE));
557 }
558
559 if(uFlags & BF_ADJUST)
560 *rc = InnerRect;
561 }
562
563 /* Cleanup */
564 SelectObject(hdc, SavePen);
565 MoveToEx(hdc, SavePoint.x, SavePoint.y, NULL);
566 return retval;
567}
568
569
570//**********************************************************************
571// DrawEdge (USER32.155)
572//
573BOOL WIN32API DrawEdge(HDC hdc, LPRECT rc, UINT edge, UINT flags)
574{
575
576 if (flags & BF_DIAGONAL)
577 return UITOOLS95_DrawDiagEdge(hdc, rc, edge, flags);
578 else
579 return UITOOLS95_DrawRectEdge(hdc, rc, edge, flags);
580}
581
582/************************************************************************
583 * UITOOLS_MakeSquareRect
584 *
585 * Utility to create a square rectangle and returning the width
586 */
587static int UITOOLS_MakeSquareRect(LPRECT src, LPRECT dst)
588{
589 int Width = src->right - src->left;
590 int Height = src->bottom - src->top;
591 int SmallDiam = Width > Height ? Height : Width;
592
593 *dst = *src;
594
595 /* Make it a square box */
596 if(Width < Height) /* SmallDiam == Width */
597 {
598 dst->top += (Height-Width)/2;
599 dst->bottom = dst->top + SmallDiam;
600 }
601 else if(Width > Height) /* SmallDiam == Height */
602 {
603 dst->left += (Width-Height)/2;
604 dst->right = dst->left + SmallDiam;
605 }
606
607 return SmallDiam;
608}
609
610
611static void UITOOLS_DrawCheckedRect( HDC dc, LPRECT rect )
612{
613 if(GetSysColor(COLOR_BTNHIGHLIGHT) == RGB(255, 255, 255))
614 {
615 HBITMAP hbm = CreateBitmap(8, 8, 1, 1, wPattern_AA55);
616 HBRUSH hbsave;
617 HBRUSH hb = CreatePatternBrush(hbm);
618 COLORREF bg;
619
620 FillRect(dc, rect, GetSysColorBrush(COLOR_BTNFACE));
621 bg = SetBkColor(dc, RGB(255, 255, 255));
622 hbsave = (HBRUSH)SelectObject(dc, hb);
623 PatBlt(dc, rect->left, rect->top, rect->right-rect->left, rect->bottom-rect->top, 0x00FA0089);
624 SelectObject(dc, hbsave);
625 SetBkColor(dc, bg);
626 DeleteObject(hb);
627 DeleteObject(hbm);
628 }
629 else
630 {
631 FillRect(dc, rect, GetSysColorBrush(COLOR_BTNHIGHLIGHT));
632 }
633}
634
635/************************************************************************
636 * UITOOLS_DFC_ButtonPush
637 *
638 * Draw a push button coming from DrawFrameControl()
639 *
640 * Does a pretty good job in emulating MS behavior. Some quirks are
641 * however there because MS uses a TrueType font (Marlett) to draw
642 * the buttons.
643 */
644static BOOL UITOOLS95_DFC_ButtonPush(HDC dc, LPRECT r, UINT uFlags)
645{
646 UINT edge;
647 RECT myr = *r;
648
649 if(uFlags & (DFCS_PUSHED | DFCS_CHECKED | DFCS_FLAT))
650 edge = EDGE_SUNKEN;
651 else
652 edge = EDGE_RAISED;
653
654 if(uFlags & DFCS_CHECKED)
655 {
656 if(uFlags & DFCS_MONO)
657 UITOOLS95_DrawRectEdge(dc, &myr, edge, BF_MONO|BF_RECT|BF_ADJUST);
658 else
659 UITOOLS95_DrawRectEdge(dc, &myr, edge, (uFlags&DFCS_FLAT)|BF_RECT|BF_SOFT|BF_ADJUST);
660
661 UITOOLS_DrawCheckedRect( dc, &myr );
662 }
663 else
664 {
665 if(uFlags & DFCS_MONO)
666 {
667 UITOOLS95_DrawRectEdge(dc, &myr, edge, BF_MONO|BF_RECT|BF_ADJUST);
668 FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNFACE));
669 }
670 else
671 {
672 UITOOLS95_DrawRectEdge(dc, r, edge, (uFlags&DFCS_FLAT) | BF_MIDDLE |BF_SOFT| BF_RECT);
673 }
674 }
675
676 /* Adjust rectangle if asked */
677 if(uFlags & DFCS_ADJUSTRECT)
678 {
679 r->left += 2;
680 r->right -= 2;
681 r->top += 2;
682 r->bottom -= 2;
683 }
684
685 return TRUE;
686}
687
688
689/************************************************************************
690 * UITOOLS_DFC_ButtonCheck
691 *
692 * Draw a check/3state button coming from DrawFrameControl()
693 *
694 * Does a pretty good job in emulating MS behavior. Some quirks are
695 * however there because MS uses a TrueType font (Marlett) to draw
696 * the buttons.
697 */
698#define DFC_CHECKPOINTSMAX 6
699
700static BOOL UITOOLS95_DFC_ButtonCheck(HDC dc, LPRECT r, UINT uFlags)
701{
702 RECT myr;
703 int SmallDiam = UITOOLS_MakeSquareRect(r, &myr);
704 UINT flags = BF_RECT | BF_ADJUST;
705
706 if(uFlags & DFCS_FLAT) flags |= BF_FLAT;
707 else if(uFlags & DFCS_MONO) flags |= BF_MONO;
708
709 UITOOLS95_DrawRectEdge( dc, &myr, EDGE_SUNKEN, flags );
710
711 if(uFlags & (DFCS_INACTIVE|DFCS_PUSHED))
712 FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNFACE));
713 else if( (uFlags & DFCS_BUTTON3STATE) && (uFlags & DFCS_CHECKED) )
714 UITOOLS_DrawCheckedRect( dc, &myr );
715 else
716 {
717 FillRect(dc, &myr, GetSysColorBrush(COLOR_WINDOW));
718 }
719
720 if(uFlags & DFCS_CHECKED)
721 {
722 POINT CheckPoints[DFC_CHECKPOINTSMAX];
723 int i;
724 HBRUSH hbsave;
725 HPEN hpsave;
726
727 /* FIXME: This comes very close to M$'s checkmark, but not */
728 /* exactly... When small or large there is a few pixels */
729 /* shift. Not bad, but could be better :) */
730 UITOOLS_MakeSquareRect(r, &myr);
731 CheckPoints[0].x = myr.left + 253*SmallDiam/1000;
732 CheckPoints[0].y = myr.top + 345*SmallDiam/1000;
733 CheckPoints[1].x = myr.left + 409*SmallDiam/1000;
734 CheckPoints[1].y = CheckPoints[0].y + (CheckPoints[1].x-CheckPoints[0].x);
735 CheckPoints[2].x = myr.left + 690*SmallDiam/1000;
736 CheckPoints[2].y = CheckPoints[1].y - (CheckPoints[2].x-CheckPoints[1].x);
737 CheckPoints[3].x = CheckPoints[2].x;
738 CheckPoints[3].y = CheckPoints[2].y + 3*SmallDiam/16;
739 CheckPoints[4].x = CheckPoints[1].x;
740 CheckPoints[4].y = CheckPoints[1].y + 3*SmallDiam/16;
741 CheckPoints[5].x = CheckPoints[0].x;
742 CheckPoints[5].y = CheckPoints[0].y + 3*SmallDiam/16;
743
744 i = (uFlags & DFCS_INACTIVE) || (uFlags & 0xff) == DFCS_BUTTON3STATE ? COLOR_BTNSHADOW : COLOR_WINDOWTEXT;
745 hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i));
746 hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i));
747 Polygon(dc, CheckPoints, DFC_CHECKPOINTSMAX);
748 SelectObject(dc, hpsave);
749 SelectObject(dc, hbsave);
750 }
751 return TRUE;
752}
753
754
755/************************************************************************
756 * UITOOLS_DFC_ButtonRadio
757 *
758 * Draw a radio/radioimage/radiomask button coming from DrawFrameControl()
759 *
760 * Does a pretty good job in emulating MS behavior. Some quirks are
761 * however there because MS uses a TrueType font (Marlett) to draw
762 * the buttons.
763 */
764static BOOL UITOOLS95_DFC_ButtonRadio(HDC dc, LPRECT r, UINT uFlags)
765{
766 RECT myr;
767 int i;
768 int SmallDiam = UITOOLS_MakeSquareRect(r, &myr);
769 int BorderShrink = SmallDiam / 16;
770 HPEN hpsave;
771 HBRUSH hbsave;
772 int xe, ye;
773 int xc, yc;
774
775 if(BorderShrink < 1) BorderShrink = 1;
776
777 if((uFlags & 0xff) == DFCS_BUTTONRADIOIMAGE)
778 {
779 FillRect(dc, r, (HBRUSH)GetStockObject(BLACK_BRUSH));
780 }
781
782 xe = myr.left;
783 ye = myr.top + SmallDiam - SmallDiam/2;
784
785 xc = myr.left + SmallDiam - SmallDiam/2;
786 yc = myr.top + SmallDiam - SmallDiam/2;
787
788 /* Define bounding box */
789 i = (14*SmallDiam)/16;
790 myr.left = xc - i+i/2;
791 myr.right = xc + i/2;
792 myr.top = yc - i+i/2;
793 myr.bottom = yc + i/2;
794
795 if((uFlags & 0xff) == DFCS_BUTTONRADIOMASK)
796 {
797 hbsave = (HBRUSH)SelectObject(dc, GetStockObject(BLACK_BRUSH));
798 Pie(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye);
799 SelectObject(dc, hbsave);
800 }
801 else
802 {
803 if(uFlags & (DFCS_FLAT|DFCS_MONO))
804 {
805 hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_WINDOWFRAME));
806 hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_WINDOWFRAME));
807 Pie(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye);
808 SelectObject(dc, hbsave);
809 SelectObject(dc, hpsave);
810 }
811 else
812 {
813 hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_BTNHIGHLIGHT));
814 hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_BTNHIGHLIGHT));
815 Pie(dc, myr.left, myr.top, myr.right, myr.bottom, myr.left-1, myr.bottom, myr.right-1, myr.top);
816
817 SelectObject(dc, GetSysColorPen(COLOR_BTNSHADOW));
818 SelectObject(dc, GetSysColorBrush(COLOR_BTNSHADOW));
819 Pie(dc, myr.left, myr.top, myr.right, myr.bottom, myr.right+1, myr.top, myr.left+1, myr.bottom);
820
821 myr.left += BorderShrink;
822 myr.right -= BorderShrink;
823 myr.top += BorderShrink;
824 myr.bottom -= BorderShrink;
825
826 SelectObject(dc, GetSysColorPen(COLOR_3DLIGHT));
827 SelectObject(dc, GetSysColorBrush(COLOR_3DLIGHT));
828 Pie(dc, myr.left, myr.top, myr.right, myr.bottom, myr.left-1, myr.bottom, myr.right-1, myr.top);
829
830 SelectObject(dc, GetSysColorPen(COLOR_3DDKSHADOW));
831 SelectObject(dc, GetSysColorBrush(COLOR_3DDKSHADOW));
832 Pie(dc, myr.left, myr.top, myr.right, myr.bottom, myr.right+1, myr.top, myr.left+1, myr.bottom);
833 SelectObject(dc, hbsave);
834 SelectObject(dc, hpsave);
835 }
836
837 i = (10*SmallDiam)/16,1;
838 myr.left = xc - i+i/2;
839 myr.right = xc + i/2;
840 myr.top = yc - i+i/2;
841 myr.bottom = yc + i/2;
842 i= !(uFlags & (DFCS_INACTIVE|DFCS_PUSHED)) ? COLOR_WINDOW : COLOR_BTNFACE;
843 hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i));
844 hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i));
845 Ellipse(dc,myr.left,myr.top,myr.right,myr.bottom);
846 SelectObject(dc, hbsave);
847 SelectObject(dc, hpsave);
848 }
849
850 if(uFlags & DFCS_CHECKED)
851 {
852 i = (6*SmallDiam)/16;
853 i = i < 1 ? 1 : i;
854 myr.left = xc - i+i/2;
855 myr.right = xc + i/2;
856 myr.top = yc - i+i/2;
857 myr.bottom = yc + i/2;
858
859 i = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_WINDOWTEXT;
860 hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i));
861 hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i));
862 Ellipse(dc,myr.left,myr.top,myr.right,myr.bottom);
863 SelectObject(dc, hpsave);
864 SelectObject(dc, hbsave);
865 }
866
867 /* FIXME: M$ has a polygon in the center at relative points: */
868 /* 0.476, 0.476 (times SmallDiam, SmallDiam) */
869 /* 0.476, 0.525 */
870 /* 0.500, 0.500 */
871 /* 0.500, 0.499 */
872 /* when the button is unchecked. The reason for it is unknown. The */
873 /* color is COLOR_BTNHIGHLIGHT, although the polygon gets painted at */
874 /* least 3 times (it looks like a clip-region when you see it happen). */
875 /* I do not really see a reason why this should be implemented. If you */
876 /* have a good reason, let me know. Maybe this is a quirk in the Marlett */
877 /* font. */
878
879 return TRUE;
880}
881
882/***********************************************************************
883 * UITOOLS_DrawFrameButton
884 */
885static BOOL UITOOLS95_DrawFrameButton(HDC hdc, LPRECT rc, UINT uState)
886{
887 switch(uState & 0xff)
888 {
889 case DFCS_BUTTONPUSH:
890 return UITOOLS95_DFC_ButtonPush(hdc, rc, uState);
891
892 case DFCS_BUTTONCHECK:
893 case DFCS_BUTTON3STATE:
894 return UITOOLS95_DFC_ButtonCheck(hdc, rc, uState);
895
896 case DFCS_BUTTONRADIOIMAGE:
897 case DFCS_BUTTONRADIOMASK:
898 case DFCS_BUTTONRADIO:
899 return UITOOLS95_DFC_ButtonRadio(hdc, rc, uState);
900
901// default:
902// WARN("Invalid button state=0x%04x\n", uState);
903 }
904
905 return FALSE;
906}
907
908/***********************************************************************
909 * UITOOLS_DrawFrameCaption
910 *
911 * Draw caption buttons (win95), coming from DrawFrameControl()
912 */
913
914static BOOL UITOOLS95_DrawFrameCaption(HDC dc, LPRECT r, UINT uFlags)
915{
916 POINT Line1[10];
917 POINT Line2[10];
918 int Line1N;
919 int Line2N;
920 RECT myr;
921 int SmallDiam = UITOOLS_MakeSquareRect(r, &myr)-2;
922 int i;
923 HBRUSH hbsave;
924 HPEN hpsave;
925 HFONT hfsave, hf;
926 int xc = (myr.left+myr.right)/2;
927 int yc = (myr.top+myr.bottom)/2;
928 int edge, move;
929 char str[2] = "?";
930 UINT alignsave;
931 int bksave;
932 COLORREF clrsave;
933 SIZE size;
934
935 UITOOLS95_DFC_ButtonPush(dc, r, uFlags & 0xff00);
936
937 switch(uFlags & 0xff)
938 {
939 case DFCS_CAPTIONCLOSE:
940 edge = 328*SmallDiam/1000;
941 move = 95*SmallDiam/1000;
942 Line1[0].x = Line2[0].x = Line1[1].x = Line2[1].x = xc - edge;
943 Line1[2].y = Line2[5].y = Line1[1].y = Line2[4].y = yc - edge;
944 Line1[3].x = Line2[3].x = Line1[4].x = Line2[4].x = xc + edge;
945 Line1[5].y = Line2[2].y = Line1[4].y = Line2[1].y = yc + edge;
946 Line1[2].x = Line2[2].x = Line1[1].x + move;
947 Line1[0].y = Line2[3].y = Line1[1].y + move;
948 Line1[5].x = Line2[5].x = Line1[4].x - move;
949 Line1[3].y = Line2[0].y = Line1[4].y - move;
950 Line1N = 6;
951 Line2N = 6;
952 break;
953
954 case DFCS_CAPTIONHELP:
955 /* This one breaks the flow */
956 /* FIXME: We need the Marlett font in order to get this right. */
957
958 hf = CreateFontA(-SmallDiam, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
959 ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
960 DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, "System");
961 alignsave = SetTextAlign(dc, TA_TOP|TA_LEFT);
962 bksave = SetBkMode(dc, TRANSPARENT);
963 clrsave = GetTextColor(dc);
964 hfsave = (HFONT)SelectObject(dc, hf);
965 GetTextExtentPoint32A(dc, str, 1, &size);
966
967 if(uFlags & DFCS_INACTIVE)
968 {
969 SetTextColor(dc, GetSysColor(COLOR_BTNHIGHLIGHT));
970 TextOutA(dc, xc-size.cx/2+1, yc-size.cy/2+1, str, 1);
971 }
972 SetTextColor(dc, GetSysColor(uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_BTNTEXT));
973 TextOutA(dc, xc-size.cx/2, yc-size.cy/2, str, 1);
974
975 SelectObject(dc, hfsave);
976 SetTextColor(dc, clrsave);
977 SetBkMode(dc, bksave);
978 SetTextAlign(dc, alignsave);
979 DeleteObject(hf);
980 return TRUE;
981
982 case DFCS_CAPTIONMIN:
983 Line1[0].x = Line1[3].x = myr.left + 96*SmallDiam/750+2;
984 Line1[1].x = Line1[2].x = Line1[0].x + 372*SmallDiam/750;
985 Line1[0].y = Line1[1].y = myr.top + 563*SmallDiam/750+1;
986 Line1[2].y = Line1[3].y = Line1[0].y + 92*SmallDiam/750;
987 Line1N = 4;
988 Line2N = 0;
989 break;
990
991 case DFCS_CAPTIONMAX:
992 edge = 47*SmallDiam/750;
993 Line1[0].x = Line1[5].x = myr.left + 57*SmallDiam/750+3;
994 Line1[0].y = Line1[1].y = myr.top + 143*SmallDiam/750+1;
995 Line1[1].x = Line1[2].x = Line1[0].x + 562*SmallDiam/750;
996 Line1[5].y = Line1[4].y = Line1[0].y + 93*SmallDiam/750;
997 Line1[2].y = Line1[3].y = Line1[0].y + 513*SmallDiam/750;
998 Line1[3].x = Line1[4].x = Line1[1].x - edge;
999
1000 Line2[0].x = Line2[5].x = Line1[0].x;
1001 Line2[3].x = Line2[4].x = Line1[1].x;
1002 Line2[1].x = Line2[2].x = Line1[0].x + edge;
1003 Line2[0].y = Line2[1].y = Line1[0].y;
1004 Line2[4].y = Line2[5].y = Line1[2].y;
1005 Line2[2].y = Line2[3].y = Line1[2].y - edge;
1006 Line1N = 6;
1007 Line2N = 6;
1008 break;
1009
1010 case DFCS_CAPTIONRESTORE:
1011 /* FIXME: this one looks bad at small sizes < 15x15 :( */
1012 edge = 47*SmallDiam/750;
1013 move = 420*SmallDiam/750;
1014 Line1[0].x = Line1[9].x = myr.left + 198*SmallDiam/750+2;
1015 Line1[0].y = Line1[1].y = myr.top + 169*SmallDiam/750+1;
1016 Line1[6].y = Line1[7].y = Line1[0].y + 93*SmallDiam/750;
1017 Line1[7].x = Line1[8].x = Line1[0].x + edge;
1018 Line1[1].x = Line1[2].x = Line1[0].x + move;
1019 Line1[5].x = Line1[6].x = Line1[1].x - edge;
1020 Line1[9].y = Line1[8].y = Line1[0].y + 187*SmallDiam/750;
1021 Line1[2].y = Line1[3].y = Line1[0].y + 327*SmallDiam/750;
1022 Line1[4].y = Line1[5].y = Line1[2].y - edge;
1023 Line1[3].x = Line1[4].x = Line1[2].x - 140*SmallDiam/750;
1024
1025 Line2[1].x = Line2[2].x = Line1[3].x;
1026 Line2[7].x = Line2[8].x = Line2[1].x - edge;
1027 Line2[0].x = Line2[9].x = Line2[3].x = Line2[4].x = Line2[1].x - move;
1028 Line2[5].x = Line2[6].x = Line2[0].x + edge;
1029 Line2[0].y = Line2[1].y = Line1[9].y;
1030 Line2[4].y = Line2[5].y = Line2[8].y = Line2[9].y = Line2[0].y + 93*SmallDiam/750;
1031 Line2[2].y = Line2[3].y = Line2[0].y + 327*SmallDiam/750;
1032 Line2[6].y = Line2[7].y = Line2[2].y - edge;
1033 Line1N = 10;
1034 Line2N = 10;
1035 break;
1036
1037 default:
1038// WARN("Invalid caption; flags=0x%04x\n", uFlags);
1039 return FALSE;
1040 }
1041
1042 /* Here the drawing takes place */
1043 if(uFlags & DFCS_INACTIVE)
1044 {
1045 /* If we have an inactive button, then you see a shadow */
1046 hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_BTNHIGHLIGHT));
1047 hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_BTNHIGHLIGHT));
1048 Polygon(dc, Line1, Line1N);
1049 if(Line2N > 0)
1050 Polygon(dc, Line2, Line2N);
1051 SelectObject(dc, hpsave);
1052 SelectObject(dc, hbsave);
1053 }
1054
1055 /* Correct for the shadow shift */
1056 for(i = 0; i < Line1N; i++)
1057 {
1058 Line1[i].x--;
1059 Line1[i].y--;
1060 }
1061 for(i = 0; i < Line2N; i++)
1062 {
1063 Line2[i].x--;
1064 Line2[i].y--;
1065 }
1066
1067 /* Make the final picture */
1068 i = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_BTNTEXT;
1069 hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i));
1070 hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i));
1071
1072 Polygon(dc, Line1, Line1N);
1073 if(Line2N > 0)
1074 Polygon(dc, Line2, Line2N);
1075 SelectObject(dc, hpsave);
1076 SelectObject(dc, hbsave);
1077
1078 return TRUE;
1079}
1080
1081
1082/************************************************************************
1083 * UITOOLS_DrawFrameScroll
1084 *
1085 * Draw a scroll-bar control coming from DrawFrameControl()
1086 */
1087static BOOL UITOOLS95_DrawFrameScroll(HDC dc, LPRECT r, UINT uFlags)
1088{
1089 POINT Line[4];
1090 RECT myr;
1091 int SmallDiam = UITOOLS_MakeSquareRect(r, &myr) - 2;
1092 int i;
1093 HBRUSH hbsave, hb, hb2;
1094 HPEN hpsave, hp, hp2;
1095 int tri = 290*SmallDiam/1000 -1;
1096 int d46, d93;
1097
1098 /*
1099 * This fixes a problem with really tiny "scroll" buttons. In particular
1100 * with the updown control.
1101 * Making sure that the arrow is as least 3 pixels wide (or high).
1102 */
1103 if (tri == 0)
1104 tri = 1;
1105
1106 switch(uFlags & 0xff)
1107 {
1108 case DFCS_SCROLLCOMBOBOX:
1109 case DFCS_SCROLLDOWN:
1110 Line[2].x = myr.left + 470*SmallDiam/1000 + 2;
1111 Line[2].y = myr.top + 687*SmallDiam/1000 + 1;
1112 Line[0].x = Line[2].x - tri;
1113 Line[1].x = Line[2].x + tri;
1114 Line[0].y = Line[1].y = Line[2].y - tri;
1115 break;
1116
1117 case DFCS_SCROLLUP:
1118 Line[2].x = myr.left + 470*SmallDiam/1000 + 2;
1119 Line[2].y = myr.bottom - 687*SmallDiam/1000 + 1;
1120 Line[0].x = Line[2].x - tri;
1121 Line[1].x = Line[2].x + tri;
1122 Line[0].y = Line[1].y = Line[2].y + tri;
1123 break;
1124
1125 case DFCS_SCROLLLEFT:
1126 Line[2].x = myr.right - 687*SmallDiam/1000 + 1;
1127 Line[2].y = myr.top + 470*SmallDiam/1000 + 2;
1128 Line[0].y = Line[2].y - tri;
1129 Line[1].y = Line[2].y + tri;
1130 Line[0].x = Line[1].x = Line[2].x + tri;
1131 break;
1132
1133 case DFCS_SCROLLRIGHT:
1134 Line[2].x = myr.left + 687*SmallDiam/1000 + 1;
1135 Line[2].y = myr.top + 470*SmallDiam/1000 + 2;
1136 Line[0].y = Line[2].y - tri;
1137 Line[1].y = Line[2].y + tri;
1138 Line[0].x = Line[1].x = Line[2].x - tri;
1139 break;
1140
1141 case DFCS_SCROLLSIZEGRIP:
1142 /* This one breaks the flow... */
1143 UITOOLS95_DrawRectEdge(dc, r, EDGE_BUMP, BF_MIDDLE | ((uFlags&(DFCS_MONO|DFCS_FLAT)) ? BF_MONO : 0));
1144 hpsave = (HPEN)SelectObject(dc, GetStockObject(NULL_PEN));
1145 hbsave = (HBRUSH)SelectObject(dc, GetStockObject(NULL_BRUSH));
1146 if(uFlags & (DFCS_MONO|DFCS_FLAT))
1147 {
1148 hp = hp2 = GetSysColorPen(COLOR_WINDOWFRAME);
1149 hb = hb2 = GetSysColorBrush(COLOR_WINDOWFRAME);
1150 }
1151 else
1152 {
1153 hp = GetSysColorPen(COLOR_BTNHIGHLIGHT);
1154 hp2 = GetSysColorPen(COLOR_BTNSHADOW);
1155 hb = GetSysColorBrush(COLOR_BTNHIGHLIGHT);
1156 hb2 = GetSysColorBrush(COLOR_BTNSHADOW);
1157 }
1158 Line[0].x = Line[1].x = r->right-1;
1159 Line[2].y = Line[3].y = r->bottom-1;
1160 d46 = 46*SmallDiam/750;
1161 d93 = 93*SmallDiam/750;
1162
1163 i = 586*SmallDiam/750;
1164 Line[0].y = r->bottom - i - 1;
1165 Line[3].x = r->right - i - 1;
1166 Line[1].y = Line[0].y + d46;
1167 Line[2].x = Line[3].x + d46;
1168 SelectObject(dc, hb);
1169 SelectObject(dc, hp);
1170 Polygon(dc, Line, 4);
1171
1172 Line[1].y++; Line[2].x++;
1173 Line[0].y = Line[1].y + d93;
1174 Line[3].x = Line[2].x + d93;
1175 SelectObject(dc, hb2);
1176 SelectObject(dc, hp2);
1177 Polygon(dc, Line, 4);
1178
1179 i = 398*SmallDiam/750;
1180 Line[0].y = r->bottom - i - 1;
1181 Line[3].x = r->right - i - 1;
1182 Line[1].y = Line[0].y + d46;
1183 Line[2].x = Line[3].x + d46;
1184 SelectObject(dc, hb);
1185 SelectObject(dc, hp);
1186 Polygon(dc, Line, 4);
1187
1188 Line[1].y++; Line[2].x++;
1189 Line[0].y = Line[1].y + d93;
1190 Line[3].x = Line[2].x + d93;
1191 SelectObject(dc, hb2);
1192 SelectObject(dc, hp2);
1193 Polygon(dc, Line, 4);
1194
1195 i = 210*SmallDiam/750;
1196 Line[0].y = r->bottom - i - 1;
1197 Line[3].x = r->right - i - 1;
1198 Line[1].y = Line[0].y + d46;
1199 Line[2].x = Line[3].x + d46;
1200 SelectObject(dc, hb);
1201 SelectObject(dc, hp);
1202 Polygon(dc, Line, 4);
1203
1204 Line[1].y++; Line[2].x++;
1205 Line[0].y = Line[1].y + d93;
1206 Line[3].x = Line[2].x + d93;
1207 SelectObject(dc, hb2);
1208 SelectObject(dc, hp2);
1209 Polygon(dc, Line, 4);
1210
1211 SelectObject(dc, hpsave);
1212 SelectObject(dc, hbsave);
1213 return TRUE;
1214
1215 default:
1216// WARN("Invalid scroll; flags=0x%04x\n", uFlags);
1217 return FALSE;
1218 }
1219
1220 /* Here do the real scroll-bar controls end up */
1221 if( ! (uFlags & (0xff00 & ~DFCS_ADJUSTRECT)) )
1222 /* UITOOLS95_DFC_ButtonPush always uses BF_SOFT which we don't */
1223 /* want for the normal scroll-arrow button. */
1224 UITOOLS95_DrawRectEdge( dc, r, EDGE_RAISED, (uFlags&DFCS_ADJUSTRECT) | BF_MIDDLE | BF_RECT);
1225 else
1226 UITOOLS95_DFC_ButtonPush(dc, r, (uFlags & 0xff00) );
1227
1228 if(uFlags & DFCS_INACTIVE)
1229 {
1230 hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_BTNHIGHLIGHT));
1231 hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_BTNHIGHLIGHT));
1232 Polygon(dc, Line, 3);
1233 SelectObject(dc, hpsave);
1234 SelectObject(dc, hbsave);
1235 }
1236
1237 if( (uFlags & DFCS_INACTIVE) || !(uFlags & DFCS_PUSHED) )
1238 for(i = 0; i < 3; i++)
1239 {
1240 Line[i].x--;
1241 Line[i].y--;
1242 }
1243
1244 i = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_BTNTEXT;
1245 hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i));
1246 hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i));
1247 Polygon(dc, Line, 3);
1248 SelectObject(dc, hpsave);
1249 SelectObject(dc, hbsave);
1250
1251 return TRUE;
1252}
1253
1254/************************************************************************
1255 * UITOOLS_DrawFrameMenu
1256 *
1257 * Draw a menu control coming from DrawFrameControl()
1258 */
1259static BOOL UITOOLS95_DrawFrameMenu(HDC dc, LPRECT r, UINT uFlags)
1260{
1261 POINT Points[6];
1262 RECT myr;
1263 int SmallDiam = UITOOLS_MakeSquareRect(r, &myr);
1264 int i;
1265 HBRUSH hbsave;
1266 HPEN hpsave;
1267 int xe, ye;
1268 int xc, yc;
1269 BOOL retval = TRUE;
1270
1271 /* Using black and white seems to be utterly wrong, but win95 doesn't */
1272 /* use anything else. I think I tried all sys-colors to change things */
1273 /* without luck. It seems as if this behavior is inherited from the */
1274 /* win31 DFC() implementation... (you remember, B/W menus). */
1275
1276 FillRect(dc, r, (HBRUSH)GetStockObject(WHITE_BRUSH));
1277
1278 hbsave = (HBRUSH)SelectObject(dc, GetStockObject(BLACK_BRUSH));
1279 hpsave = (HPEN)SelectObject(dc, GetStockObject(BLACK_PEN));
1280
1281 switch(uFlags & 0xff)
1282 {
1283 case DFCS_MENUARROW:
1284 i = 187*SmallDiam/750;
1285 Points[2].x = myr.left + 468*SmallDiam/750;
1286 Points[2].y = myr.top + 352*SmallDiam/750+1;
1287 Points[0].y = Points[2].y - i;
1288 Points[1].y = Points[2].y + i;
1289 Points[0].x = Points[1].x = Points[2].x - i;
1290 Polygon(dc, Points, 3);
1291 break;
1292
1293 case DFCS_MENUBULLET:
1294 xe = myr.left;
1295 ye = myr.top + SmallDiam - SmallDiam/2;
1296 xc = myr.left + SmallDiam - SmallDiam/2;
1297 yc = myr.top + SmallDiam - SmallDiam/2;
1298 i = 234*SmallDiam/750;
1299 i = i < 1 ? 1 : i;
1300 myr.left = xc - i+i/2;
1301 myr.right = xc + i/2;
1302 myr.top = yc - i+i/2;
1303 myr.bottom = yc + i/2;
1304 Pie(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye);
1305 break;
1306
1307 case DFCS_MENUCHECK:
1308 Points[0].x = myr.left + 253*SmallDiam/1000;
1309 Points[0].y = myr.top + 445*SmallDiam/1000;
1310 Points[1].x = myr.left + 409*SmallDiam/1000;
1311 Points[1].y = Points[0].y + (Points[1].x-Points[0].x);
1312 Points[2].x = myr.left + 690*SmallDiam/1000;
1313 Points[2].y = Points[1].y - (Points[2].x-Points[1].x);
1314 Points[3].x = Points[2].x;
1315 Points[3].y = Points[2].y + 3*SmallDiam/16;
1316 Points[4].x = Points[1].x;
1317 Points[4].y = Points[1].y + 3*SmallDiam/16;
1318 Points[5].x = Points[0].x;
1319 Points[5].y = Points[0].y + 3*SmallDiam/16;
1320 Polygon(dc, Points, 6);
1321 break;
1322
1323 default:
1324// WARN("Invalid menu; flags=0x%04x\n", uFlags);
1325 retval = FALSE;
1326 break;
1327 }
1328
1329 SelectObject(dc, hpsave);
1330 SelectObject(dc, hbsave);
1331 return retval;
1332}
1333
1334/**********************************************************************
1335 * DrawFrameControl (USER32.158)
1336 */
1337BOOL WIN32API DrawFrameControl(HDC hdc, LPRECT rc, UINT uType,
1338 UINT uState )
1339{
1340 /* Win95 doesn't support drawing in other mapping modes */
1341 if(GetMapMode(hdc) != MM_TEXT)
1342 return FALSE;
1343
1344 switch(uType)
1345 {
1346 case DFC_BUTTON:
1347 return UITOOLS95_DrawFrameButton(hdc, rc, uState);
1348 case DFC_CAPTION:
1349 return UITOOLS95_DrawFrameCaption(hdc, rc, uState);
1350 case DFC_MENU:
1351 return UITOOLS95_DrawFrameMenu(hdc, rc, uState);
1352 case DFC_SCROLL:
1353 return UITOOLS95_DrawFrameScroll(hdc, rc, uState);
1354// default:
1355// WARN("(%x,%p,%d,%x), bad type!\n",
1356// hdc,rc,uType,uState );
1357 }
1358 return FALSE;
1359}
1360/******************************************************************************
1361 *
1362 * This function is used by Paint_DrawState which is inturn used by both
1363 * DrawStateA and DrawStateW. The code is directly borrowed from Wine.
1364 *
1365 ******************************************************************************/
1366
1367static BOOL Paint_DrawStateJam(HDC hdc, UINT opcode,
1368 DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
1369 LPRECT rc, UINT dtflags, BOOL unicode)
1370{
1371 HDC memdc;
1372 HBITMAP hbmsave;
1373 BOOL retval;
1374 INT cx = rc->right - rc->left;
1375 INT cy = rc->bottom - rc->top;
1376
1377 switch(opcode)
1378 {
1379 case DST_TEXT:
1380 case DST_PREFIXTEXT:
1381 if(unicode)
1382 return DrawTextW(hdc, (LPWSTR)lp, (INT)wp, rc, dtflags);
1383 else
1384 return DrawTextA(hdc, (LPSTR)lp, (INT)wp, rc, dtflags);
1385
1386 case DST_ICON:
1387 return DrawIcon(hdc, rc->left, rc->top, (HICON)lp);
1388
1389 case DST_BITMAP:
1390 memdc = CreateCompatibleDC(hdc);
1391 if(!memdc) return FALSE;
1392 hbmsave = (HBITMAP)SelectObject(memdc, (HBITMAP)lp);
1393 if(!hbmsave)
1394 {
1395 DeleteDC(memdc);
1396 return FALSE;
1397 }
1398 retval = BitBlt(hdc, rc->left, rc->top, cx, cy, memdc, 0, 0, SRCCOPY);
1399 SelectObject(memdc, hbmsave);
1400 DeleteDC(memdc);
1401 return retval;
1402
1403 case DST_COMPLEX:
1404 if(func)
1405 return func(hdc, lp, wp, cx, cy);
1406 else
1407 return FALSE;
1408 }
1409 return FALSE;
1410}
1411
1412
1413/******************************************************************************
1414 *
1415 * This function is used by both DrawStateA and DrawStateW. The code is directly
1416 * borrowed from Wine
1417 *
1418 ******************************************************************************/
1419BOOL Paint_DrawState (HDC hdc, HBRUSH hbr, DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
1420 INT x, INT y, INT cx, INT cy, UINT flags, BOOL unicode)
1421{
1422 HBITMAP hbm, hbmsave;
1423 HFONT hfsave;
1424 HBRUSH hbsave;
1425 HDC memdc;
1426 RECT rc;
1427 UINT dtflags = DT_NOCLIP;
1428 COLORREF fg, bg;
1429 UINT opcode = flags & 0xf;
1430 INT len = wp;
1431 BOOL retval, tmp;
1432
1433 if((opcode == DST_TEXT || opcode == DST_PREFIXTEXT) && !len) /* The string is '\0' terminated */
1434 {
1435 if(unicode)
1436 len = lstrlenW((LPWSTR)lp);
1437 else
1438 len = lstrlenA((LPSTR)lp);
1439 }
1440
1441 /* Find out what size the image has if not given by caller */
1442 if(!cx || !cy)
1443 {
1444 SIZE s;
1445 BITMAP bmp;
1446
1447 switch(opcode)
1448 {
1449 case DST_TEXT:
1450 case DST_PREFIXTEXT:
1451 if(unicode)
1452 retval = GetTextExtentPoint32W(hdc, (LPWSTR)lp, len, &s);
1453 else
1454 retval = GetTextExtentPoint32A(hdc, (LPSTR)lp, len, &s);
1455 if(!retval) return FALSE;
1456 break;
1457
1458 case DST_ICON:
1459 /* Just assume the icon has the size given by GetSystemMetrics. This should be
1460 valid since both CreateIcon and LoadIcon can't create icons with different
1461 sizes. I wouldn't how else to get the size of the icon. RP
1462 */
1463 s.cx = GetSystemMetrics (SM_CXICON);
1464 s.cy = GetSystemMetrics (SM_CYICON);
1465 break;
1466
1467 case DST_BITMAP:
1468 retval = GetObjectA ((HBITMAP) lp, sizeof (BITMAP), &bmp);
1469 if(retval == 0) return FALSE;
1470 s.cx = bmp.bmWidth;
1471 s.cy = bmp.bmHeight;
1472 break;
1473
1474 case DST_COMPLEX: /* cx and cy must be set in this mode */
1475 return FALSE;
1476 }
1477
1478 if(!cx) cx = s.cx;
1479 if(!cy) cy = s.cy;
1480 }
1481
1482 rc.left = x;
1483 rc.top = y;
1484 rc.right = x + cx;
1485 rc.bottom = y + cy;
1486
1487 if(flags & DSS_RIGHT) /* This one is not documented in the win32.hlp file */
1488 dtflags |= DT_RIGHT;
1489 if(opcode == DST_TEXT)
1490 dtflags |= DT_NOPREFIX;
1491
1492 /* For DSS_NORMAL we just jam in the image and return */
1493 if((flags & 0x7ff0) == DSS_NORMAL)
1494 {
1495 return Paint_DrawStateJam(hdc, opcode, func, lp, len, &rc, dtflags, unicode);
1496 }
1497
1498 /* For all other states we need to convert the image to B/W in a local bitmap */
1499 /* before it is displayed */
1500 fg = SetTextColor(hdc, RGB(0, 0, 0));
1501 bg = SetBkColor(hdc, RGB(255, 255, 255));
1502 hbm = (HBITMAP)NULL; hbmsave = (HBITMAP)NULL;
1503 memdc = (HDC)NULL; hbsave = (HBRUSH)NULL;
1504 retval = FALSE; /* assume failure */
1505
1506 /* From here on we must use "goto cleanup" when something goes wrong */
1507 hbm = CreateBitmap(cx, cy, 1, 1, NULL);
1508 if(!hbm) goto cleanup;
1509 memdc = CreateCompatibleDC(hdc);
1510 if(!memdc) goto cleanup;
1511 hbmsave = (HBITMAP)SelectObject(memdc, hbm);
1512 if(!hbmsave) goto cleanup;
1513 rc.left = rc.top = 0;
1514 rc.right = cx;
1515 rc.bottom = cy;
1516 if(!FillRect(memdc, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH))) goto cleanup;
1517 SetBkColor(memdc, RGB(255, 255, 255));
1518 SetTextColor(memdc, RGB(0, 0, 0));
1519 hfsave = (HFONT)SelectObject(memdc, GetCurrentObject(hdc, OBJ_FONT));
1520 if(!hfsave && (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)) goto cleanup;
1521 tmp = Paint_DrawStateJam(memdc, opcode, func, lp, len, &rc, dtflags, unicode);
1522 if(hfsave) SelectObject(memdc, hfsave);
1523 if(!tmp) goto cleanup;
1524
1525 /* These states cause the image to be dithered */
1526 if(flags & (DSS_UNION|DSS_DISABLED))
1527 {
1528 WORD wPattern55AA[] = { 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa };
1529 HBITMAP hPattern55AABitmap = CreateBitmap( 8, 8, 1, 1, wPattern55AA );
1530 HBRUSH hPattern55AABrush = CreatePatternBrush(hPattern55AABitmap);
1531
1532 hbsave = (HBRUSH)SelectObject(memdc, hPattern55AABrush);
1533 if(!hbsave) goto cleanup;
1534 tmp = PatBlt(memdc, 0, 0, cx, cy, 0x00FA0089);
1535 if(hbsave) SelectObject(memdc, hbsave);
1536 if(!tmp) goto cleanup;
1537 }
1538
1539 hbsave = (HBRUSH)SelectObject(hdc, hbr ? hbr : GetStockObject(WHITE_BRUSH));
1540 if(!hbsave) goto cleanup;
1541
1542 if(!BitBlt(hdc, x, y, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
1543
1544 /* DSS_DEFAULT makes the image boldface */
1545 if(flags & DSS_DEFAULT)
1546 {
1547 if(!BitBlt(hdc, x+1, y, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
1548 }
1549
1550 retval = TRUE; /* We succeeded */
1551
1552cleanup:
1553 SetTextColor(hdc, fg);
1554 SetBkColor(hdc, bg);
1555
1556 if(hbsave) SelectObject(hdc, hbsave);
1557 if(hbmsave) SelectObject(memdc, hbmsave);
1558 if(hbm) DeleteObject(hbm);
1559 if(memdc) DeleteDC(memdc);
1560
1561 return retval;
1562}
1563
1564
1565
1566/*****************************************************************************
1567 * Name : BOOL WIN32API DrawStateA
1568 * Purpose : Draws a bitmap, icon, text or complex object in one of the following
1569 * states: normal, disabled, union or mono
1570 * Parameters:
1571 * Variables :
1572 * Result : If the function succeeds, the return value is a handle of the
1573 * window station associated with the calling process.
1574 * If the function fails, the return value is NULL. This can occur
1575 * if the calling process is not an application written for Windows
1576 * NT. To get extended error information, call GetLastError.
1577 * Remark : Disabled doesn't look like the Windows implementation, but it does
1578 * look disabled.
1579 * Status : PARTIALLY IMPLEMENTED
1580 *
1581 * Author : Rene Pronk [Sun, 1999/07/25 21:27]
1582 *****************************************************************************/
1583
1584BOOL WIN32API DrawStateA(HDC hdc, HBRUSH hbc, DRAWSTATEPROC lpOutputFunc, LPARAM lData,
1585 WPARAM wData, int x, int y, int cx, int cy, UINT fuFlags)
1586{
1587 dprintf(("USER32:DrawStateA (%08xh,%08xh,%08xh,%08xh,%08xh,%d,%d,%d,%d,%08x).\n",
1588 hdc, hbc, lpOutputFunc, lData, wData, x, y, cx, cy, fuFlags));
1589
1590 return Paint_DrawState (hdc, hbc, lpOutputFunc, lData, wData, x, y ,cx, cy, fuFlags, FALSE);
1591}
1592
1593
1594
1595/*****************************************************************************
1596 * Name : BOOL WIN32API DrawStateW
1597 * Purpose : Draws a bitmap, icon, text or complex object in one of the following
1598 * states: normal, disabled, union or mono
1599 * Parameters:
1600 * Variables :
1601 * Result : If the function succeeds, the return value is a handle of the
1602 * window station associated with the calling process.
1603 * If the function fails, the return value is NULL. This can occur
1604 * if the calling process is not an application written for Windows
1605 * NT. To get extended error information, call GetLastError.
1606 * Remark : Disabled doesn't look like the Windows implementation, but it does
1607 * look disabled.
1608 * Status : PARTIALLY IMPLEMENTED
1609 *
1610 * Author : Rene Pronk [Sun, 1999/07/25 21:27]
1611 *****************************************************************************/
1612
1613BOOL WIN32API DrawStateW(HDC hdc, HBRUSH hbc, DRAWSTATEPROC lpOutputFunc, LPARAM lData,
1614 WPARAM wData, int x, int y, int cx, int cy, UINT fuFlags)
1615{
1616 dprintf(("USER32:DrawStateW (%08xh,%08xh,%08xh,%08xh,%08xh,%d,%d,%d,%d,%08x).\n",
1617 hdc, hbc, lpOutputFunc, lData, wData, x, y, cx, cy, fuFlags));
1618
1619 return Paint_DrawState (hdc, hbc, lpOutputFunc, lData, wData, x, y ,cx, cy, fuFlags, TRUE);
1620}
1621//******************************************************************************
1622//******************************************************************************
1623BOOL WIN32API DrawFocusRect( HDC arg1, const RECT * arg2)
1624{
1625#ifdef DEBUG
1626 WriteLog("USER32: DrawFocusRect\n");
1627#endif
1628 return O32_DrawFocusRect(arg1, arg2);
1629}
1630//******************************************************************************
1631//******************************************************************************
1632BOOL WIN32API DrawIcon( HDC hDC, int X, int Y, HICON hIcon)
1633{
1634 ICONINFO ii;
1635 HDC hMemDC;
1636 BITMAP bmp;
1637 HBITMAP oldBmp;
1638 COLORREF oldFg,oldBg;
1639
1640#ifdef DEBUG
1641 WriteLog("USER32: DrawIcon\n");
1642#endif
1643
1644 if (!hDC || !hIcon)
1645 {
1646 SetLastError(ERROR_INVALID_PARAMETER);
1647
1648 return FALSE;
1649 }
1650
1651 if (!GetIconInfo(hIcon,&ii)) return FALSE;
1652 oldFg = SetTextColor(hDC,RGB(0,0,0));
1653 oldBg = SetBkColor(hDC,RGB(255,255,255));
1654 hMemDC = CreateCompatibleDC(hDC);
1655 oldBmp = SelectObject(hMemDC,ii.hbmMask);
1656 if (ii.hbmColor)
1657 {
1658 GetObjectA(ii.hbmColor,sizeof(BITMAP),(LPVOID)&bmp);
1659 BitBlt(hDC,X,Y,bmp.bmWidth,bmp.bmHeight,hMemDC,0,0,SRCAND);
1660 SelectObject(hMemDC,ii.hbmColor);
1661 BitBlt(hDC,X,Y,bmp.bmWidth,bmp.bmHeight,hMemDC,0,0,SRCINVERT);
1662 } else
1663 {
1664 GetObjectA(ii.hbmMask,sizeof(BITMAP),(LPVOID)&bmp);
1665 BitBlt(hDC,X,Y,bmp.bmWidth,bmp.bmHeight/2,hMemDC,0,0,SRCAND);
1666 BitBlt(hDC,X,Y,bmp.bmWidth,bmp.bmHeight/2,hMemDC,0,bmp.bmHeight/2,SRCINVERT);
1667 }
1668 SelectObject(hMemDC,oldBmp);
1669 DeleteObject(hMemDC);
1670 if (ii.hbmColor) DeleteObject(ii.hbmColor);
1671 if (ii.hbmMask) DeleteObject(ii.hbmMask);
1672 SetTextColor(hDC,oldFg);
1673 SetBkColor(hDC,oldBg);
1674
1675 return TRUE;
1676}
1677//******************************************************************************
1678//******************************************************************************
1679BOOL WIN32API DrawIconEx(HDC hdc, int xLeft, int yTop, HICON hIcon,
1680 int cxWidth, int cyWidth, UINT istepIfAniCur,
1681 HBRUSH hbrFlickerFreeDraw, UINT diFlags)
1682{
1683 ICONINFO ii;
1684 HDC hMemDC;
1685 BITMAP bmp;
1686 HBITMAP oldBmp;
1687 COLORREF oldFg,oldBg;
1688 INT oldStretchMode;
1689
1690#ifdef DEBUG
1691 WriteLog("USER32: DrawIconEx\n");
1692#endif
1693
1694 //CB: istepIfAniCur, DI_COMPAT ignored
1695
1696 if (!hdc || !hIcon)
1697 {
1698 SetLastError(ERROR_INVALID_PARAMETER);
1699
1700 return FALSE;
1701 }
1702
1703 if (!GetIconInfo(hIcon,&ii)) return FALSE;
1704 if (ii.hbmColor)
1705 GetObjectA(ii.hbmColor,sizeof(BITMAP),(LPVOID)&bmp);
1706 else
1707 GetObjectA(ii.hbmMask,sizeof(BITMAP),(LPVOID)&bmp);
1708
1709 /* Calculate the size of the destination image. */
1710 if (diFlags & DI_DEFAULTSIZE)
1711 {
1712 cxWidth = GetSystemMetrics(SM_CXICON);
1713 cyWidth = GetSystemMetrics(SM_CYICON);
1714 } else if (cxWidth == 0)
1715 {
1716 cxWidth = bmp.bmWidth;
1717 } else if (cyWidth == 0)
1718 {
1719 cyWidth = ii.hbmColor ? bmp.bmHeight:bmp.bmHeight/2;
1720 }
1721
1722 if (hbrFlickerFreeDraw)
1723 {
1724 HDC hBmpDC = CreateCompatibleDC(hdc);
1725 HBITMAP memBmp,oldMemBmp = CreateCompatibleBitmap(hdc,cxWidth,cyWidth);
1726 RECT rect;
1727
1728 oldMemBmp = SelectObject(hBmpDC,memBmp);
1729 rect.left = 0;
1730 rect.top = 0;
1731 rect.right = cxWidth;
1732 rect.bottom = cyWidth;
1733 FillRect(hBmpDC,&rect,hbrFlickerFreeDraw);
1734 oldFg = SetTextColor(hBmpDC,RGB(0,0,0));
1735 oldBg = SetBkColor(hBmpDC,RGB(255,255,255));
1736 hMemDC = CreateCompatibleDC(hdc);
1737 oldBmp = SelectObject(hMemDC,ii.hbmMask);
1738 oldStretchMode = SetStretchBltMode(hBmpDC,STRETCH_DELETESCANS);
1739 if (ii.hbmColor)
1740 {
1741 if (diFlags & DI_MASK)
1742 StretchBlt(hBmpDC,0,0,cxWidth,cyWidth,hMemDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCAND);
1743 if (diFlags & DI_IMAGE)
1744 {
1745 SelectObject(hMemDC,ii.hbmColor);
1746 StretchBlt(hBmpDC,0,0,cxWidth,cyWidth,hMemDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCINVERT);
1747 }
1748 } else if (diFlags & DI_MASK)
1749 {
1750 StretchBlt(hBmpDC,0,0,cxWidth,cyWidth,hMemDC,0,0,bmp.bmWidth,bmp.bmHeight/2,SRCAND);
1751 StretchBlt(hBmpDC,0,0,cxWidth,cyWidth,hMemDC,0,bmp.bmHeight/2,bmp.bmWidth,bmp.bmHeight/2,SRCINVERT);
1752 }
1753 BitBlt(hdc,xLeft,yTop,cxWidth,cyWidth,hBmpDC,0,0,SRCCOPY);
1754 SelectObject(hMemDC,oldBmp);
1755 DeleteObject(hMemDC);
1756 SetTextColor(hdc,oldFg);
1757 SetBkColor(hdc,oldBg);
1758 SetStretchBltMode(hBmpDC,oldStretchMode);
1759 SelectObject(hBmpDC,oldMemBmp);
1760 DeleteObject(hBmpDC);
1761 DeleteObject(memBmp);
1762 } else
1763 {
1764 oldFg = SetTextColor(hdc,RGB(0,0,0));
1765 oldBg = SetBkColor(hdc,RGB(255,255,255));
1766 hMemDC = CreateCompatibleDC(hdc);
1767 oldBmp = SelectObject(hMemDC,ii.hbmMask);
1768 oldStretchMode = SetStretchBltMode(hdc,STRETCH_DELETESCANS);
1769 if (ii.hbmColor)
1770 {
1771 if (diFlags & DI_MASK)
1772 StretchBlt(hdc,xLeft,yTop,cxWidth,cyWidth,hMemDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCAND);
1773 if (diFlags & DI_IMAGE)
1774 {
1775 SelectObject(hMemDC,ii.hbmColor);
1776 StretchBlt(hdc,xLeft,yTop,cxWidth,cyWidth,hMemDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCINVERT);
1777 }
1778 } else if (diFlags & DI_MASK)
1779 {
1780 StretchBlt(hdc,xLeft,yTop,cxWidth,cyWidth,hMemDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCAND);
1781 StretchBlt(hdc,xLeft,yTop,cxWidth,cyWidth,hMemDC,0,bmp.bmHeight/2,bmp.bmWidth,bmp.bmHeight/2,SRCINVERT);
1782 }
1783 SelectObject(hMemDC,oldBmp);
1784 DeleteObject(hMemDC);
1785 SetTextColor(hdc,oldFg);
1786 SetBkColor(hdc,oldBg);
1787 SetStretchBltMode(hdc,oldStretchMode);
1788 }
1789 if (ii.hbmColor) DeleteObject(ii.hbmColor);
1790 if (ii.hbmMask) DeleteObject(ii.hbmMask);
1791
1792 return TRUE;
1793}
1794/*****************************************************************************
1795 * Name : BOOL WIN32API DrawAnimatedRects
1796 * Purpose : The DrawAnimatedRects function draws a wire-frame rectangle
1797 * and animates it to indicate the opening of an icon or the
1798 * minimizing or maximizing of a window.
1799 * Parameters: HWND hwnd handle of clipping window
1800 * int idAni type of animation
1801 * CONST RECT * lprcFrom address of rectangle coordinates (minimized)
1802 * CONST RECT * lprcTo address of rectangle coordinates (restored)
1803 * Variables :
1804 * Result : If the function succeeds, the return value is TRUE.
1805 * If the function fails, the return value is FALSE.
1806 * Remark :
1807 * Status : UNTESTED STUB
1808 *
1809 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1810 *****************************************************************************/
1811
1812BOOL WIN32API DrawAnimatedRects(HWND hwnd,
1813 int idAni,
1814 CONST RECT *lprcFrom,
1815 CONST RECT *lprcTo)
1816{
1817 dprintf(("USER32:DrawAnimatedRects (%08xh,%u,%08xh,%08x) not implemented.\n",
1818 hwnd,
1819 idAni,
1820 lprcFrom,
1821 lprcTo));
1822
1823 return (TRUE);
1824}
1825
1826
1827/*****************************************************************************
1828 * Name : VOID WIN32API DrawCaption
1829 * Purpose : The DrawCaption function draws a window caption.
1830 * Parameters: HDC hdc handle of device context
1831 * LPRECT lprc address of bounding rectangle coordinates
1832 * HFONT hfont handle of font for caption
1833 * HICON hicon handle of icon in caption
1834 * LPSTR lpszText address of caption string
1835 * WORD wFlags drawing options
1836 * Variables :
1837 * Result :
1838 * Remark :
1839 * Status : UNTESTED STUB
1840 *
1841 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1842 *****************************************************************************/
1843
1844BOOL WIN32API DrawCaption (HWND hwnd,
1845 HDC hdc,
1846 const RECT *lprc,
1847 UINT wFlags)
1848{
1849 dprintf(("USER32:DrawCaption (%08xh,%08xh,%08xh,%08xh) not implemented.\n",
1850 hwnd,
1851 hdc,
1852 lprc,
1853 wFlags));
1854
1855 return FALSE;
1856}
1857/***********************************************************************
1858 * DrawCaptionTemp32A [USER32.599]
1859 *
1860 * PARAMS
1861 *
1862 * RETURNS
1863 * Success:
1864 * Failure:
1865 */
1866
1867BOOL WIN32API DrawCaptionTempA(HWND hwnd,
1868 HDC hdc,
1869 const RECT *rect,
1870 HFONT hFont,
1871 HICON hIcon,
1872 LPCSTR str,
1873 UINT uFlags)
1874{
1875 RECT rc = *rect;
1876
1877 dprintf(("USER32: DrawCaptionTempA(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh,%08xh)\n",
1878 hwnd,
1879 hdc,
1880 rect,
1881 hFont,
1882 hIcon,
1883 str,
1884 uFlags));
1885
1886 /* drawing background */
1887 if (uFlags & DC_INBUTTON)
1888 {
1889 O32_FillRect (hdc,
1890 &rc,
1891 GetSysColorBrush (COLOR_3DFACE));
1892
1893 if (uFlags & DC_ACTIVE)
1894 {
1895 HBRUSH hbr = O32_SelectObject (hdc,
1896 GetSysColorBrush (COLOR_ACTIVECAPTION));
1897 O32_PatBlt (hdc,
1898 rc.left,
1899 rc.top,
1900 rc.right - rc.left,
1901 rc.bottom - rc.top,
1902 0xFA0089);
1903
1904 O32_SelectObject (hdc,
1905 hbr);
1906 }
1907 }
1908 else
1909 {
1910 O32_FillRect (hdc,
1911 &rc,
1912 GetSysColorBrush ((uFlags & DC_ACTIVE) ?
1913 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
1914 }
1915
1916
1917 /* drawing icon */
1918 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP))
1919 {
1920 POINT pt;
1921
1922 pt.x = rc.left + 2;
1923 pt.y = (rc.bottom + rc.top - O32_GetSystemMetrics(SM_CYSMICON)) / 2;
1924
1925 if (hIcon)
1926 {
1927 DrawIconEx (hdc,
1928 pt.x,
1929 pt.y,
1930 hIcon,
1931 O32_GetSystemMetrics(SM_CXSMICON),
1932 O32_GetSystemMetrics(SM_CYSMICON),
1933 0,
1934 0,
1935 DI_NORMAL);
1936 }
1937 else
1938 {
1939 /* @@@PH 1999/06/08 not ported yet, just don't draw any icon
1940 WND *wndPtr = WIN_FindWndPtr(hwnd);
1941 HICON hAppIcon = 0;
1942
1943 if (wndPtr->class->hIconSm)
1944 hAppIcon = wndPtr->class->hIconSm;
1945 else
1946 if (wndPtr->class->hIcon)
1947 hAppIcon = wndPtr->class->hIcon;
1948
1949 DrawIconEx (hdc,
1950 pt.x,
1951 pt.y,
1952 hAppIcon,
1953 GetSystemMetrics(SM_CXSMICON),
1954 GetSystemMetrics(SM_CYSMICON),
1955 0,
1956 0,
1957 DI_NORMAL);
1958
1959 WIN_ReleaseWndPtr(wndPtr);
1960 */
1961 }
1962
1963 rc.left += (rc.bottom - rc.top);
1964 }
1965
1966 /* drawing text */
1967 if (uFlags & DC_TEXT)
1968 {
1969 HFONT hOldFont;
1970
1971 if (uFlags & DC_INBUTTON)
1972 O32_SetTextColor (hdc,
1973 O32_GetSysColor (COLOR_BTNTEXT));
1974 else
1975 if (uFlags & DC_ACTIVE)
1976 O32_SetTextColor (hdc,
1977 O32_GetSysColor (COLOR_CAPTIONTEXT));
1978 else
1979 O32_SetTextColor (hdc,
1980 O32_GetSysColor (COLOR_INACTIVECAPTIONTEXT));
1981
1982 O32_SetBkMode (hdc,
1983 TRANSPARENT);
1984
1985 if (hFont)
1986 hOldFont = O32_SelectObject (hdc,
1987 hFont);
1988 else
1989 {
1990 NONCLIENTMETRICSA nclm;
1991 HFONT hNewFont;
1992
1993 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1994 O32_SystemParametersInfo (SPI_GETNONCLIENTMETRICS,
1995 0,
1996 &nclm,
1997 0);
1998 hNewFont = O32_CreateFontIndirect ((uFlags & DC_SMALLCAP) ?
1999 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
2000 hOldFont = O32_SelectObject (hdc,
2001 hNewFont);
2002 }
2003
2004 if (str)
2005 DrawTextA (hdc,
2006 str,
2007 -1,
2008 &rc,
2009 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
2010 else
2011 {
2012 CHAR szText[128];
2013 INT nLen;
2014
2015 nLen = O32_GetWindowText (Win32BaseWindow::Win32ToOS2FrameHandle(hwnd),
2016 szText,
2017 128);
2018
2019 DrawTextA (hdc,
2020 szText,
2021 nLen,
2022 &rc,
2023 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
2024 }
2025
2026 if (hFont)
2027 O32_SelectObject (hdc,
2028 hOldFont);
2029 else
2030 O32_DeleteObject (O32_SelectObject (hdc,
2031 hOldFont));
2032 }
2033
2034 /* drawing focus ??? */
2035 if (uFlags & 0x2000)
2036 {
2037 dprintf(("USER32: DrawCaptionTempA undocumented flag (0x2000)!\n"));
2038 }
2039
2040 return 0;
2041}
2042
2043
2044/***********************************************************************
2045 * DrawCaptionTemp32W [USER32.602]
2046 *
2047 * PARAMS
2048 *
2049 * RETURNS
2050 * Success:
2051 * Failure:
2052 */
2053
2054BOOL WIN32API DrawCaptionTempW (HWND hwnd,
2055 HDC hdc,
2056 const RECT *rect,
2057 HFONT hFont,
2058 HICON hIcon,
2059 LPCWSTR str,
2060 UINT uFlags)
2061{
2062 LPSTR strAscii = UnicodeToAsciiString((LPWSTR)str);
2063
2064 BOOL res = DrawCaptionTempA (hwnd,
2065 hdc,
2066 rect,
2067 hFont,
2068 hIcon,
2069 strAscii,
2070 uFlags);
2071
2072 FreeAsciiString(strAscii);
2073
2074 return res;
2075}
2076
2077//******************************************************************************
2078//******************************************************************************
Note: See TracBrowser for help on using the repository browser.