xref: /reactos/dll/cpl/desk/draw.c (revision e8ec23fc)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Display Control Panel
4  * FILE:            dll/cpl/desk/draw.c
5  * PURPOSE:         Providing drawing functions
6  *
7  * PROGRAMMERS:     Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
8  */
9 
10 #include "desk.h"
11 
12 #define MENU_BAR_ITEMS_SPACE (12)
13 
14 /******************************************************************************/
15 
16 static const signed char LTInnerNormal[] = {
17     -1,        -1,                  -1,                 -1,
18     -1,        COLOR_BTNHIGHLIGHT,  COLOR_BTNHIGHLIGHT, -1,
19     -1,        COLOR_3DDKSHADOW,    COLOR_3DDKSHADOW,   -1,
20     -1,        -1,                  -1,                 -1
21 };
22 
23 static const signed char LTOuterNormal[] = {
24     -1,                 COLOR_3DLIGHT,   COLOR_BTNSHADOW, -1,
25     COLOR_BTNHIGHLIGHT, COLOR_3DLIGHT,   COLOR_BTNSHADOW, -1,
26     COLOR_3DDKSHADOW,   COLOR_3DLIGHT,   COLOR_BTNSHADOW, -1,
27     -1,                 COLOR_3DLIGHT,   COLOR_BTNSHADOW, -1
28 };
29 
30 static const signed char RBInnerNormal[] = {
31     -1,        -1,              -1,                 -1,
32     -1,        COLOR_BTNSHADOW, COLOR_BTNSHADOW,    -1,
33     -1,        COLOR_3DLIGHT,   COLOR_3DLIGHT,      -1,
34     -1,        -1,              -1,                 -1
35 };
36 
37 static const signed char RBOuterNormal[] = {
38     -1,                 COLOR_3DDKSHADOW,  COLOR_BTNHIGHLIGHT, -1,
39     COLOR_BTNSHADOW,    COLOR_3DDKSHADOW,  COLOR_BTNHIGHLIGHT, -1,
40     COLOR_3DLIGHT,      COLOR_3DDKSHADOW,  COLOR_BTNHIGHLIGHT, -1,
41     -1,                 COLOR_3DDKSHADOW,  COLOR_BTNHIGHLIGHT, -1
42 };
43 
44 static const signed char LTRBOuterMono[] = {
45     -1,           COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
46     COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
47     COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
48     COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
49 };
50 
51 static const signed char LTRBInnerMono[] = {
52     -1, -1,           -1,           -1,
53     -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW,
54     -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW,
55     -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW,
56 };
57 
58 static BOOL
MyIntDrawRectEdge(HDC hdc,LPRECT rc,UINT uType,UINT uFlags,COLOR_SCHEME * scheme)59 MyIntDrawRectEdge(HDC hdc, LPRECT rc, UINT uType, UINT uFlags, COLOR_SCHEME *scheme)
60 {
61     signed char LTInnerI, LTOuterI;
62     signed char RBInnerI, RBOuterI;
63     HPEN LTInnerPen, LTOuterPen;
64     HPEN RBInnerPen, RBOuterPen;
65     RECT InnerRect = *rc;
66     POINT SavePoint;
67     HPEN SavePen;
68     int LBpenplus = 0;
69     int LTpenplus = 0;
70     int RTpenplus = 0;
71     int RBpenplus = 0;
72     HBRUSH hbr;
73 
74     /* Init some vars */
75     LTInnerPen = LTOuterPen = RBInnerPen = RBOuterPen = (HPEN)GetStockObject(NULL_PEN);
76     SavePen = (HPEN)SelectObject(hdc, LTInnerPen);
77 
78     /* Determine the colors of the edges */
79     LTInnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
80     LTOuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
81     RBInnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
82     RBOuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
83 
84     if ((uFlags & BF_BOTTOMLEFT) == BF_BOTTOMLEFT)
85         LBpenplus = 1;
86     if ((uFlags & BF_TOPRIGHT) == BF_TOPRIGHT)
87         RTpenplus = 1;
88     if ((uFlags & BF_BOTTOMRIGHT) == BF_BOTTOMRIGHT)
89         RBpenplus = 1;
90     if ((uFlags & BF_TOPLEFT) == BF_TOPLEFT)
91         LTpenplus = 1;
92 
93     if ((uFlags & MY_BF_ACTIVEBORDER))
94         hbr = CreateSolidBrush(scheme->crColor[COLOR_ACTIVEBORDER]);
95     else
96         hbr = CreateSolidBrush(scheme->crColor[COLOR_BTNFACE]);
97 
98     FillRect(hdc, &InnerRect, hbr);
99     DeleteObject(hbr);
100 
101     MoveToEx(hdc, 0, 0, &SavePoint);
102 
103     /* Draw the outer edge */
104     if (LTOuterI != -1)
105     {
106         LTOuterPen = GetStockObject(DC_PEN);
107         SelectObject(hdc, LTOuterPen);
108         SetDCPenColor(hdc, scheme->crColor[LTOuterI]);
109         if (uFlags & BF_TOP)
110         {
111             MoveToEx(hdc, InnerRect.left, InnerRect.top, NULL);
112             LineTo(hdc, InnerRect.right, InnerRect.top);
113         }
114         if (uFlags & BF_LEFT)
115         {
116             MoveToEx(hdc, InnerRect.left, InnerRect.top, NULL);
117             LineTo(hdc, InnerRect.left, InnerRect.bottom);
118         }
119     }
120 
121     if (RBOuterI != -1)
122     {
123         RBOuterPen = GetStockObject(DC_PEN);
124         SelectObject(hdc, RBOuterPen);
125         SetDCPenColor(hdc, scheme->crColor[RBOuterI]);
126         if (uFlags & BF_BOTTOM)
127         {
128             MoveToEx(hdc, InnerRect.left, InnerRect.bottom-1, NULL);
129             LineTo(hdc, InnerRect.right, InnerRect.bottom-1);
130         }
131         if (uFlags & BF_RIGHT)
132         {
133             MoveToEx(hdc, InnerRect.right-1, InnerRect.top, NULL);
134             LineTo(hdc, InnerRect.right-1, InnerRect.bottom);
135         }
136     }
137 
138     /* Draw the inner edge */
139     if (LTInnerI != -1)
140     {
141         LTInnerPen = GetStockObject(DC_PEN);
142         SelectObject(hdc, LTInnerPen);
143         SetDCPenColor(hdc, scheme->crColor[LTInnerI]);
144         if (uFlags & BF_TOP)
145         {
146             MoveToEx(hdc, InnerRect.left+LTpenplus, InnerRect.top+1, NULL);
147             LineTo(hdc, InnerRect.right-RTpenplus, InnerRect.top+1);
148         }
149         if (uFlags & BF_LEFT)
150         {
151             MoveToEx(hdc, InnerRect.left+1, InnerRect.top+LTpenplus, NULL);
152             LineTo(hdc, InnerRect.left+1, InnerRect.bottom-LBpenplus);
153         }
154     }
155 
156     if (RBInnerI != -1)
157     {
158         RBInnerPen = GetStockObject(DC_PEN);
159         SelectObject(hdc, RBInnerPen);
160         SetDCPenColor(hdc, scheme->crColor[RBInnerI]);
161         if (uFlags & BF_BOTTOM)
162         {
163             MoveToEx(hdc, InnerRect.left+LBpenplus, InnerRect.bottom-2, NULL);
164             LineTo(hdc, InnerRect.right-RBpenplus, InnerRect.bottom-2);
165         }
166         if (uFlags & BF_RIGHT)
167         {
168             MoveToEx(hdc, InnerRect.right-2, InnerRect.top+RTpenplus, NULL);
169             LineTo(hdc, InnerRect.right-2, InnerRect.bottom-RBpenplus);
170         }
171     }
172 
173     if (uFlags & BF_ADJUST)
174     {
175         int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0)
176                       + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0);
177 
178         if (uFlags & BF_LEFT)
179             InnerRect.left += add;
180         if (uFlags & BF_RIGHT)
181             InnerRect.right -= add;
182         if (uFlags & BF_TOP)
183             InnerRect.top += add;
184         if (uFlags & BF_BOTTOM)
185             InnerRect.bottom -= add;
186 
187         if (uFlags & BF_ADJUST)
188             *rc = InnerRect;
189     }
190 
191     /* Cleanup */
192     SelectObject(hdc, SavePen);
193     MoveToEx(hdc, SavePoint.x, SavePoint.y, NULL);
194     return TRUE;
195 }
196 
197 static BOOL
MyDrawFrameButton(HDC hdc,LPRECT rc,UINT uState,COLOR_SCHEME * scheme)198 MyDrawFrameButton(HDC hdc, LPRECT rc, UINT uState, COLOR_SCHEME *scheme)
199 {
200     UINT edge;
201     if (uState & (DFCS_PUSHED | DFCS_CHECKED | DFCS_FLAT))
202         edge = EDGE_SUNKEN;
203     else
204         edge = EDGE_RAISED;
205     return MyIntDrawRectEdge(hdc, rc, edge, (uState & DFCS_FLAT) | BF_RECT | BF_SOFT, scheme);
206 }
207 
208 static int
MyMakeSquareRect(LPRECT src,LPRECT dst)209 MyMakeSquareRect(LPRECT src, LPRECT dst)
210 {
211     int Width  = src->right - src->left;
212     int Height = src->bottom - src->top;
213     int SmallDiam = Width > Height ? Height : Width;
214 
215     *dst = *src;
216 
217     /* Make it a square box */
218     if (Width < Height)      /* SmallDiam == Width */
219     {
220         dst->top += (Height-Width)/2;
221         dst->bottom = dst->top + SmallDiam;
222     }
223     else if (Width > Height) /* SmallDiam == Height */
224     {
225         dst->left += (Width-Height)/2;
226         dst->right = dst->left + SmallDiam;
227     }
228 
229     return SmallDiam;
230 }
231 
232 static BOOL
MyDrawFrameCaption(HDC dc,LPRECT r,UINT uFlags,COLOR_SCHEME * scheme)233 MyDrawFrameCaption(HDC dc, LPRECT r, UINT uFlags, COLOR_SCHEME *scheme)
234 {
235     LOGFONT lf;
236     HFONT hFont, hOldFont;
237     COLORREF clrsave;
238     RECT myr;
239     INT bkmode;
240     TCHAR Symbol;
241     switch(uFlags & 0xff)
242     {
243     case DFCS_CAPTIONCLOSE:
244         Symbol = 'r';
245         break;
246     case DFCS_CAPTIONHELP:
247         Symbol = 's';
248         break;
249     case DFCS_CAPTIONMIN:
250         Symbol = '0';
251         break;
252     case DFCS_CAPTIONMAX:
253         Symbol = '1';
254         break;
255     case DFCS_CAPTIONRESTORE:
256         Symbol = '2';
257         break;
258     default:
259         return FALSE;
260     }
261     MyIntDrawRectEdge(dc, r, (uFlags & DFCS_PUSHED) ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT | BF_MIDDLE | BF_SOFT, scheme);
262     ZeroMemory(&lf, sizeof(lf));
263     MyMakeSquareRect(r, &myr);
264     myr.left += 1;
265     myr.top += 1;
266     myr.right -= 1;
267     myr.bottom -= 1;
268     if (uFlags & DFCS_PUSHED)
269        OffsetRect(&myr,1,1);
270     lf.lfHeight = myr.bottom - myr.top;
271     lf.lfWidth = 0;
272     lf.lfWeight = FW_NORMAL;
273     lf.lfCharSet = DEFAULT_CHARSET;
274     lstrcpy(lf.lfFaceName, TEXT("Marlett"));
275     hFont = CreateFontIndirect(&lf);
276     /* Save font and text color */
277     hOldFont = SelectObject(dc, hFont);
278     clrsave = GetTextColor(dc);
279     bkmode = GetBkMode(dc);
280     /* Set color and drawing mode */
281     SetBkMode(dc, TRANSPARENT);
282     if (uFlags & DFCS_INACTIVE)
283     {
284         /* Draw shadow */
285         SetTextColor(dc, scheme->crColor[COLOR_BTNHIGHLIGHT]);
286         TextOut(dc, myr.left + 1, myr.top + 1, &Symbol, 1);
287     }
288     SetTextColor(dc, scheme->crColor[(uFlags & DFCS_INACTIVE) ? COLOR_BTNSHADOW : COLOR_BTNTEXT]);
289     /* Draw selected symbol */
290     TextOut(dc, myr.left, myr.top, &Symbol, 1);
291     /* Restore previous settings */
292     SetTextColor(dc, clrsave);
293     SelectObject(dc, hOldFont);
294     SetBkMode(dc, bkmode);
295     DeleteObject(hFont);
296     return TRUE;
297 }
298 
299 /******************************************************************************/
300 
301 static BOOL
MyDrawFrameScroll(HDC dc,LPRECT r,UINT uFlags,COLOR_SCHEME * scheme)302 MyDrawFrameScroll(HDC dc, LPRECT r, UINT uFlags, COLOR_SCHEME *scheme)
303 {
304     LOGFONT lf;
305     HFONT hFont, hOldFont;
306     COLORREF clrsave;
307     RECT myr;
308     INT bkmode;
309     TCHAR Symbol;
310     switch(uFlags & 0xff)
311     {
312     case DFCS_SCROLLCOMBOBOX:
313     case DFCS_SCROLLDOWN:
314         Symbol = '6';
315         break;
316 
317     case DFCS_SCROLLUP:
318         Symbol = '5';
319         break;
320 
321     case DFCS_SCROLLLEFT:
322         Symbol = '3';
323         break;
324 
325     case DFCS_SCROLLRIGHT:
326         Symbol = '4';
327         break;
328 
329     default:
330         return FALSE;
331     }
332     MyIntDrawRectEdge(dc, r, (uFlags & DFCS_PUSHED) ? EDGE_SUNKEN : EDGE_RAISED, (uFlags&DFCS_FLAT) | BF_MIDDLE | BF_RECT, scheme);
333     ZeroMemory(&lf, sizeof(lf));
334     MyMakeSquareRect(r, &myr);
335     myr.left += 1;
336     myr.top += 1;
337     myr.right -= 1;
338     myr.bottom -= 1;
339     if (uFlags & DFCS_PUSHED)
340        OffsetRect(&myr,1,1);
341     lf.lfHeight = myr.bottom - myr.top;
342     lf.lfWidth = 0;
343     lf.lfWeight = FW_NORMAL;
344     lf.lfCharSet = DEFAULT_CHARSET;
345     lstrcpy(lf.lfFaceName, TEXT("Marlett"));
346     hFont = CreateFontIndirect(&lf);
347     /* Save font and text color */
348     hOldFont = SelectObject(dc, hFont);
349     clrsave = GetTextColor(dc);
350     bkmode = GetBkMode(dc);
351     /* Set color and drawing mode */
352     SetBkMode(dc, TRANSPARENT);
353     if (uFlags & DFCS_INACTIVE)
354     {
355         /* Draw shadow */
356         SetTextColor(dc, scheme->crColor[COLOR_BTNHIGHLIGHT]);
357         TextOut(dc, myr.left + 1, myr.top + 1, &Symbol, 1);
358     }
359     SetTextColor(dc, scheme->crColor[(uFlags & DFCS_INACTIVE) ? COLOR_BTNSHADOW : COLOR_BTNTEXT]);
360     /* Draw selected symbol */
361     TextOut(dc, myr.left, myr.top, &Symbol, 1);
362     /* restore previous settings */
363     SetTextColor(dc, clrsave);
364     SelectObject(dc, hOldFont);
365     SetBkMode(dc, bkmode);
366     DeleteObject(hFont);
367     return TRUE;
368 }
369 
370 BOOL
MyDrawFrameControl(HDC hDC,LPRECT rc,UINT uType,UINT uState,COLOR_SCHEME * scheme)371 MyDrawFrameControl(HDC hDC, LPRECT rc, UINT uType, UINT uState, COLOR_SCHEME *scheme)
372 {
373     switch(uType)
374     {
375     case DFC_BUTTON:
376         return MyDrawFrameButton(hDC, rc, uState, scheme);
377     case DFC_CAPTION:
378         return MyDrawFrameCaption(hDC, rc, uState, scheme);
379     case DFC_SCROLL:
380         return MyDrawFrameScroll(hDC, rc, uState, scheme);
381     }
382     return FALSE;
383 }
384 
385 BOOL
MyDrawEdge(HDC hDC,LPRECT rc,UINT edge,UINT flags,COLOR_SCHEME * scheme)386 MyDrawEdge(HDC hDC, LPRECT rc, UINT edge, UINT flags, COLOR_SCHEME *scheme)
387 {
388     return MyIntDrawRectEdge(hDC, rc, edge, flags, scheme);
389 }
390 
391 VOID
MyDrawCaptionButtons(HDC hdc,LPRECT lpRect,BOOL bMinMax,int x,COLOR_SCHEME * scheme)392 MyDrawCaptionButtons(HDC hdc, LPRECT lpRect, BOOL bMinMax, int x, COLOR_SCHEME *scheme)
393 {
394     RECT rc3;
395     RECT rc4;
396     RECT rc5;
397 
398     rc3.left = lpRect->right - 2 - x;
399     rc3.top = lpRect->top + 2;
400     rc3.right = lpRect->right - 2;
401     rc3.bottom = lpRect->bottom - 2;
402 
403     MyDrawFrameControl(hdc, &rc3, DFC_CAPTION, DFCS_CAPTIONCLOSE, scheme);
404 
405     if (bMinMax)
406     {
407         rc4.left = rc3.left - x - 2;
408         rc4.top = rc3.top;
409         rc4.right = rc3.right - x - 2;
410         rc4.bottom = rc3.bottom;
411 
412         MyDrawFrameControl(hdc, &rc4, DFC_CAPTION, DFCS_CAPTIONMAX, scheme);
413 
414         rc5.left = rc4.left - x;
415         rc5.top = rc4.top;
416         rc5.right = rc4.right - x;
417         rc5.bottom = rc4.bottom;
418 
419         MyDrawFrameControl(hdc, &rc5, DFC_CAPTION, DFCS_CAPTIONMIN, scheme);
420     }
421 }
422 
423 VOID
MyDrawScrollbar(HDC hdc,LPRECT rc,HBRUSH hbrScrollbar,COLOR_SCHEME * scheme)424 MyDrawScrollbar(HDC hdc, LPRECT rc, HBRUSH hbrScrollbar, COLOR_SCHEME *scheme)
425 {
426     RECT rcTop;
427     RECT rcBottom;
428     RECT rcMiddle;
429     int width;
430 
431     width = rc->right - rc->left;
432 
433     rcTop.left = rc->left;
434     rcTop.right = rc->right;
435     rcTop.top = rc->top;
436     rcTop.bottom = rc->top + width;
437 
438     rcMiddle.left = rc->left;
439     rcMiddle.right = rc->right;
440     rcMiddle.top = rc->top + width;
441     rcMiddle.bottom = rc->bottom - width;
442 
443     rcBottom.left = rc->left;
444     rcBottom.right = rc->right;
445     rcBottom.top = rc->bottom - width;
446     rcBottom.bottom = rc->bottom;
447 
448     MyDrawFrameControl(hdc, &rcTop, DFC_SCROLL, DFCS_SCROLLUP, scheme);
449     MyDrawFrameControl(hdc, &rcBottom, DFC_SCROLL, DFCS_SCROLLDOWN, scheme);
450 
451     FillRect(hdc, &rcMiddle, hbrScrollbar);
452 }
453 
454 /******************************************************************************/
455 
456 BOOL
MyDrawCaptionTemp(HWND hwnd,HDC hdc,const RECT * rect,HFONT hFont,HICON hIcon,LPCWSTR str,UINT uFlags,COLOR_SCHEME * scheme)457 MyDrawCaptionTemp(HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont, HICON hIcon, LPCWSTR str, UINT uFlags, COLOR_SCHEME *scheme)
458 {
459     //ULONG Height;
460     //UINT VCenter, Padding;
461     //LONG ButtonWidth;
462     HBRUSH hbr;
463     HGDIOBJ hFontOld;
464     RECT rc;
465 
466     //Height = scheme->Size[SIZE_CAPTION_Y] - 1;
467     //VCenter = (rect->bottom - rect->top) / 2;
468     //Padding = VCenter - (Height / 2);
469 
470     //ButtonWidth = scheme->Size[SIZE_SIZE_X] - 2;
471 
472     if (uFlags & DC_GRADIENT)
473     {
474         GRADIENT_RECT gcap = {0, 1};
475         TRIVERTEX vert[2];
476         COLORREF Colors[2];
477 
478         Colors[0] = scheme->crColor[((uFlags & DC_ACTIVE) ?
479             COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION)];
480         Colors[1] = scheme->crColor[((uFlags & DC_ACTIVE) ?
481             COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION)];
482 
483         vert[0].x = rect->left;
484         vert[0].y = rect->top;
485         vert[0].Red = (WORD)Colors[0]<<8;
486         vert[0].Green = (WORD)Colors[0] & 0xFF00;
487         vert[0].Blue = (WORD)(Colors[0]>>8) & 0xFF00;
488         vert[0].Alpha = 0;
489 
490         vert[1].x = rect->right;
491         vert[1].y = rect->bottom;
492         vert[1].Red = (WORD)Colors[1]<<8;
493         vert[1].Green = (WORD)Colors[1] & 0xFF00;
494         vert[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00;
495         vert[1].Alpha = 0;
496 
497         GdiGradientFill(hdc, vert, 2, &gcap, 1, GRADIENT_FILL_RECT_H);
498     }
499     else
500     {
501         if (uFlags & DC_ACTIVE)
502             hbr = CreateSolidBrush(scheme->crColor[COLOR_ACTIVECAPTION]);
503         else
504             hbr = CreateSolidBrush(scheme->crColor[COLOR_INACTIVECAPTION]);
505         FillRect(hdc, rect, hbr);
506         DeleteObject(hbr);
507     }
508 
509     hFontOld = SelectObject(hdc, hFont);
510     SetBkMode(hdc, TRANSPARENT);
511     if (uFlags & DC_ACTIVE)
512         SetTextColor(hdc, scheme->crColor[COLOR_CAPTIONTEXT]);
513     else
514         SetTextColor(hdc, scheme->crColor[COLOR_INACTIVECAPTIONTEXT]);
515     rc.left = rect->left + 2;
516     rc.top = rect->top;
517     rc.right = rect->right;
518     rc.bottom = rect->bottom;
519     DrawTextW(hdc, str, -1, &rc, DT_SINGLELINE | DT_VCENTER);
520     SelectObject(hdc, hFontOld);
521     return TRUE;
522 }
523 
524 /******************************************************************************/
525 
526 DWORD
MyDrawMenuBarTemp(HWND Wnd,HDC DC,LPRECT Rect,HMENU Menu,HFONT Font,COLOR_SCHEME * scheme)527 MyDrawMenuBarTemp(HWND Wnd, HDC DC, LPRECT Rect, HMENU Menu, HFONT Font, COLOR_SCHEME *scheme)
528 {
529     HBRUSH hbr;
530     HPEN hPen;
531     HGDIOBJ hPenOld, hFontOld;
532     BOOL flat_menu;
533     INT i, bkgnd, x;
534     RECT rect;
535     WCHAR Text[128];
536     UINT uFormat = DT_CENTER | DT_VCENTER | DT_SINGLELINE;
537 
538     flat_menu = scheme->bFlatMenus;
539 
540     if (flat_menu)
541         hbr = CreateSolidBrush(scheme->crColor[COLOR_MENUBAR]);
542     else
543         hbr = CreateSolidBrush(scheme->crColor[COLOR_MENU]);
544     FillRect(DC, Rect, hbr);
545     DeleteObject(hbr);
546 
547     hPen = CreatePen(PS_SOLID, 0, scheme->crColor[COLOR_3DFACE]);
548     hPenOld = SelectObject(DC, hPen);
549     MoveToEx(DC, Rect->left, Rect->bottom - 1, NULL);
550     LineTo(DC, Rect->right, Rect->bottom - 1);
551     SelectObject(DC, hPenOld);
552     DeleteObject(hPen);
553 
554     bkgnd = (flat_menu ? COLOR_MENUBAR : COLOR_MENU);
555     x = Rect->left;
556     hFontOld = SelectObject(DC, Font);
557     for (i = 0; i < 3; i++)
558     {
559         GetMenuStringW(Menu, i, Text, 128, MF_BYPOSITION);
560 
561         rect.left = rect.right = x;
562         rect.top = Rect->top;
563         rect.bottom = Rect->bottom;
564         DrawTextW(DC, Text, -1, &rect, DT_SINGLELINE | DT_CALCRECT);
565         rect.bottom = Rect->bottom;
566         rect.right += MENU_BAR_ITEMS_SPACE;
567         x += rect.right - rect.left;
568 
569         if (i == 2)
570         {
571             if (flat_menu)
572             {
573                 SetTextColor(DC, scheme->crColor[COLOR_HIGHLIGHTTEXT]);
574                 SetBkColor(DC, scheme->crColor[COLOR_HIGHLIGHT]);
575 
576                 InflateRect (&rect, -1, -1);
577                 hbr = CreateSolidBrush(scheme->crColor[COLOR_MENUHILIGHT]);
578                 FillRect(DC, &rect, hbr);
579                 DeleteObject(hbr);
580 
581                 InflateRect (&rect, 1, 1);
582                 hbr = CreateSolidBrush(scheme->crColor[COLOR_HIGHLIGHT]);
583                 FrameRect(DC, &rect, hbr);
584                 DeleteObject(hbr);
585             }
586             else
587             {
588                 SetTextColor(DC, scheme->crColor[COLOR_MENUTEXT]);
589                 SetBkColor(DC, scheme->crColor[COLOR_MENU]);
590                 DrawEdge(DC, &rect, BDR_SUNKENOUTER, BF_RECT);
591             }
592         }
593         else
594         {
595             if (i == 1)
596                 SetTextColor(DC, scheme->crColor[COLOR_GRAYTEXT]);
597             else
598                 SetTextColor(DC, scheme->crColor[COLOR_MENUTEXT]);
599 
600             SetBkColor(DC, scheme->crColor[bkgnd]);
601             hbr = CreateSolidBrush(scheme->crColor[bkgnd]);
602             FillRect(DC, &rect, hbr);
603             DeleteObject(hbr);
604         }
605 
606         SetBkMode(DC, TRANSPARENT);
607 
608         rect.left += MENU_BAR_ITEMS_SPACE / 2;
609         rect.right -= MENU_BAR_ITEMS_SPACE / 2;
610 
611         if (i == 1)
612         {
613             ++rect.left; ++rect.top; ++rect.right; ++rect.bottom;
614             SetTextColor(DC, scheme->crColor[COLOR_BTNHIGHLIGHT]);
615             DrawTextW(DC, Text, -1, &rect, uFormat);
616             --rect.left; --rect.top; --rect.right; --rect.bottom;
617             SetTextColor(DC, scheme->crColor[COLOR_BTNSHADOW]);
618         }
619         DrawTextW(DC, Text, -1, &rect, uFormat);
620     }
621     SelectObject(DC, hFontOld);
622 
623     return TRUE;
624 }
625