2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS uxtheme.dll
4 * FILE: dll/win32/uxtheme/nonclient.c
5 * PURPOSE: uxtheme non client area management
6 * PROGRAMMER: Giannis Adamopoulos
11 #include "undocuser.h"
17 #include "wine/debug.h"
19 WINE_DEFAULT_DEBUG_CHANNEL(uxtheme
);
21 HFONT hMenuFont
= NULL
;
22 HFONT hMenuFontBold
= NULL
;
24 void InitMenuFont(VOID
)
28 ncm
.cbSize
= sizeof(NONCLIENTMETRICS
);
30 if(!SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, sizeof(ncm
), &ncm
, 0))
35 hMenuFont
= CreateFontIndirect(&ncm
.lfMenuFont
);
37 ncm
.lfMenuFont
.lfWeight
= max(ncm
.lfMenuFont
.lfWeight
+ 300, 1000);
38 hMenuFontBold
= CreateFontIndirect(&ncm
.lfMenuFont
);
43 IsWindowActive(HWND hWnd
, DWORD ExStyle
)
47 if (ExStyle
& WS_EX_MDICHILD
)
49 ret
= IsChild(GetForegroundWindow(), hWnd
);
51 ret
= (hWnd
== (HWND
)SendMessageW(GetParent(hWnd
), WM_MDIGETACTIVE
, 0, 0));
55 ret
= (GetForegroundWindow() == hWnd
);
62 UserHasWindowEdge(DWORD Style
, DWORD ExStyle
)
64 if (Style
& WS_MINIMIZE
)
66 if (ExStyle
& WS_EX_DLGMODALFRAME
)
68 if (ExStyle
& WS_EX_STATICEDGE
)
70 if (Style
& WS_THICKFRAME
)
72 if (Style
== WS_DLGFRAME
|| Style
== WS_CAPTION
)
78 UserGetWindowIcon(HWND hwnd
)
82 SendMessageTimeout(hwnd
, WM_GETICON
, ICON_SMALL2
, 0, SMTO_ABORTIFHUNG
, 1000, (PDWORD_PTR
)&hIcon
);
85 SendMessageTimeout(hwnd
, WM_GETICON
, ICON_SMALL
, 0, SMTO_ABORTIFHUNG
, 1000, (PDWORD_PTR
)&hIcon
);
88 SendMessageTimeout(hwnd
, WM_GETICON
, ICON_BIG
, 0, SMTO_ABORTIFHUNG
, 1000, (PDWORD_PTR
)&hIcon
);
91 hIcon
= (HICON
)GetClassLong(hwnd
, GCL_HICONSM
);
94 hIcon
= (HICON
)GetClassLong(hwnd
, GCL_HICON
);
97 hIcon
= LoadIcon(NULL
, IDI_WINLOGO
);
102 WCHAR
*UserGetWindowCaption(HWND hwnd
)
106 text
= (WCHAR
*)HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
107 if (text
) InternalGetWindowText(hwnd
, text
, len
);
112 ThemeDrawTitle(PDRAW_CONTEXT context
, RECT
* prcCurrent
)
117 HRESULT WINAPI
ThemeDrawCaptionText(HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
,
118 LPCWSTR pszText
, int iCharCount
, DWORD dwTextFlags
,
119 DWORD dwTextFlags2
, const RECT
*pRect
, BOOL Active
)
123 HGDIOBJ oldFont
= NULL
;
126 COLORREF oldTextColor
;
130 hr
= GetThemeSysFont(0,TMT_CAPTIONFONT
,&logfont
);
133 hFont
= CreateFontIndirectW(&logfont
);
135 CopyRect(&rt
, pRect
);
137 oldFont
= SelectObject(hdc
, hFont
);
139 if(dwTextFlags2
& DTT_GRAYED
)
140 textColor
= GetSysColor(COLOR_GRAYTEXT
);
142 textColor
= GetSysColor(COLOR_INACTIVECAPTIONTEXT
);
144 textColor
= GetSysColor(COLOR_CAPTIONTEXT
);
146 oldTextColor
= SetTextColor(hdc
, textColor
);
147 oldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
148 DrawTextW(hdc
, pszText
, iCharCount
, &rt
, dwTextFlags
);
149 SetBkMode(hdc
, oldBkMode
);
150 SetTextColor(hdc
, oldTextColor
);
153 SelectObject(hdc
, oldFont
);
160 ThemeInitDrawContext(PDRAW_CONTEXT pcontext
,
164 pcontext
->wi
.cbSize
= sizeof(pcontext
->wi
);
165 GetWindowInfo(hWnd
, &pcontext
->wi
);
166 pcontext
->hWnd
= hWnd
;
167 pcontext
->Active
= IsWindowActive(hWnd
, pcontext
->wi
.dwExStyle
);
168 pcontext
->hPrevTheme
= GetPropW(hWnd
, (LPCWSTR
)MAKEINTATOM(atWindowTheme
));
169 pcontext
->theme
= OpenThemeData(pcontext
->hWnd
, L
"WINDOW");
170 pcontext
->scrolltheme
= OpenThemeData(pcontext
->hWnd
, L
"SCROLLBAR");
172 pcontext
->CaptionHeight
= pcontext
->wi
.cyWindowBorders
;
173 pcontext
->CaptionHeight
+= GetSystemMetrics(pcontext
->wi
.dwExStyle
& WS_EX_TOOLWINDOW
? SM_CYSMCAPTION
: SM_CYCAPTION
);
177 hRgn
= CreateRectRgnIndirect(&pcontext
->wi
.rcWindow
);
179 pcontext
->hRgn
= hRgn
;
181 pcontext
->hDC
= GetDCEx(hWnd
, hRgn
, DCX_WINDOW
| DCX_INTERSECTRGN
| DCX_USESTYLE
| DCX_KEEPCLIPRGN
);
185 ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext
)
187 ReleaseDC(pcontext
->hWnd
,pcontext
->hDC
);
189 CloseThemeData (pcontext
->theme
);
190 CloseThemeData (pcontext
->scrolltheme
);
192 SetPropW(pcontext
->hWnd
, (LPCWSTR
)MAKEINTATOM(atWindowTheme
), pcontext
->hPrevTheme
);
194 if(pcontext
->hRgn
!= NULL
)
196 DeleteObject(pcontext
->hRgn
);
201 ThemeStartBufferedPaint(PDRAW_CONTEXT pcontext
, int cx
, int cy
)
205 pcontext
->hDCScreen
= pcontext
->hDC
;
206 pcontext
->hDC
= CreateCompatibleDC(pcontext
->hDCScreen
);
207 hbmp
= CreateCompatibleBitmap(pcontext
->hDCScreen
, cx
, cy
);
208 pcontext
->hbmpOld
= (HBITMAP
)SelectObject(pcontext
->hDC
, hbmp
);
212 ThemeEndBufferedPaint(PDRAW_CONTEXT pcontext
, int x
, int y
, int cx
, int cy
)
215 BitBlt(pcontext
->hDCScreen
, 0, 0, cx
, cy
, pcontext
->hDC
, x
, y
, SRCCOPY
);
216 hbmp
= (HBITMAP
) SelectObject(pcontext
->hDC
, pcontext
->hbmpOld
);
217 DeleteObject(pcontext
->hDC
);
220 pcontext
->hDC
= pcontext
->hDCScreen
;
224 ThemeDrawCaptionButton(PDRAW_CONTEXT pcontext
,
226 CAPTIONBUTTON buttonId
,
230 INT ButtonWidth
, ButtonHeight
, iPartId
;
232 ButtonHeight
= GetSystemMetrics( pcontext
->wi
.dwExStyle
& WS_EX_TOOLWINDOW
? SM_CYSMSIZE
: SM_CYSIZE
);
233 ButtonWidth
= GetSystemMetrics( pcontext
->wi
.dwExStyle
& WS_EX_TOOLWINDOW
? SM_CXSMSIZE
: SM_CXSIZE
);
238 iPartId
= pcontext
->wi
.dwExStyle
& WS_EX_TOOLWINDOW
? WP_SMALLCLOSEBUTTON
: WP_CLOSEBUTTON
;
242 if (!(pcontext
->wi
.dwStyle
& WS_MAXIMIZEBOX
))
244 if (!(pcontext
->wi
.dwStyle
& WS_MINIMIZEBOX
))
247 iStateId
= BUTTON_DISABLED
;
250 iPartId
= pcontext
->wi
.dwStyle
& WS_MAXIMIZE
? WP_RESTOREBUTTON
: WP_MAXBUTTON
;
254 if (!(pcontext
->wi
.dwStyle
& WS_MINIMIZEBOX
))
256 if (!(pcontext
->wi
.dwStyle
& WS_MAXIMIZEBOX
))
259 iStateId
= BUTTON_DISABLED
;
262 iPartId
= WP_MINBUTTON
;
266 //FIXME: Implement Help Button
273 /* Calculate the position */
274 rcPart
.top
= prcCurrent
->top
;
275 rcPart
.right
= prcCurrent
->right
;
276 rcPart
.bottom
= rcPart
.top
+ ButtonHeight
;
277 rcPart
.left
= rcPart
.right
- ButtonWidth
;
278 prcCurrent
->right
-= ButtonWidth
+ BUTTON_GAP_SIZE
;
280 DrawThemeBackground(pcontext
->theme
, pcontext
->hDC
, iPartId
, iStateId
, &rcPart
, NULL
);
284 ThemeGetButtonState(DWORD htCurrect
, DWORD htHot
, DWORD htDown
, BOOL Active
)
286 if (htHot
== htCurrect
)
289 return BUTTON_INACTIVE
;
290 if (htDown
== htCurrect
)
291 return BUTTON_PRESSED
;
293 return BUTTON_NORMAL
;
296 /* Used only from mouse event handlers */
298 ThemeDrawCaptionButtons(PDRAW_CONTEXT pcontext
, DWORD htHot
, DWORD htDown
)
302 /* Check if the window has caption buttons */
303 if (!((pcontext
->wi
.dwStyle
& WS_CAPTION
) && (pcontext
->wi
.dwStyle
& WS_SYSMENU
)))
306 rcCurrent
.top
= rcCurrent
.left
= 0;
307 rcCurrent
.right
= pcontext
->wi
.rcWindow
.right
- pcontext
->wi
.rcWindow
.left
;
308 rcCurrent
.bottom
= pcontext
->CaptionHeight
;
310 /* Add a padding around the objects of the caption */
311 InflateRect(&rcCurrent
, -(int)pcontext
->wi
.cyWindowBorders
-BUTTON_GAP_SIZE
,
312 -(int)pcontext
->wi
.cyWindowBorders
-BUTTON_GAP_SIZE
);
314 /* Draw the buttons */
315 ThemeDrawCaptionButton(pcontext
, &rcCurrent
, CLOSEBUTTON
,
316 ThemeGetButtonState(HTCLOSE
, htHot
, htDown
, pcontext
->Active
));
317 ThemeDrawCaptionButton(pcontext
, &rcCurrent
, MAXBUTTON
,
318 ThemeGetButtonState(HTMAXBUTTON
, htHot
, htDown
, pcontext
->Active
));
319 ThemeDrawCaptionButton(pcontext
, &rcCurrent
, MINBUTTON
,
320 ThemeGetButtonState(HTMINBUTTON
, htHot
, htDown
, pcontext
->Active
));
321 ThemeDrawCaptionButton(pcontext
, &rcCurrent
, HELPBUTTON
,
322 ThemeGetButtonState(HTHELP
, htHot
, htDown
, pcontext
->Active
));
325 /* Used from WM_NCPAINT and WM_NCACTIVATE handlers*/
327 ThemeDrawCaption(PDRAW_CONTEXT pcontext
, RECT
* prcCurrent
)
334 hIcon
= UserGetWindowIcon(pcontext
->hWnd
);
335 CaptionText
= UserGetWindowCaption(pcontext
->hWnd
);
337 /* Get the caption part and state id */
338 if (pcontext
->wi
.dwExStyle
& WS_EX_TOOLWINDOW
)
339 iPart
= WP_SMALLCAPTION
;
340 else if (pcontext
->wi
.dwStyle
& WS_MAXIMIZE
)
341 iPart
= WP_MAXCAPTION
;
345 iState
= pcontext
->Active
? FS_ACTIVE
: FS_INACTIVE
;
347 /* Draw the caption background*/
348 rcPart
= *prcCurrent
;
349 rcPart
.bottom
= pcontext
->CaptionHeight
;
350 prcCurrent
->top
= rcPart
.bottom
;
351 DrawThemeBackground(pcontext
->theme
, pcontext
->hDC
,iPart
,iState
,&rcPart
,NULL
);
353 /* Add a padding around the objects of the caption */
354 InflateRect(&rcPart
, -(int)pcontext
->wi
.cyWindowBorders
-BUTTON_GAP_SIZE
,
355 -(int)pcontext
->wi
.cyWindowBorders
-BUTTON_GAP_SIZE
);
357 /* Draw the caption buttons */
358 if (pcontext
->wi
.dwStyle
& WS_SYSMENU
)
360 iState
= pcontext
->Active
? BUTTON_NORMAL
: BUTTON_INACTIVE
;
362 ThemeDrawCaptionButton(pcontext
, &rcPart
, CLOSEBUTTON
, iState
);
363 ThemeDrawCaptionButton(pcontext
, &rcPart
, MAXBUTTON
, iState
);
364 ThemeDrawCaptionButton(pcontext
, &rcPart
, MINBUTTON
, iState
);
365 ThemeDrawCaptionButton(pcontext
, &rcPart
, HELPBUTTON
, iState
);
371 if(hIcon
&& !(pcontext
->wi
.dwExStyle
& WS_EX_TOOLWINDOW
))
373 int IconHeight
= GetSystemMetrics(SM_CYSMICON
);
374 int IconWidth
= GetSystemMetrics(SM_CXSMICON
);
375 DrawIconEx(pcontext
->hDC
, rcPart
.left
, rcPart
.top
, hIcon
, IconWidth
, IconHeight
, 0, NULL
, DI_NORMAL
);
376 rcPart
.left
+= IconWidth
+ 4;
381 /* Draw the caption */
384 /*FIXME: Use DrawThemeTextEx*/
385 ThemeDrawCaptionText(pcontext
->theme
,
390 lstrlenW(CaptionText
),
391 DT_VCENTER
| DT_SINGLELINE
| DT_END_ELLIPSIS
,
395 HeapFree(GetProcessHeap(), 0, CaptionText
);
400 ThemeDrawBorders(PDRAW_CONTEXT pcontext
, RECT
* prcCurrent
)
403 int iState
= pcontext
->Active
? FS_ACTIVE
: FS_INACTIVE
;
405 /* Draw the bottom border */
406 rcPart
= *prcCurrent
;
407 rcPart
.top
= rcPart
.bottom
- pcontext
->wi
.cyWindowBorders
;
408 prcCurrent
->bottom
= rcPart
.top
;
409 DrawThemeBackground(pcontext
->theme
, pcontext
->hDC
, WP_FRAMEBOTTOM
, iState
, &rcPart
, NULL
);
411 /* Draw the left border */
412 rcPart
= *prcCurrent
;
413 rcPart
.right
= pcontext
->wi
.cxWindowBorders
;
414 prcCurrent
->left
= rcPart
.right
;
415 DrawThemeBackground(pcontext
->theme
, pcontext
->hDC
,WP_FRAMELEFT
, iState
, &rcPart
, NULL
);
417 /* Draw the right border */
418 rcPart
= *prcCurrent
;
419 rcPart
.left
= rcPart
.right
- pcontext
->wi
.cxWindowBorders
;
420 prcCurrent
->right
= rcPart
.left
;
421 DrawThemeBackground(pcontext
->theme
, pcontext
->hDC
,WP_FRAMERIGHT
, iState
, &rcPart
, NULL
);
425 DrawClassicFrame(PDRAW_CONTEXT context
, RECT
* prcCurrent
)
427 /* Draw outer edge */
428 if (UserHasWindowEdge(context
->wi
.dwStyle
, context
->wi
.dwExStyle
))
430 DrawEdge(context
->hDC
, prcCurrent
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
432 else if (context
->wi
.dwExStyle
& WS_EX_STATICEDGE
)
434 DrawEdge(context
->hDC
, prcCurrent
, BDR_SUNKENINNER
, BF_RECT
| BF_ADJUST
| BF_FLAT
);
437 /* Firstly the "thick" frame */
438 if ((context
->wi
.dwStyle
& WS_THICKFRAME
) && !(context
->wi
.dwStyle
& WS_MINIMIZE
))
441 (GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
)) *
442 GetSystemMetrics(SM_CXBORDER
);
444 (GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
)) *
445 GetSystemMetrics(SM_CYBORDER
);
447 SelectObject(context
->hDC
, GetSysColorBrush(
448 context
->Active
? COLOR_ACTIVEBORDER
: COLOR_INACTIVEBORDER
));
451 PatBlt(context
->hDC
, prcCurrent
->left
, prcCurrent
->top
,
452 prcCurrent
->right
- prcCurrent
->left
, Height
, PATCOPY
);
453 PatBlt(context
->hDC
, prcCurrent
->left
, prcCurrent
->top
,
454 Width
, prcCurrent
->bottom
- prcCurrent
->top
, PATCOPY
);
455 PatBlt(context
->hDC
, prcCurrent
->left
, prcCurrent
->bottom
,
456 prcCurrent
->right
- prcCurrent
->left
, -Height
, PATCOPY
);
457 PatBlt(context
->hDC
, prcCurrent
->right
, prcCurrent
->top
,
458 -Width
, prcCurrent
->bottom
- prcCurrent
->top
, PATCOPY
);
460 InflateRect(prcCurrent
, -Width
, -Height
);
463 /* Now the other bit of the frame */
464 if (context
->wi
.dwStyle
& (WS_DLGFRAME
| WS_BORDER
) || context
->wi
.dwExStyle
& WS_EX_DLGMODALFRAME
)
466 INT Width
= GetSystemMetrics(SM_CXBORDER
);
467 INT Height
= GetSystemMetrics(SM_CYBORDER
);
469 SelectObject(context
->hDC
, GetSysColorBrush(
470 (context
->wi
.dwExStyle
& (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
)) ? COLOR_3DFACE
:
471 (context
->wi
.dwExStyle
& WS_EX_STATICEDGE
) ? COLOR_WINDOWFRAME
:
472 (context
->wi
.dwStyle
& (WS_DLGFRAME
| WS_THICKFRAME
)) ? COLOR_3DFACE
:
476 PatBlt(context
->hDC
, prcCurrent
->left
, prcCurrent
->top
,
477 prcCurrent
->right
- prcCurrent
->left
, Height
, PATCOPY
);
478 PatBlt(context
->hDC
, prcCurrent
->left
, prcCurrent
->top
,
479 Width
, prcCurrent
->bottom
- prcCurrent
->top
, PATCOPY
);
480 PatBlt(context
->hDC
, prcCurrent
->left
, prcCurrent
->bottom
,
481 prcCurrent
->right
- prcCurrent
->left
, -Height
, PATCOPY
);
482 PatBlt(context
->hDC
, prcCurrent
->right
, prcCurrent
->top
,
483 -Width
, prcCurrent
->bottom
- prcCurrent
->top
, PATCOPY
);
485 InflateRect(prcCurrent
, -Width
, -Height
);
488 if (context
->wi
.dwExStyle
& WS_EX_CLIENTEDGE
)
490 DrawEdge(context
->hDC
, prcCurrent
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
495 ThemeDrawMenuItem(PDRAW_CONTEXT pcontext
, HMENU Menu
, int imenu
)
498 BOOL flat_menu
= FALSE
;
501 WCHAR wstrItemText
[20];
503 HFONT FontOld
= NULL
;
504 UINT uFormat
= DT_CENTER
| DT_VCENTER
| DT_SINGLELINE
;
506 Item
.cbSize
= sizeof(MENUITEMINFOW
);
507 Item
.fMask
= MIIM_FTYPE
| MIIM_STATE
| MIIM_STRING
;
508 Item
.dwTypeData
= wstrItemText
;
510 if (!GetMenuItemInfoW(Menu
, imenu
, TRUE
, &Item
))
513 if(Item
.fType
& MF_SEPARATOR
)
519 Item
.dwTypeData
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, Item
.cch
* sizeof(WCHAR
));
520 Item
.fMask
= MIIM_FTYPE
| MIIM_STATE
| MIIM_STRING
;
521 GetMenuItemInfoW(Menu
, imenu
, TRUE
, &Item
);
527 flat_menu
= GetThemeSysBool(pcontext
->theme
, TMT_FLATMENUS
);
529 GetMenuItemRect(pcontext
->hWnd
, Menu
, imenu
, &Rect
);
532 OffsetRect(&Rect
, -pcontext
->wi
.rcClient
.left
, -pcontext
->wi
.rcClient
.top
);
534 OffsetRect(&Rect
, -pcontext
->wi
.rcWindow
.left
, -pcontext
->wi
.rcWindow
.top
);
537 SetBkColor(pcontext
->hDC
, GetSysColor(flat_menu
? COLOR_MENUBAR
: COLOR_MENU
));
538 SetTextColor(pcontext
->hDC
, GetSysColor(Item
.fState
& MF_GRAYED
? COLOR_GRAYTEXT
: COLOR_MENUTEXT
));
540 if (0 != (Item
.fState
& MFS_DEFAULT
))
542 FontOld
= (HFONT
)SelectObject(pcontext
->hDC
, hMenuFontBold
);
545 Rect
.left
+= MENU_BAR_ITEMS_SPACE
/ 2;
546 Rect
.right
-= MENU_BAR_ITEMS_SPACE
/ 2;
548 Text
= (PWCHAR
) Item
.dwTypeData
;
551 for (i
= 0; L
'\0' != Text
[i
]; i
++)
553 if (L
'\t' == Text
[i
] || L
'\b' == Text
[i
])
560 SetBkMode(pcontext
->hDC
, OPAQUE
);
562 if (0 != (Item
.fState
& MF_GRAYED
))
564 if (0 == (Item
.fState
& MF_HILITE
))
566 ++Rect
.left
; ++Rect
.top
; ++Rect
.right
; ++Rect
.bottom
;
567 SetTextColor(pcontext
->hDC
, RGB(0xff, 0xff, 0xff));
568 DrawTextW(pcontext
->hDC
, Text
, i
, &Rect
, uFormat
);
569 --Rect
.left
; --Rect
.top
; --Rect
.right
; --Rect
.bottom
;
571 SetTextColor(pcontext
->hDC
, RGB(0x80, 0x80, 0x80));
572 SetBkMode(pcontext
->hDC
, TRANSPARENT
);
575 DrawTextW(pcontext
->hDC
, Text
, i
, &Rect
, uFormat
);
577 /* Exclude from the clip region the area drawn by DrawText */
578 SetRect(&rcCalc
, 0,0,0,0);
579 DrawTextW(pcontext
->hDC
, Text
, i
, &rcCalc
, uFormat
| DT_CALCRECT
);
580 InflateRect( &Rect
, 0, -(rcCalc
.bottom
+1)/2);
581 ExcludeClipRect(pcontext
->hDC
, Rect
.left
, Rect
.top
, Rect
.right
, Rect
.bottom
);
585 SelectObject(pcontext
->hDC
, FontOld
);
590 ThemeDrawMenuBar(PDRAW_CONTEXT pcontext
, PRECT prcCurrent
)
593 MENUBARINFO MenuBarInfo
;
595 HFONT FontOld
= NULL
;
603 flat_menu
= GetThemeSysBool(pcontext
->theme
, TMT_FLATMENUS
);
605 MenuBarInfo
.cbSize
= sizeof(MENUBARINFO
);
606 if (! GetMenuBarInfo(pcontext
->hWnd
, OBJID_MENU
, 0, &MenuBarInfo
))
609 Menu
= GetMenu(pcontext
->hWnd
);
610 if (GetMenuItemCount(Menu
) == 0)
613 Rect
= MenuBarInfo
.rcBar
;
614 OffsetRect(&Rect
, -pcontext
->wi
.rcWindow
.left
, -pcontext
->wi
.rcWindow
.top
);
616 /* Draw a line under the menu*/
617 oldPen
= (HPEN
)SelectObject(pcontext
->hDC
, GetStockObject(DC_PEN
));
618 SetDCPenColor(pcontext
->hDC
, GetSysColor(COLOR_3DFACE
));
619 MoveToEx(pcontext
->hDC
, Rect
.left
, Rect
.bottom
, NULL
);
620 LineTo(pcontext
->hDC
, Rect
.right
, Rect
.bottom
);
621 SelectObject(pcontext
->hDC
, oldPen
);
623 /* Draw menu items */
624 FontOld
= (HFONT
)SelectObject(pcontext
->hDC
, hMenuFont
);
626 for (i
= 0; i
< GetMenuItemCount(Menu
); i
++)
628 ThemeDrawMenuItem(pcontext
, Menu
, i
);
631 SelectObject(pcontext
->hDC
, FontOld
);
633 /* Fill the menu background area that isn't painted yet*/
634 FillRect(pcontext
->hDC
, &Rect
, GetSysColorBrush(flat_menu
? COLOR_MENUBAR
: COLOR_MENU
));
638 ThemePaintWindow(PDRAW_CONTEXT pcontext
, RECT
* prcCurrent
)
640 if(!(pcontext
->wi
.dwStyle
& WS_VISIBLE
))
643 if(pcontext
->wi
.dwStyle
& WS_MINIMIZE
)
645 ThemeDrawTitle(pcontext
, prcCurrent
);
649 if((pcontext
->wi
.dwStyle
& WS_CAPTION
)==WS_CAPTION
)
651 ThemeStartBufferedPaint(pcontext
, prcCurrent
->right
, pcontext
->CaptionHeight
);
652 ThemeDrawCaption(pcontext
, prcCurrent
);
653 ThemeEndBufferedPaint(pcontext
, 0, 0, prcCurrent
->right
, pcontext
->CaptionHeight
);
654 ThemeDrawBorders(pcontext
, prcCurrent
);
658 DrawClassicFrame(pcontext
, prcCurrent
);
661 if(HAS_MENU(pcontext
->hWnd
, pcontext
->wi
.dwStyle
))
662 ThemeDrawMenuBar(pcontext
, prcCurrent
);
664 if(pcontext
->wi
.dwStyle
& WS_HSCROLL
)
665 ThemeDrawScrollBar(pcontext
, SB_HORZ
, NULL
);
667 if(pcontext
->wi
.dwStyle
& WS_VSCROLL
)
668 ThemeDrawScrollBar(pcontext
, SB_VERT
, NULL
);
676 ThemeHandleNCPaint(HWND hWnd
, HRGN hRgn
)
678 DRAW_CONTEXT context
;
681 ThemeInitDrawContext(&context
, hWnd
, hRgn
);
683 rcCurrent
= context
.wi
.rcWindow
;
684 OffsetRect( &rcCurrent
, -context
.wi
.rcWindow
.left
, -context
.wi
.rcWindow
.top
);
686 ThemePaintWindow(&context
, &rcCurrent
);
687 ThemeCleanupDrawContext(&context
);
693 ThemeHandleNcMouseMove(HWND hWnd
, DWORD ht
, POINT
* pt
)
695 DRAW_CONTEXT context
;
698 tme
.cbSize
= sizeof(TRACKMOUSEEVENT
);
699 tme
.dwFlags
= TME_QUERY
;
700 tme
.hwndTrack
= hWnd
;
701 TrackMouseEvent(&tme
);
702 if (tme
.dwFlags
!= (TME_LEAVE
| TME_NONCLIENT
))
704 tme
.hwndTrack
= hWnd
;
705 tme
.dwFlags
= TME_LEAVE
| TME_NONCLIENT
;
706 TrackMouseEvent(&tme
);
709 ThemeInitDrawContext(&context
, hWnd
, 0);
710 ThemeDrawCaptionButtons(&context
, ht
, 0);
712 if(context
.wi
.dwStyle
& WS_HSCROLL
)
713 ThemeDrawScrollBar(&context
, SB_HORZ
, ht
== HTHSCROLL
? pt
: NULL
);
715 if(context
.wi
.dwStyle
& WS_VSCROLL
)
716 ThemeDrawScrollBar(&context
, SB_VERT
, ht
== HTVSCROLL
? pt
: NULL
);
718 ThemeCleanupDrawContext(&context
);
724 ThemeHandleNcMouseLeave(HWND hWnd
)
726 DRAW_CONTEXT context
;
728 ThemeInitDrawContext(&context
, hWnd
, 0);
729 ThemeDrawCaptionButtons(&context
, 0, 0);
731 if(context
.wi
.dwStyle
& WS_HSCROLL
)
732 ThemeDrawScrollBar(&context
, SB_HORZ
, NULL
);
734 if(context
.wi
.dwStyle
& WS_VSCROLL
)
735 ThemeDrawScrollBar(&context
, SB_VERT
, NULL
);
737 ThemeCleanupDrawContext(&context
);
743 ThemeHandleButton(HWND hWnd
, WPARAM wParam
)
746 BOOL Pressed
= TRUE
, OldState
;
749 DRAW_CONTEXT context
;
751 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
755 if (!(Style
& WS_SYSMENU
))
760 if (!(Style
& WS_MINIMIZEBOX
))
762 SCMsg
= ((Style
& WS_MINIMIZE
) ? SC_RESTORE
: SC_MINIMIZE
);
765 if (!(Style
& WS_MAXIMIZEBOX
))
767 SCMsg
= ((Style
& WS_MAXIMIZE
) ? SC_RESTORE
: SC_MAXIMIZE
);
773 ThemeInitDrawContext(&context
, hWnd
, 0);
774 ThemeDrawCaptionButtons(&context
, 0, wParam
);
780 if (GetMessageW(&Msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
) <= 0)
783 if (Msg
.message
== WM_LBUTTONUP
)
786 if (Msg
.message
!= WM_MOUSEMOVE
)
790 ht
= SendMessage(hWnd
, WM_NCHITTEST
, 0, MAKELPARAM(Msg
.pt
.x
, Msg
.pt
.y
));
791 Pressed
= (ht
== wParam
);
793 ThemeDrawCaptionButtons(&context
, 0, Pressed
? wParam
: 0);
796 ThemeDrawCaptionButtons(&context
, 0, 0);
797 ThemeCleanupDrawContext(&context
);
802 SendMessageW(hWnd
, WM_SYSCOMMAND
, SCMsg
, 0);
807 DefWndNCHitTest(HWND hWnd
, POINT Point
)
813 GetWindowInfo(hWnd
, &wi
);
815 if (!PtInRect(&wi
.rcWindow
, Point
))
819 WindowRect
= wi
.rcWindow
;
821 if (UserHasWindowEdge(wi
.dwStyle
, wi
.dwExStyle
))
825 InflateRect(&WindowRect
, -(int)wi
.cxWindowBorders
, -(int)wi
.cyWindowBorders
);
826 XSize
= GetSystemMetrics(SM_CXSIZE
) * GetSystemMetrics(SM_CXBORDER
);
827 YSize
= GetSystemMetrics(SM_CYSIZE
) * GetSystemMetrics(SM_CYBORDER
);
828 if (!PtInRect(&WindowRect
, Point
))
832 ThickFrame
= (wi
.dwStyle
& WS_THICKFRAME
);
833 if (Point
.y
< WindowRect
.top
)
835 if(wi
.dwStyle
& WS_MINIMIZE
)
839 if (Point
.x
< (WindowRect
.left
+ XSize
))
841 if (Point
.x
>= (WindowRect
.right
- XSize
))
845 if (Point
.y
>= WindowRect
.bottom
)
847 if(wi
.dwStyle
& WS_MINIMIZE
)
851 if (Point
.x
< (WindowRect
.left
+ XSize
))
853 if (Point
.x
>= (WindowRect
.right
- XSize
))
854 return HTBOTTOMRIGHT
;
857 if (Point
.x
< WindowRect
.left
)
859 if(wi
.dwStyle
& WS_MINIMIZE
)
863 if (Point
.y
< (WindowRect
.top
+ YSize
))
865 if (Point
.y
>= (WindowRect
.bottom
- YSize
))
869 if (Point
.x
>= WindowRect
.right
)
871 if(wi
.dwStyle
& WS_MINIMIZE
)
875 if (Point
.y
< (WindowRect
.top
+ YSize
))
877 if (Point
.y
>= (WindowRect
.bottom
- YSize
))
878 return HTBOTTOMRIGHT
;
885 if (wi
.dwExStyle
& WS_EX_STATICEDGE
)
886 InflateRect(&WindowRect
, -GetSystemMetrics(SM_CXBORDER
),
887 -GetSystemMetrics(SM_CYBORDER
));
888 if (!PtInRect(&WindowRect
, Point
))
892 if ((wi
.dwStyle
& WS_CAPTION
) == WS_CAPTION
)
894 if (wi
.dwExStyle
& WS_EX_TOOLWINDOW
)
895 WindowRect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
897 WindowRect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
899 if (!PtInRect(&WindowRect
, Point
))
904 if (wi
.dwExStyle
& WS_EX_TOOLWINDOW
)
905 ButtonWidth
= GetSystemMetrics(SM_CXSMSIZE
);
907 ButtonWidth
= GetSystemMetrics(SM_CXSIZE
);
910 ButtonWidth
+= BUTTON_GAP_SIZE
;
912 if (wi
.dwStyle
& WS_SYSMENU
)
914 if (wi
.dwExStyle
& WS_EX_TOOLWINDOW
)
916 WindowRect
.right
-= ButtonWidth
;
920 if(!(wi
.dwExStyle
& WS_EX_DLGMODALFRAME
))
921 WindowRect
.left
+= ButtonWidth
;
922 WindowRect
.right
-= ButtonWidth
;
925 if (Point
.x
< WindowRect
.left
)
927 if (WindowRect
.right
<= Point
.x
)
929 if (wi
.dwStyle
& WS_MAXIMIZEBOX
|| wi
.dwStyle
& WS_MINIMIZEBOX
)
930 WindowRect
.right
-= ButtonWidth
;
931 if (Point
.x
>= WindowRect
.right
)
933 if (wi
.dwStyle
& WS_MINIMIZEBOX
)
934 WindowRect
.right
-= ButtonWidth
;
935 if (Point
.x
>= WindowRect
.right
)
941 if(!(wi
.dwStyle
& WS_MINIMIZE
))
946 ScreenToClient(hWnd
, &ClientPoint
);
947 GetClientRect(hWnd
, &wi
.rcClient
);
949 if (PtInRect(&wi
.rcClient
, ClientPoint
))
954 if ((menu
= GetMenu(hWnd
)) && !(wi
.dwStyle
& WS_CHILD
))
956 if (Point
.x
> 0 && Point
.x
< WindowRect
.right
&& ClientPoint
.y
< 0)
960 if (wi
.dwExStyle
& WS_EX_CLIENTEDGE
)
962 InflateRect(&WindowRect
, -2 * GetSystemMetrics(SM_CXBORDER
),
963 -2 * GetSystemMetrics(SM_CYBORDER
));
966 if ((wi
.dwStyle
& WS_VSCROLL
) && (wi
.dwStyle
& WS_HSCROLL
) &&
967 (WindowRect
.bottom
- WindowRect
.top
) > GetSystemMetrics(SM_CYHSCROLL
))
969 RECT ParentRect
, TempRect
= WindowRect
, TempRect2
= WindowRect
;
970 HWND Parent
= GetParent(hWnd
);
972 TempRect
.bottom
-= GetSystemMetrics(SM_CYHSCROLL
);
973 if ((wi
.dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
974 TempRect
.right
= TempRect
.left
+ GetSystemMetrics(SM_CXVSCROLL
);
976 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXVSCROLL
);
977 if (PtInRect(&TempRect
, Point
))
980 TempRect2
.top
= TempRect2
.bottom
- GetSystemMetrics(SM_CYHSCROLL
);
981 if ((wi
.dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
982 TempRect2
.left
+= GetSystemMetrics(SM_CXVSCROLL
);
984 TempRect2
.right
-= GetSystemMetrics(SM_CXVSCROLL
);
985 if (PtInRect(&TempRect2
, Point
))
988 TempRect
.top
= TempRect2
.top
;
989 TempRect
.bottom
= TempRect2
.bottom
;
991 GetClientRect(Parent
, &ParentRect
);
992 if (PtInRect(&TempRect
, Point
) && HASSIZEGRIP(wi
.dwStyle
, wi
.dwExStyle
,
993 GetWindowLongW(Parent
, GWL_STYLE
), wi
.rcWindow
, ParentRect
))
995 if ((wi
.dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
998 return HTBOTTOMRIGHT
;
1003 if (wi
.dwStyle
& WS_VSCROLL
)
1005 RECT TempRect
= WindowRect
;
1007 if ((wi
.dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
1008 TempRect
.right
= TempRect
.left
+ GetSystemMetrics(SM_CXVSCROLL
);
1010 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXVSCROLL
);
1011 if (PtInRect(&TempRect
, Point
))
1014 else if (wi
.dwStyle
& WS_HSCROLL
)
1016 RECT TempRect
= WindowRect
;
1017 TempRect
.top
= TempRect
.bottom
- GetSystemMetrics(SM_CYHSCROLL
);
1018 if (PtInRect(&TempRect
, Point
))
1028 ThemeWndProc(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, WNDPROC DefWndProc
)
1033 return ThemeHandleNCPaint(hWnd
, (HRGN
)wParam
);
1035 ThemeHandleNCPaint(hWnd
, (HRGN
)1);
1037 case WM_NCMOUSEMOVE
:
1040 Point
.x
= GET_X_LPARAM(lParam
);
1041 Point
.y
= GET_Y_LPARAM(lParam
);
1042 return ThemeHandleNcMouseMove(hWnd
, wParam
, &Point
);
1044 case WM_NCMOUSELEAVE
:
1045 return ThemeHandleNcMouseLeave(hWnd
);
1046 case WM_NCLBUTTONDOWN
:
1053 ThemeHandleButton(hWnd
, wParam
);
1057 return DefWndProc(hWnd
, Msg
, wParam
, lParam
);
1062 Point
.x
= GET_X_LPARAM(lParam
);
1063 Point
.y
= GET_Y_LPARAM(lParam
);
1064 return DefWndNCHitTest(hWnd
, Point
);
1068 if((wParam
& 0xfff0) == SC_VSCROLL
||
1069 (wParam
& 0xfff0) == SC_HSCROLL
)
1072 Pt
.x
= (short)LOWORD(lParam
);
1073 Pt
.y
= (short)HIWORD(lParam
);
1074 NC_TrackScrollBar(hWnd
, wParam
, Pt
);
1078 return DefWndProc(hWnd
, Msg
, wParam
, lParam
);
1081 case WM_NCUAHDRAWCAPTION
:
1082 case WM_NCUAHDRAWFRAME
:
1083 /* FIXME: how should these be handled? */
1086 return DefWndProc(hWnd
, Msg
, wParam
, lParam
);