2 * ReactOS User32 Library
3 * - Window non-client area management
5 * Copyright (C) 2003 ReactOS Team
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 /* INCLUDES *******************************************************************/
26 #include <wine/debug.h>
27 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
29 #define HAS_DLGFRAME(Style, ExStyle) \
30 (((ExStyle) & WS_EX_DLGMODALFRAME) || \
31 (((Style) & WS_DLGFRAME) && (!((Style) & (WS_THICKFRAME | WS_MINIMIZE)))))
33 #define HAS_THICKFRAME(Style, ExStyle) \
34 (((Style) & WS_THICKFRAME) && !((Style) & WS_MINIMIZE) && \
35 (!(((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)))
37 #define HAS_THINFRAME(Style, ExStyle) \
38 (((Style) & (WS_BORDER | WS_MINIMIZE)) || (!((Style) & (WS_CHILD | WS_POPUP))))
40 #define HASSIZEGRIP(Style, ExStyle, ParentStyle, WindowRect, ParentClientRect) \
41 ((!(Style & WS_CHILD) && (Style & WS_THICKFRAME) && !(Style & WS_MAXIMIZE)) || \
42 ((Style & WS_CHILD) && (ParentStyle & WS_THICKFRAME) && !(ParentStyle & WS_MAXIMIZE) && \
43 (WindowRect.right - WindowRect.left == ParentClientRect.right) && \
44 (WindowRect.bottom - WindowRect.top == ParentClientRect.bottom)))
46 #ifndef STATE_SYSTEM_OFFSCREEN
47 #define STATE_SYSTEM_OFFSCREEN 0x00010000
51 * FIXME: This should be moved to a header
54 IntDrawScrollBar(HWND hWnd
, HDC hDC
, INT nBar
);
56 IntScrollHitTest(HWND hWnd
, INT nBar
, POINT pt
, BOOL bDragging
);
58 BOOL WINAPI
GdiGradientFill(HDC
,PTRIVERTEX
,ULONG
,PVOID
,ULONG
,ULONG
);
60 extern ATOM AtomInternalPos
;
62 /* PRIVATE FUNCTIONS **********************************************************/
65 IntIsScrollBarVisible(HWND hWnd
, INT hBar
)
68 sbi
.cbSize
= sizeof(SCROLLBARINFO
);
69 if(!NtUserGetScrollBarInfo(hWnd
, hBar
, &sbi
))
72 return !(sbi
.rgstate
[0] & STATE_SYSTEM_OFFSCREEN
);
76 UserHasWindowEdge(DWORD Style
, DWORD ExStyle
)
78 if (Style
& WS_MINIMIZE
)
80 if (ExStyle
& WS_EX_DLGMODALFRAME
)
82 if (ExStyle
& WS_EX_STATICEDGE
)
84 if (Style
& WS_THICKFRAME
)
87 if (Style
== WS_DLGFRAME
|| Style
== WS_CAPTION
)
93 UserGetWindowBorders(DWORD Style
, DWORD ExStyle
, SIZE
*Size
, BOOL WithClient
)
97 if (UserHasWindowEdge(Style
, ExStyle
))
99 else if (ExStyle
& WS_EX_STATICEDGE
)
101 if ((ExStyle
& WS_EX_CLIENTEDGE
) && WithClient
)
103 if (Style
& WS_CAPTION
|| ExStyle
& WS_EX_DLGMODALFRAME
)
105 Size
->cx
= Size
->cy
= Border
;
106 if ((Style
& WS_THICKFRAME
) && !(Style
& WS_MINIMIZE
))
108 Size
->cx
+= GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
);
109 Size
->cy
+= GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
);
111 Size
->cx
*= GetSystemMetrics(SM_CXBORDER
);
112 Size
->cy
*= GetSystemMetrics(SM_CYBORDER
);
116 UserHasMenu(HWND hWnd
, ULONG Style
)
118 return (!(Style
& WS_CHILD
) && GetMenu(hWnd
) != 0);
122 UserGetWindowIcon(HWND hwnd
)
126 SendMessageTimeout(hwnd
, WM_GETICON
, ICON_SMALL2
, 0, SMTO_ABORTIFHUNG
, 1000, (PDWORD_PTR
)&hIcon
);
128 if (!hIcon
) hIcon
= UserGetProp(hwnd
, gpsi
->atomIconSmProp
);
129 if (!hIcon
) hIcon
= UserGetProp(hwnd
, gpsi
->atomIconProp
);
130 if (!hIcon
) hIcon
= (HICON
)GetClassLongPtr(hwnd
, GCL_HICONSM
);
131 if (!hIcon
) hIcon
= (HICON
)GetClassLongPtr(hwnd
, GCL_HICON
);
132 if (!hIcon
&& (GetWindowLongW( hwnd
, GWL_STYLE
) & DS_MODALFRAME
))
134 if (!hIcon
) hIcon
= gpsi
->hIconSmWindows
; // Both are IDI_WINLOGO Small
135 if (!hIcon
) hIcon
= gpsi
->hIconWindows
; // Reg size.
141 UserDrawSysMenuButton(HWND hWnd
, HDC hDC
, LPRECT Rect
, BOOL Down
)
145 if ((WindowIcon
= UserGetWindowIcon(hWnd
)))
147 return DrawIconEx(hDC
, Rect
->left
+ 2, Rect
->top
+ 2, WindowIcon
,
148 GetSystemMetrics(SM_CXSMICON
), GetSystemMetrics(SM_CYSMICON
),
157 * - Cache bitmaps, then just bitblt instead of calling DFC() (and
158 * wasting precious CPU cycles) every time
159 * - Center the buttons verticaly in the rect
162 UserDrawCaptionButton(HWND hWnd
, LPRECT Rect
, DWORD Style
, DWORD ExStyle
, HDC hDC
, BOOL bDown
, ULONG Type
)
166 if (!(Style
& WS_SYSMENU
))
175 case DFCS_CAPTIONMIN
:
177 if (ExStyle
& WS_EX_TOOLWINDOW
)
178 return; /* ToolWindows don't have min/max buttons */
180 if (Style
& WS_SYSMENU
)
181 TempRect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
182 if (Style
& (WS_MAXIMIZEBOX
| WS_MINIMIZEBOX
))
183 TempRect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
184 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
185 TempRect
.bottom
= TempRect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 2;
189 DrawFrameControl(hDC
, &TempRect
, DFC_CAPTION
,
190 ((Style
& WS_MINIMIZE
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMIN
) |
191 (bDown
? DFCS_PUSHED
: 0) |
192 ((Style
& WS_MINIMIZEBOX
) ? 0 : DFCS_INACTIVE
));
195 case DFCS_CAPTIONMAX
:
197 if (ExStyle
& WS_EX_TOOLWINDOW
)
198 return; /* ToolWindows don't have min/max buttons */
200 if (Style
& WS_SYSMENU
)
201 TempRect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
202 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
203 TempRect
.bottom
= TempRect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 2;
207 DrawFrameControl(hDC
, &TempRect
, DFC_CAPTION
,
208 ((Style
& WS_MAXIMIZE
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
) |
209 (bDown
? DFCS_PUSHED
: 0) |
210 ((Style
& WS_MAXIMIZEBOX
) ? 0 : DFCS_INACTIVE
));
213 case DFCS_CAPTIONCLOSE
:
215 HMENU hSysMenu
= GetSystemMenu(hWnd
, FALSE
);
216 UINT MenuState
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
); /* in case of error MenuState==0xFFFFFFFF */
218 /* FIXME: A tool window has a smaller Close button */
220 if (ExStyle
& WS_EX_TOOLWINDOW
)
222 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXSMSIZE
);
223 TempRect
.bottom
= TempRect
.top
+ GetSystemMetrics(SM_CYSMSIZE
) - 2;
227 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXSIZE
);
228 TempRect
.bottom
= TempRect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 2;
233 DrawFrameControl(hDC
, &TempRect
, DFC_CAPTION
,
234 (DFCS_CAPTIONCLOSE
| (bDown
? DFCS_PUSHED
: 0) |
235 ((!(MenuState
& (MF_GRAYED
|MF_DISABLED
)) && !(GetClassLong(hWnd
, GCL_STYLE
) & CS_NOCLOSE
)) ? 0 : DFCS_INACTIVE
)));
242 UserDrawCaptionButtonWnd(HWND hWnd
, HDC hDC
, BOOL bDown
, ULONG Type
)
246 DWORD Style
, ExStyle
;
248 GetWindowRect(hWnd
, &WindowRect
);
249 WindowRect
.right
-= WindowRect
.left
;
250 WindowRect
.bottom
-= WindowRect
.top
;
251 WindowRect
.left
= WindowRect
.top
= 0;
252 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
253 ExStyle
= GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
);
254 UserGetWindowBorders(Style
, ExStyle
, &WindowBorder
, FALSE
);
255 InflateRect(&WindowRect
, -WindowBorder
.cx
, -WindowBorder
.cy
);
256 UserDrawCaptionButton(hWnd
, &WindowRect
, Style
, ExStyle
, hDC
, bDown
, Type
);
260 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
261 the call to GetDCEx implying that it is allowed not to use it either.
262 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
263 will cause clipRgn to be deleted after ReleaseDC().
264 Now, how is the "system" supposed to tell what happened?
268 * - Drawing of WS_BORDER after scrollbars
269 * - Correct drawing of size-box
272 DefWndNCPaint(HWND hWnd
, HRGN hRgn
, BOOL Active
)
275 DWORD Style
, ExStyle
;
277 RECT ClientRect
, WindowRect
, CurrentRect
, TempRect
;
279 if (!IsWindowVisible(hWnd
))
282 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
284 TRACE("DefWndNCPaint: hWnd %p, hRgn %p, Active %s.\n",
285 hWnd
, hRgn
, Active
? "TRUE" : "FALSE");
287 hDC
= GetDCEx(hWnd
, hRgn
, DCX_WINDOW
| DCX_INTERSECTRGN
| DCX_USESTYLE
| DCX_KEEPCLIPRGN
);
290 ERR("hDC is NULL!\n");
291 if (hRgn
!= HRGN_WINDOW
)
296 Parent
= GetParent(hWnd
);
297 ExStyle
= GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
);
300 if (ExStyle
& WS_EX_MDICHILD
)
302 Active
= IsChild(GetForegroundWindow(), hWnd
);
304 Active
= (hWnd
== (HWND
)SendMessageW(Parent
, WM_MDIGETACTIVE
, 0, 0));
308 Active
= (GetForegroundWindow() == hWnd
);
311 GetWindowRect(hWnd
, &WindowRect
);
312 GetClientRect(hWnd
, &ClientRect
);
314 CurrentRect
.top
= CurrentRect
.left
= 0;
315 CurrentRect
.right
= WindowRect
.right
- WindowRect
.left
;
316 CurrentRect
.bottom
= WindowRect
.bottom
- WindowRect
.top
;
318 /* Draw outer edge */
319 if (UserHasWindowEdge(Style
, ExStyle
))
321 DrawEdge(hDC
, &CurrentRect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
323 if (ExStyle
& WS_EX_STATICEDGE
)
326 DrawEdge(hDC
, &CurrentRect
, BDR_SUNKENINNER
, BF_RECT
| BF_ADJUST
| BF_FLAT
);
328 SelectObject(hDC
, GetSysColorBrush(COLOR_BTNSHADOW
));
329 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.top
, CurrentRect
.right
- CurrentRect
.left
, 1, PATCOPY
);
330 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.top
, 1, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
332 SelectObject(hDC
, GetSysColorBrush(COLOR_BTNHIGHLIGHT
));
333 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.bottom
- 1, CurrentRect
.right
- CurrentRect
.left
, 1, PATCOPY
);
334 PatBlt(hDC
, CurrentRect
.right
- 1, CurrentRect
.top
, 1, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
336 InflateRect(&CurrentRect
, -1, -1);
340 /* Firstly the "thick" frame */
341 if ((Style
& WS_THICKFRAME
) && !(Style
& WS_MINIMIZE
))
344 (GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
)) *
345 GetSystemMetrics(SM_CXBORDER
);
347 (GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
)) *
348 GetSystemMetrics(SM_CYBORDER
);
350 SelectObject(hDC
, GetSysColorBrush(Active
? COLOR_ACTIVEBORDER
:
351 COLOR_INACTIVEBORDER
));
354 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.top
, CurrentRect
.right
- CurrentRect
.left
, Height
, PATCOPY
);
355 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.top
, Width
, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
357 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.bottom
- 1, CurrentRect
.right
- CurrentRect
.left
, -Height
, PATCOPY
);
358 PatBlt(hDC
, CurrentRect
.right
- 1, CurrentRect
.top
, -Width
, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
360 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.bottom
, CurrentRect
.right
- CurrentRect
.left
, -Height
, PATCOPY
);
361 PatBlt(hDC
, CurrentRect
.right
, CurrentRect
.top
, -Width
, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
364 InflateRect(&CurrentRect
, -Width
, -Height
);
367 /* Now the other bit of the frame */
368 if (Style
& (WS_DLGFRAME
| WS_BORDER
) || ExStyle
& WS_EX_DLGMODALFRAME
)
370 DWORD Width
= GetSystemMetrics(SM_CXBORDER
);
371 DWORD Height
= GetSystemMetrics(SM_CYBORDER
);
373 SelectObject(hDC
, GetSysColorBrush(
374 (ExStyle
& (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
)) ? COLOR_3DFACE
:
375 (ExStyle
& WS_EX_STATICEDGE
) ? COLOR_WINDOWFRAME
:
376 (Style
& (WS_DLGFRAME
| WS_THICKFRAME
)) ? COLOR_3DFACE
:
380 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.top
, CurrentRect
.right
- CurrentRect
.left
, Height
, PATCOPY
);
381 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.top
, Width
, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
383 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.bottom
- 1, CurrentRect
.right
- CurrentRect
.left
, -Height
, PATCOPY
);
384 PatBlt(hDC
, CurrentRect
.right
- 1, CurrentRect
.top
, -Width
, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
386 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.bottom
, CurrentRect
.right
- CurrentRect
.left
, -Height
, PATCOPY
);
387 PatBlt(hDC
, CurrentRect
.right
, CurrentRect
.top
, -Width
, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
390 InflateRect(&CurrentRect
, -Width
, -Height
);
394 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
396 DWORD CaptionFlags
= DC_ICON
| DC_TEXT
| DC_BUTTONS
;
398 BOOL Gradient
= FALSE
;
400 if(SystemParametersInfoW(SPI_GETGRADIENTCAPTIONS
, 0, &Gradient
, 0) && Gradient
)
402 CaptionFlags
|= DC_GRADIENT
;
405 TempRect
= CurrentRect
;
409 CaptionFlags
|= DC_ACTIVE
;
412 if (ExStyle
& WS_EX_TOOLWINDOW
)
414 CaptionFlags
|= DC_SMALLCAP
;
415 TempRect
.bottom
= TempRect
.top
+ GetSystemMetrics(SM_CYSMCAPTION
) - 1;
416 CurrentRect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
420 TempRect
.bottom
= TempRect
.top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
421 CurrentRect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
424 NtUserDrawCaption(hWnd
, hDC
, &TempRect
, CaptionFlags
);
427 if (Style
& WS_SYSMENU
)
429 UserDrawCaptionButton(hWnd
, &TempRect
, Style
, ExStyle
, hDC
, FALSE
, DFCS_CAPTIONCLOSE
);
430 if ((Style
& (WS_MAXIMIZEBOX
| WS_MINIMIZEBOX
)) && !(ExStyle
& WS_EX_TOOLWINDOW
))
432 UserDrawCaptionButton(hWnd
, &TempRect
, Style
, ExStyle
, hDC
, FALSE
, DFCS_CAPTIONMIN
);
433 UserDrawCaptionButton(hWnd
, &TempRect
, Style
, ExStyle
, hDC
, FALSE
, DFCS_CAPTIONMAX
);
436 if(!(Style
& WS_MINIMIZE
))
438 /* Line under caption */
439 PreviousPen
= SelectObject(hDC
, GetStockObject(DC_PEN
));
440 SetDCPenColor(hDC
, GetSysColor(
441 ((ExStyle
& (WS_EX_STATICEDGE
| WS_EX_CLIENTEDGE
|
442 WS_EX_DLGMODALFRAME
)) == WS_EX_STATICEDGE
) ?
443 COLOR_WINDOWFRAME
: COLOR_3DFACE
));
444 MoveToEx(hDC
, TempRect
.left
, TempRect
.bottom
, NULL
);
445 LineTo(hDC
, TempRect
.right
, TempRect
.bottom
);
446 SelectObject(hDC
, PreviousPen
);
450 if(!(Style
& WS_MINIMIZE
))
452 HMENU menu
= GetMenu(hWnd
);
454 if (menu
&& !(Style
& WS_CHILD
))
456 TempRect
= CurrentRect
;
457 TempRect
.bottom
= TempRect
.top
+ (UINT
)NtUserxSetMenuBarHeight(menu
, 0);
458 CurrentRect
.top
+= MenuDrawMenuBar(hDC
, &TempRect
, hWnd
, FALSE
);
461 if (ExStyle
& WS_EX_CLIENTEDGE
)
463 DrawEdge(hDC
, &CurrentRect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
466 /* Draw the scrollbars */
467 if ((Style
& WS_VSCROLL
) && (Style
& WS_HSCROLL
) &&
468 IntIsScrollBarVisible(hWnd
, OBJID_VSCROLL
) && IntIsScrollBarVisible(hWnd
, OBJID_HSCROLL
))
470 RECT ParentClientRect
;
472 TempRect
= CurrentRect
;
473 if (ExStyle
& WS_EX_LEFTSCROLLBAR
)
474 TempRect
.right
= TempRect
.left
+ GetSystemMetrics(SM_CXVSCROLL
);
476 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXVSCROLL
);
477 TempRect
.top
= TempRect
.bottom
- GetSystemMetrics(SM_CYHSCROLL
);
478 FillRect(hDC
, &TempRect
, GetSysColorBrush(COLOR_BTNFACE
));
479 /* FIXME: Correct drawing of size-box with WS_EX_LEFTSCROLLBAR */
481 GetClientRect(Parent
, &ParentClientRect
);
482 if (HASSIZEGRIP(Style
, ExStyle
, GetWindowLongPtrW(Parent
, GWL_STYLE
), WindowRect
, ParentClientRect
))
484 DrawFrameControl(hDC
, &TempRect
, DFC_SCROLL
, DFCS_SCROLLSIZEGRIP
);
486 IntDrawScrollBar(hWnd
, hDC
, SB_VERT
);
487 IntDrawScrollBar(hWnd
, hDC
, SB_HORZ
);
491 if (Style
& WS_VSCROLL
&& IntIsScrollBarVisible(hWnd
, OBJID_VSCROLL
))
492 IntDrawScrollBar(hWnd
, hDC
, SB_VERT
);
493 else if (Style
& WS_HSCROLL
&& IntIsScrollBarVisible(hWnd
, OBJID_HSCROLL
))
494 IntDrawScrollBar(hWnd
, hDC
, SB_HORZ
);
498 ReleaseDC(hWnd
, hDC
);
499 if (hRgn
!= HRGN_WINDOW
)
500 DeleteObject(hRgn
); // We use DCX_KEEPCLIPRGN
502 return 0; // For WM_NCPAINT message, return 0.
506 DefWndNCCalcSize(HWND hWnd
, BOOL CalcSizeStruct
, RECT
*Rect
)
509 DWORD Style
= GetClassLongPtrW(hWnd
, GCL_STYLE
);
522 if (Style
& CS_VREDRAW
)
524 Result
|= WVR_VREDRAW
;
526 if (Style
& CS_HREDRAW
)
528 Result
|= WVR_HREDRAW
;
530 Result
|= WVR_VALIDRECTS
;
533 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
534 ExStyle
= GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
);
536 if (!(Style
& WS_MINIMIZE
))
538 HMENU menu
= GetMenu(hWnd
);
540 if (UserHasWindowEdge(Style
, ExStyle
))
542 UserGetWindowBorders(Style
, ExStyle
, &WindowBorders
, FALSE
);
543 InflateRect(Rect
, -WindowBorders
.cx
, -WindowBorders
.cy
);
545 if ((ExStyle
& WS_EX_STATICEDGE
) || (Style
& WS_BORDER
))
547 InflateRect(Rect
, -1, -1);
550 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
552 if (ExStyle
& WS_EX_TOOLWINDOW
)
553 Rect
->top
+= GetSystemMetrics(SM_CYSMCAPTION
);
555 Rect
->top
+= GetSystemMetrics(SM_CYCAPTION
);
558 if (menu
&& !(Style
& WS_CHILD
))
560 HDC hDC
= GetWindowDC(hWnd
);
563 RECT CliRect
= *Rect
;
564 CliRect
.bottom
-= OrigRect
.top
;
565 CliRect
.right
-= OrigRect
.left
;
566 CliRect
.left
-= OrigRect
.left
;
567 CliRect
.top
-= OrigRect
.top
;
568 Rect
->top
+= MenuDrawMenuBar(hDC
, &CliRect
, hWnd
, TRUE
);
569 ReleaseDC(hWnd
, hDC
);
573 if (ExStyle
& WS_EX_CLIENTEDGE
)
575 InflateRect(Rect
, -2 * GetSystemMetrics(SM_CXBORDER
),
576 -2 * GetSystemMetrics(SM_CYBORDER
));
579 if(Style
& (WS_VSCROLL
| WS_HSCROLL
))
582 SETSCROLLBARINFO ssbi
;
584 sbi
.cbSize
= sizeof(SCROLLBARINFO
);
585 if((Style
& WS_VSCROLL
) && NtUserGetScrollBarInfo(hWnd
, OBJID_VSCROLL
, &sbi
))
588 LONG sx
= Rect
->right
;
590 sx
-= GetSystemMetrics(SM_CXVSCROLL
);
591 for(i
= 0; i
<= CCHILDREN_SCROLLBAR
; i
++)
592 ssbi
.rgstate
[i
] = sbi
.rgstate
[i
];
594 ssbi
.rgstate
[0] |= STATE_SYSTEM_OFFSCREEN
;
596 ssbi
.rgstate
[0] &= ~STATE_SYSTEM_OFFSCREEN
;
597 NtUserSetScrollBarInfo(hWnd
, OBJID_VSCROLL
, &ssbi
);
598 if(ssbi
.rgstate
[0] & STATE_SYSTEM_OFFSCREEN
)
599 Style
&= ~WS_VSCROLL
;
602 Style
&= ~WS_VSCROLL
;
604 if((Style
& WS_HSCROLL
) && NtUserGetScrollBarInfo(hWnd
, OBJID_HSCROLL
, &sbi
))
607 LONG sy
= Rect
->bottom
;
609 sy
-= GetSystemMetrics(SM_CYHSCROLL
);
610 for(i
= 0; i
<= CCHILDREN_SCROLLBAR
; i
++)
611 ssbi
.rgstate
[i
] = sbi
.rgstate
[i
];
613 ssbi
.rgstate
[0] |= STATE_SYSTEM_OFFSCREEN
;
615 ssbi
.rgstate
[0] &= ~STATE_SYSTEM_OFFSCREEN
;
616 NtUserSetScrollBarInfo(hWnd
, OBJID_HSCROLL
, &ssbi
);
617 if(ssbi
.rgstate
[0] & STATE_SYSTEM_OFFSCREEN
)
618 Style
&= ~WS_HSCROLL
;
621 Style
&= ~WS_HSCROLL
;
624 if ((Style
& WS_VSCROLL
) && (Style
& WS_HSCROLL
))
626 if ((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
627 Rect
->left
+= GetSystemMetrics(SM_CXVSCROLL
);
629 Rect
->right
-= GetSystemMetrics(SM_CXVSCROLL
);
630 Rect
->bottom
-= GetSystemMetrics(SM_CYHSCROLL
);
634 if (Style
& WS_VSCROLL
)
636 if ((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
637 Rect
->left
+= GetSystemMetrics(SM_CXVSCROLL
);
639 Rect
->right
-= GetSystemMetrics(SM_CXVSCROLL
);
641 else if (Style
& WS_HSCROLL
)
642 Rect
->bottom
-= GetSystemMetrics(SM_CYHSCROLL
);
644 if (Rect
->top
> Rect
->bottom
)
645 Rect
->bottom
= Rect
->top
;
646 if (Rect
->left
> Rect
->right
)
647 Rect
->right
= Rect
->left
;
651 Rect
->right
= Rect
->left
;
652 Rect
->bottom
= Rect
->top
;
659 DefWndNCActivate(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
661 PWND Wnd
= ValidateHwnd(hWnd
);
665 /* Lotus Notes draws menu descriptions in the caption of its main
666 * window. When it wants to restore original "system" view, it just
667 * sends WM_NCACTIVATE message to itself. Any optimizations here in
668 * attempt to minimize redrawings lead to a not restored caption.
671 NtUserxSetWindowState(Wnd
, WNDSACTIVEFRAME
);
673 NtUserxClearWindowState(Wnd
, WNDSACTIVEFRAME
);
675 if (Wnd
->state
& WNDS_NONCPAINT
)
678 /* This isn't documented but is reproducible in at least XP SP2 and
679 * Outlook 2007 depends on it
682 // If this parameter is set to -1, DefWindowProc does not repaint the
683 // nonclient area to reflect the state change.
686 DefWndNCPaint(hWnd
, HRGN_WINDOW
, wParam
);
693 * - Check the scrollbar handling
696 DefWndNCHitTest(HWND hWnd
, POINT Point
)
698 RECT WindowRect
, ClientRect
, OrigWndRect
;
701 DWORD Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
702 DWORD ExStyle
= GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
);
704 GetWindowRect(hWnd
, &WindowRect
);
705 if (!PtInRect(&WindowRect
, Point
))
709 OrigWndRect
= WindowRect
;
711 if (UserHasWindowEdge(Style
, ExStyle
))
715 UserGetWindowBorders(Style
, ExStyle
, &WindowBorders
, FALSE
);
716 InflateRect(&WindowRect
, -WindowBorders
.cx
, -WindowBorders
.cy
);
717 XSize
= GetSystemMetrics(SM_CXSIZE
) * GetSystemMetrics(SM_CXBORDER
);
718 YSize
= GetSystemMetrics(SM_CYSIZE
) * GetSystemMetrics(SM_CYBORDER
);
719 if (!PtInRect(&WindowRect
, Point
))
723 ThickFrame
= (Style
& WS_THICKFRAME
);
724 if (Point
.y
< WindowRect
.top
)
726 if(Style
& WS_MINIMIZE
)
730 if (Point
.x
< (WindowRect
.left
+ XSize
))
732 if (Point
.x
>= (WindowRect
.right
- XSize
))
736 if (Point
.y
>= WindowRect
.bottom
)
738 if(Style
& WS_MINIMIZE
)
742 if (Point
.x
< (WindowRect
.left
+ XSize
))
744 if (Point
.x
>= (WindowRect
.right
- XSize
))
745 return HTBOTTOMRIGHT
;
748 if (Point
.x
< WindowRect
.left
)
750 if(Style
& WS_MINIMIZE
)
754 if (Point
.y
< (WindowRect
.top
+ YSize
))
756 if (Point
.y
>= (WindowRect
.bottom
- YSize
))
760 if (Point
.x
>= WindowRect
.right
)
762 if(Style
& WS_MINIMIZE
)
766 if (Point
.y
< (WindowRect
.top
+ YSize
))
768 if (Point
.y
>= (WindowRect
.bottom
- YSize
))
769 return HTBOTTOMRIGHT
;
776 if (ExStyle
& WS_EX_STATICEDGE
)
777 InflateRect(&WindowRect
,
778 -GetSystemMetrics(SM_CXBORDER
),
779 -GetSystemMetrics(SM_CYBORDER
));
780 if (!PtInRect(&WindowRect
, Point
))
784 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
786 if (ExStyle
& WS_EX_TOOLWINDOW
)
787 WindowRect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
789 WindowRect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
790 if (!PtInRect(&WindowRect
, Point
))
792 if (Style
& WS_SYSMENU
)
794 if (ExStyle
& WS_EX_TOOLWINDOW
)
796 WindowRect
.right
-= GetSystemMetrics(SM_CXSMSIZE
);
800 if(!(ExStyle
& WS_EX_DLGMODALFRAME
))
801 WindowRect
.left
+= GetSystemMetrics(SM_CXSIZE
);
802 WindowRect
.right
-= GetSystemMetrics(SM_CXSIZE
);
805 if (Point
.x
< WindowRect
.left
)
807 if (WindowRect
.right
<= Point
.x
)
809 if (Style
& WS_MAXIMIZEBOX
|| Style
& WS_MINIMIZEBOX
)
810 WindowRect
.right
-= GetSystemMetrics(SM_CXSIZE
);
811 if (Point
.x
>= WindowRect
.right
)
813 if (Style
& WS_MINIMIZEBOX
)
814 WindowRect
.right
-= GetSystemMetrics(SM_CXSIZE
);
815 if (Point
.x
>= WindowRect
.right
)
821 if(!(Style
& WS_MINIMIZE
))
824 ScreenToClient(hWnd
, &ClientPoint
);
825 GetClientRect(hWnd
, &ClientRect
);
827 if (PtInRect(&ClientRect
, ClientPoint
))
832 if (GetMenu(hWnd
) && !(Style
& WS_CHILD
))
834 if (Point
.x
> 0 && Point
.x
< WindowRect
.right
&& ClientPoint
.y
< 0)
838 if (ExStyle
& WS_EX_CLIENTEDGE
)
840 InflateRect(&WindowRect
, -2 * GetSystemMetrics(SM_CXBORDER
),
841 -2 * GetSystemMetrics(SM_CYBORDER
));
844 if ((Style
& WS_VSCROLL
) && (Style
& WS_HSCROLL
) &&
845 (WindowRect
.bottom
- WindowRect
.top
) > GetSystemMetrics(SM_CYHSCROLL
))
847 RECT ParentRect
, TempRect
= WindowRect
, TempRect2
= WindowRect
;
848 HWND Parent
= GetParent(hWnd
);
850 TempRect
.bottom
-= GetSystemMetrics(SM_CYHSCROLL
);
851 if ((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
852 TempRect
.right
= TempRect
.left
+ GetSystemMetrics(SM_CXVSCROLL
);
854 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXVSCROLL
);
855 if (PtInRect(&TempRect
, Point
))
858 TempRect2
.top
= TempRect2
.bottom
- GetSystemMetrics(SM_CYHSCROLL
);
859 if ((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
860 TempRect2
.left
+= GetSystemMetrics(SM_CXVSCROLL
);
862 TempRect2
.right
-= GetSystemMetrics(SM_CXVSCROLL
);
863 if (PtInRect(&TempRect2
, Point
))
866 TempRect
.top
= TempRect2
.top
;
867 TempRect
.bottom
= TempRect2
.bottom
;
869 GetClientRect(Parent
, &ParentRect
);
870 if (PtInRect(&TempRect
, Point
) && HASSIZEGRIP(Style
, ExStyle
,
871 GetWindowLongPtrW(Parent
, GWL_STYLE
), OrigWndRect
, ParentRect
))
873 if ((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
876 return HTBOTTOMRIGHT
;
881 if (Style
& WS_VSCROLL
)
883 RECT TempRect
= WindowRect
;
885 if ((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
886 TempRect
.right
= TempRect
.left
+ GetSystemMetrics(SM_CXVSCROLL
);
888 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXVSCROLL
);
889 if (PtInRect(&TempRect
, Point
))
892 if (Style
& WS_HSCROLL
)
894 RECT TempRect
= WindowRect
;
895 TempRect
.top
= TempRect
.bottom
- GetSystemMetrics(SM_CYHSCROLL
);
896 if (PtInRect(&TempRect
, Point
))
906 DefWndDoButton(HWND hWnd
, WPARAM wParam
)
910 BOOL Pressed
= TRUE
, OldState
;
917 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
921 hSysMenu
= GetSystemMenu(hWnd
, FALSE
);
922 MenuState
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
); /* in case of error MenuState==0xFFFFFFFF */
923 if (!(Style
& WS_SYSMENU
) || (MenuState
& (MF_GRAYED
|MF_DISABLED
)) || (GetClassLongPtrW(hWnd
, GCL_STYLE
) & CS_NOCLOSE
))
925 ButtonType
= DFCS_CAPTIONCLOSE
;
929 if (!(Style
& WS_MINIMIZEBOX
))
931 ButtonType
= DFCS_CAPTIONMIN
;
932 SCMsg
= ((Style
& WS_MINIMIZE
) ? SC_RESTORE
: SC_MINIMIZE
);
935 if (!(Style
& WS_MAXIMIZEBOX
))
937 ButtonType
= DFCS_CAPTIONMAX
;
938 SCMsg
= ((Style
& WS_MAXIMIZE
) ? SC_RESTORE
: SC_MAXIMIZE
);
947 * FIXME: Not sure where to do this, but we must flush the pending
948 * window updates when someone clicks on the close button and at
949 * the same time the window is overlapped with another one. This
950 * looks like a good place for now...
954 WindowDC
= GetWindowDC(hWnd
);
955 UserDrawCaptionButtonWnd(hWnd
, WindowDC
, TRUE
, ButtonType
);
961 if (GetMessageW(&Msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
) <= 0)
963 if (CallMsgFilterW( &Msg
, MSGF_MAX
)) continue;
965 if (Msg
.message
== WM_LBUTTONUP
)
968 if (Msg
.message
!= WM_MOUSEMOVE
)
972 Pressed
= (DefWndNCHitTest(hWnd
, Msg
.pt
) == wParam
);
973 if (Pressed
!= OldState
)
974 UserDrawCaptionButtonWnd(hWnd
, WindowDC
, Pressed
, ButtonType
);
978 UserDrawCaptionButtonWnd(hWnd
, WindowDC
, FALSE
, ButtonType
);
980 ReleaseDC(hWnd
, WindowDC
);
982 SendMessageW(hWnd
, WM_SYSCOMMAND
, SCMsg
, MAKELONG(Msg
.pt
.x
,Msg
.pt
.y
));
987 DefWndNCLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
989 PWND Wnd
= ValidateHwnd(hWnd
);
995 HWND hTopWnd
= hWnd
, parent
;
998 if ((GetWindowLongW( hTopWnd
, GWL_STYLE
) & (WS_POPUP
|WS_CHILD
)) != WS_CHILD
)
1000 parent
= GetAncestor( hTopWnd
, GA_PARENT
);
1001 if (!parent
|| parent
== GetDesktopWindow()) break;
1005 if ( NtUserCallHwndLock(hTopWnd
, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOWMOUSE
) ||
1006 GetActiveWindow() == hTopWnd
)
1008 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
1014 LONG style
= GetWindowLongPtrW( hWnd
, GWL_STYLE
);
1015 if (style
& WS_SYSMENU
)
1017 if( Wnd
&& !(style
& WS_MINIMIZE
) )
1020 HDC hDC
= GetWindowDC(hWnd
);
1021 UserGetInsideRectNC(Wnd
, &rect
);
1022 UserDrawSysMenuButton(hWnd
, hDC
, &rect
, TRUE
);
1023 ReleaseDC( hWnd
, hDC
);
1025 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
1031 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTMENU
, lParam
);
1036 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
1041 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
1048 DefWndDoButton(hWnd
, wParam
);
1061 * "make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU"
1062 * This was previously done by setting wParam=SC_SIZE + wParam - 2
1064 /* But that is not what WinNT does. Instead it sends this. This
1065 * is easy to differentiate from HTSYSMENU, because HTSYSMENU adds
1066 * SC_MOUSEMENU into wParam.
1068 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- (HTLEFT
- WMSZ_LEFT
), lParam
);
1079 DefWndNCLButtonDblClk(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1083 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1088 /* Maximize/Restore the window */
1089 if((Style
& WS_CAPTION
) == WS_CAPTION
&& (Style
& WS_MAXIMIZEBOX
))
1091 SendMessageW(hWnd
, WM_SYSCOMMAND
, ((Style
& (WS_MINIMIZE
| WS_MAXIMIZE
)) ? SC_RESTORE
: SC_MAXIMIZE
), 0);
1097 HMENU hSysMenu
= GetSystemMenu(hWnd
, FALSE
);
1098 UINT state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1100 /* If the close item of the sysmenu is disabled or not present do nothing */
1101 if ((state
& (MF_DISABLED
| MF_GRAYED
)) || (state
== 0xFFFFFFFF))
1104 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
1108 return DefWndNCLButtonDown(hWnd
, wParam
, lParam
);
1113 /***********************************************************************
1114 * NC_HandleNCRButtonDown
1116 * Handle a WM_NCRBUTTONDOWN message. Called from DefWindowProc().
1118 LRESULT
NC_HandleNCRButtonDown( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1121 INT hittest
= wParam
;
1127 if (!GetSystemMenu( hwnd
, FALSE
)) break;
1132 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1133 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1134 if (msg
.message
== WM_RBUTTONUP
)
1136 hittest
= DefWndNCHitTest( hwnd
, msg
.pt
);
1139 if (hwnd
!= GetCapture()) return 0;
1142 if (hittest
== HTCAPTION
|| hittest
== HTSYSMENU
|| hittest
== HTHSCROLL
|| hittest
== HTVSCROLL
)
1144 TRACE("Msg pt %x and Msg.lParam %x and lParam %x\n",MAKELONG(msg
.pt
.x
,msg
.pt
.y
),msg
.lParam
,lParam
);
1145 SendMessageW( hwnd
, WM_CONTEXTMENU
, (WPARAM
)hwnd
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
));
1152 /***********************************************************************
1155 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
1156 * but without the borders (if any).
1157 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
1159 static void FASTCALL
1160 NcGetInsideRect(HWND Wnd
, RECT
*Rect
)
1165 GetWindowRect(Wnd
, Rect
);
1166 Rect
->right
= Rect
->right
- Rect
->left
;
1168 Rect
->bottom
= Rect
->bottom
- Rect
->top
;
1171 Style
= GetWindowLongPtrW(Wnd
, GWL_STYLE
);
1172 if (0 != (Style
& WS_ICONIC
))
1177 /* Remove frame from rectangle */
1178 ExStyle
= GetWindowLongPtrW(Wnd
, GWL_EXSTYLE
);
1179 if (HAS_THICKFRAME(Style
, ExStyle
))
1181 InflateRect(Rect
, - GetSystemMetrics(SM_CXFRAME
), - GetSystemMetrics(SM_CYFRAME
));
1183 else if (HAS_DLGFRAME(Style
, ExStyle
))
1185 InflateRect(Rect
, - GetSystemMetrics(SM_CXDLGFRAME
), - GetSystemMetrics(SM_CYDLGFRAME
));
1187 else if (HAS_THINFRAME(Style
, ExStyle
))
1189 InflateRect(Rect
, - GetSystemMetrics(SM_CXBORDER
), - GetSystemMetrics(SM_CYBORDER
));
1192 /* We have additional border information if the window
1193 * is a child (but not an MDI child) */
1194 if (0 != (Style
& WS_CHILD
)
1195 && 0 == (ExStyle
& WS_EX_MDICHILD
))
1197 if (0 != (ExStyle
& WS_EX_CLIENTEDGE
))
1199 InflateRect(Rect
, - GetSystemMetrics(SM_CXEDGE
), - GetSystemMetrics(SM_CYEDGE
));
1201 if (0 != (ExStyle
& WS_EX_STATICEDGE
))
1203 InflateRect(Rect
, - GetSystemMetrics(SM_CXBORDER
), - GetSystemMetrics(SM_CYBORDER
));
1208 /***********************************************************************
1212 NcGetSysPopupPos(HWND Wnd
, RECT
*Rect
)
1218 GetWindowRect(Wnd
, Rect
);
1222 NcGetInsideRect(Wnd
, Rect
);
1223 GetWindowRect(Wnd
, &WindowRect
);
1224 OffsetRect(Rect
, WindowRect
.left
, WindowRect
.top
);
1225 if (0 != (GetWindowLongPtrW(Wnd
, GWL_STYLE
) & WS_CHILD
))
1227 ClientToScreen(GetParent(Wnd
), (POINT
*) Rect
);
1229 Rect
->right
= Rect
->left
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1230 Rect
->bottom
= Rect
->top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1234 /* PUBLIC FUNCTIONS ***********************************************************/
1237 RealAdjustWindowRectEx(LPRECT lpRect
,
1246 lpRect
->top
-= GetSystemMetrics(SM_CYMENU
);
1248 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1250 if (dwExStyle
& WS_EX_TOOLWINDOW
)
1251 lpRect
->top
-= GetSystemMetrics(SM_CYSMCAPTION
);
1253 lpRect
->top
-= GetSystemMetrics(SM_CYCAPTION
);
1255 UserGetWindowBorders(dwStyle
, dwExStyle
, &BorderSize
, TRUE
);
1270 AdjustWindowRectEx(LPRECT lpRect
,
1275 BOOL Hook
, Ret
= FALSE
;
1279 Hook
= BeginIfHookedUserApiHook();
1281 /* Bypass SEH and go direct. */
1282 if (!Hook
) return RealAdjustWindowRectEx(lpRect
, dwStyle
, bMenu
, dwExStyle
);
1286 Ret
= guah
.AdjustWindowRectEx(lpRect
, dwStyle
, bMenu
, dwExStyle
);
1288 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1305 AdjustWindowRect(LPRECT lpRect
,
1309 return AdjustWindowRectEx(lpRect
, dwStyle
, bMenu
, 0);
1312 // Enabling this will cause captions to draw smoother, but slower:
1313 #define DOUBLE_BUFFER_CAPTION
1319 DrawCaption(HWND hWnd
, HDC hDC
, LPCRECT lprc
, UINT uFlags
)
1321 BOOL Hook
, Ret
= FALSE
;
1325 Hook
= BeginIfHookedUserApiHook();
1327 /* Bypass SEH and go direct. */
1328 if (!Hook
) return NtUserDrawCaption(hWnd
, hDC
, lprc
, uFlags
);
1332 Ret
= guah
.DrawCaption(hWnd
, hDC
, lprc
, uFlags
);
1334 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1359 UNICODE_STRING Text
= {0};
1360 RtlInitUnicodeString(&Text
, str
);
1361 return NtUserDrawCaptionTemp(hWnd
, hDC
, rect
, hFont
, hIcon
, &Text
, uFlags
);
1383 if (!(uFlags
& DC_TEXT
) || !str
)
1384 return DrawCaptionTempW(hwnd
, hdc
, rect
, hFont
, hIcon
, NULL
, uFlags
);
1386 len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
1387 if ((strW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
))))
1389 MultiByteToWideChar(CP_ACP
, 0, str
, -1, strW
, len
);
1390 ret
= DrawCaptionTempW(hwnd
, hdc
, rect
, hFont
, hIcon
, strW
, uFlags
);
1391 HeapFree(GetProcessHeap(), 0, strW
);