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 Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 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 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; see the file COPYING.LIB.
19 * If not, write to the Free Software Foundation,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 /* INCLUDES *******************************************************************/
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 GetSysColorPen(int nIndex
);
60 BOOL STDCALL
GdiGradientFill(HDC
,PTRIVERTEX
,ULONG
,PVOID
,ULONG
,ULONG
);
62 extern ATOM AtomInternalPos
;
64 /* PRIVATE FUNCTIONS **********************************************************/
67 IntIsScrollBarVisible(HWND hWnd
, INT hBar
)
70 sbi
.cbSize
= sizeof(SCROLLBARINFO
);
71 if(!NtUserGetScrollBarInfo(hWnd
, hBar
, &sbi
))
74 return !(sbi
.rgstate
[0] & STATE_SYSTEM_OFFSCREEN
);
78 UserHasWindowEdge(DWORD Style
, DWORD ExStyle
)
80 if (Style
& WS_MINIMIZE
)
82 if (ExStyle
& WS_EX_DLGMODALFRAME
)
84 if (ExStyle
& WS_EX_STATICEDGE
)
86 if (Style
& WS_THICKFRAME
)
89 if (Style
== WS_DLGFRAME
|| Style
== WS_CAPTION
)
95 UserGetWindowBorders(DWORD Style
, DWORD ExStyle
, SIZE
*Size
, BOOL WithClient
)
99 if (UserHasWindowEdge(Style
, ExStyle
))
101 else if (ExStyle
& WS_EX_STATICEDGE
)
103 if ((ExStyle
& WS_EX_CLIENTEDGE
) && WithClient
)
105 if (Style
& WS_CAPTION
|| ExStyle
& WS_EX_DLGMODALFRAME
)
107 Size
->cx
= Size
->cy
= Border
;
108 if ((Style
& WS_THICKFRAME
) && !(Style
& WS_MINIMIZE
))
110 Size
->cx
+= GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
);
111 Size
->cy
+= GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
);
113 Size
->cx
*= GetSystemMetrics(SM_CXBORDER
);
114 Size
->cy
*= GetSystemMetrics(SM_CYBORDER
);
118 UserHasMenu(HWND hWnd
, ULONG Style
)
120 return (!(Style
& WS_CHILD
) && GetMenu(hWnd
) != 0);
124 UserGetWindowIcon(HWND hwnd
)
128 SendMessageTimeout(hwnd
, WM_GETICON
, ICON_SMALL2
, 0, SMTO_ABORTIFHUNG
, 1000, (LPDWORD
)&hIcon
);
131 SendMessageTimeout(hwnd
, WM_GETICON
, ICON_SMALL
, 0, SMTO_ABORTIFHUNG
, 1000, (LPDWORD
)&hIcon
);
134 SendMessageTimeout(hwnd
, WM_GETICON
, ICON_BIG
, 0, SMTO_ABORTIFHUNG
, 1000, (LPDWORD
)&hIcon
);
137 hIcon
= (HICON
)GetClassLong(hwnd
, GCL_HICONSM
);
140 hIcon
= (HICON
)GetClassLong(hwnd
, GCL_HICON
);
146 UserDrawSysMenuButton(HWND hWnd
, HDC hDC
, LPRECT Rect
, BOOL Down
)
150 if ((WindowIcon
= UserGetWindowIcon(hWnd
)))
152 return DrawIconEx(hDC
, Rect
->left
+ 2, Rect
->top
+ 2, WindowIcon
,
153 GetSystemMetrics(SM_CXSMICON
), GetSystemMetrics(SM_CYSMICON
),
162 * - Cache bitmaps, then just bitblt instead of calling DFC() (and
163 * wasting precious CPU cycles) every time
164 * - Center the buttons verticaly in the rect
167 UserDrawCaptionButton(LPRECT Rect
, DWORD Style
, DWORD ExStyle
, HDC hDC
, BOOL bDown
, ULONG Type
)
171 if (!(Style
& WS_SYSMENU
))
180 case DFCS_CAPTIONMIN
:
182 if (ExStyle
& WS_EX_TOOLWINDOW
)
183 return; /* ToolWindows don't have min/max buttons */
185 if (Style
& WS_SYSMENU
)
186 TempRect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
187 if (Style
& (WS_MAXIMIZEBOX
| WS_MINIMIZEBOX
))
188 TempRect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
189 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
190 TempRect
.bottom
= TempRect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 2;
194 DrawFrameControl(hDC
, &TempRect
, DFC_CAPTION
,
195 ((Style
& WS_MINIMIZE
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMIN
) |
196 (bDown
? DFCS_PUSHED
: 0) |
197 ((Style
& WS_MINIMIZEBOX
) ? 0 : DFCS_INACTIVE
));
200 case DFCS_CAPTIONMAX
:
202 if (ExStyle
& WS_EX_TOOLWINDOW
)
203 return; /* ToolWindows don't have min/max buttons */
205 if (Style
& WS_SYSMENU
)
206 TempRect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
207 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
208 TempRect
.bottom
= TempRect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 2;
212 DrawFrameControl(hDC
, &TempRect
, DFC_CAPTION
,
213 ((Style
& WS_MAXIMIZE
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
) |
214 (bDown
? DFCS_PUSHED
: 0) |
215 ((Style
& WS_MAXIMIZEBOX
) ? 0 : DFCS_INACTIVE
));
218 case DFCS_CAPTIONCLOSE
:
220 /* FIXME: A tool window has a smaller Close button */
222 if (ExStyle
& WS_EX_TOOLWINDOW
)
224 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXSMSIZE
);
225 TempRect
.bottom
= TempRect
.top
+ GetSystemMetrics(SM_CYSMSIZE
) - 2;
229 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXSIZE
);
230 TempRect
.bottom
= TempRect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 2;
235 DrawFrameControl(hDC
, &TempRect
, DFC_CAPTION
,
236 (DFCS_CAPTIONCLOSE
| (bDown
? DFCS_PUSHED
: 0) |
237 ((Style
& WS_SYSMENU
) ? 0 : DFCS_INACTIVE
)));
244 UserDrawCaptionButtonWnd(HWND hWnd
, HDC hDC
, BOOL bDown
, ULONG Type
)
248 DWORD Style
, ExStyle
;
250 GetWindowRect(hWnd
, &WindowRect
);
251 WindowRect
.right
-= WindowRect
.left
;
252 WindowRect
.bottom
-= WindowRect
.top
;
253 WindowRect
.left
= WindowRect
.top
= 0;
254 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
255 ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
256 UserGetWindowBorders(Style
, ExStyle
, &WindowBorder
, FALSE
);
257 InflateRect(&WindowRect
, -WindowBorder
.cx
, -WindowBorder
.cy
);
258 UserDrawCaptionButton(&WindowRect
, Style
, ExStyle
, hDC
, bDown
, Type
);
263 * - Drawing of WS_BORDER after scrollbars
264 * - Correct drawing of size-box
267 DefWndNCPaint(HWND hWnd
, HRGN hRgn
, BOOL Active
)
270 DWORD Style
, ExStyle
;
272 RECT ClientRect
, WindowRect
, CurrentRect
, TempRect
;
274 if (!IsWindowVisible(hWnd
))
277 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
279 hDC
= GetDCEx(hWnd
, hRgn
, DCX_WINDOW
| DCX_INTERSECTRGN
| 0x10000);
285 Parent
= GetParent(hWnd
);
286 ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
289 if (ExStyle
& WS_EX_MDICHILD
)
291 Active
= IsChild(GetForegroundWindow(), hWnd
);
293 Active
= (hWnd
== (HWND
)SendMessageW(Parent
, WM_MDIGETACTIVE
, 0, 0));
297 Active
= (GetForegroundWindow() == hWnd
);
300 GetWindowRect(hWnd
, &WindowRect
);
301 GetClientRect(hWnd
, &ClientRect
);
303 CurrentRect
.top
= CurrentRect
.left
= 0;
304 CurrentRect
.right
= WindowRect
.right
- WindowRect
.left
;
305 CurrentRect
.bottom
= WindowRect
.bottom
- WindowRect
.top
;
307 /* Draw outer edge */
308 if (UserHasWindowEdge(Style
, ExStyle
))
310 DrawEdge(hDC
, &CurrentRect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
312 if (ExStyle
& WS_EX_STATICEDGE
)
315 DrawEdge(hDC
, &CurrentRect
, BDR_SUNKENINNER
, BF_RECT
| BF_ADJUST
| BF_FLAT
);
317 SelectObject(hDC
, GetSysColorBrush(COLOR_BTNSHADOW
));
318 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.top
, CurrentRect
.right
- CurrentRect
.left
, 1, PATCOPY
);
319 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.top
, 1, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
321 SelectObject(hDC
, GetSysColorBrush(COLOR_BTNHIGHLIGHT
));
322 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.bottom
- 1, CurrentRect
.right
- CurrentRect
.left
, 1, PATCOPY
);
323 PatBlt(hDC
, CurrentRect
.right
- 1, CurrentRect
.top
, 1, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
325 InflateRect(&CurrentRect
, -1, -1);
329 /* Firstly the "thick" frame */
330 if ((Style
& WS_THICKFRAME
) && !(Style
& WS_MINIMIZE
))
333 (GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
)) *
334 GetSystemMetrics(SM_CXBORDER
);
336 (GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
)) *
337 GetSystemMetrics(SM_CYBORDER
);
339 SelectObject(hDC
, GetSysColorBrush(Active
? COLOR_ACTIVEBORDER
:
340 COLOR_INACTIVEBORDER
));
343 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.top
, CurrentRect
.right
- CurrentRect
.left
, Height
, PATCOPY
);
344 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.top
, Width
, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
346 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.bottom
- 1, CurrentRect
.right
- CurrentRect
.left
, -Height
, PATCOPY
);
347 PatBlt(hDC
, CurrentRect
.right
- 1, CurrentRect
.top
, -Width
, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
349 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.bottom
, CurrentRect
.right
- CurrentRect
.left
, -Height
, PATCOPY
);
350 PatBlt(hDC
, CurrentRect
.right
, CurrentRect
.top
, -Width
, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
353 InflateRect(&CurrentRect
, -Width
, -Height
);
356 /* Now the other bit of the frame */
357 if (Style
& (WS_DLGFRAME
| WS_BORDER
) || ExStyle
& WS_EX_DLGMODALFRAME
)
359 DWORD Width
= GetSystemMetrics(SM_CXBORDER
);
360 DWORD Height
= GetSystemMetrics(SM_CYBORDER
);
362 SelectObject(hDC
, GetSysColorBrush(
363 (ExStyle
& (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
)) ? COLOR_3DFACE
:
364 (ExStyle
& WS_EX_STATICEDGE
) ? COLOR_WINDOWFRAME
:
365 (Style
& (WS_DLGFRAME
| WS_THICKFRAME
)) ? COLOR_3DFACE
:
369 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.top
, CurrentRect
.right
- CurrentRect
.left
, Height
, PATCOPY
);
370 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.top
, Width
, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
372 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.bottom
- 1, CurrentRect
.right
- CurrentRect
.left
, -Height
, PATCOPY
);
373 PatBlt(hDC
, CurrentRect
.right
- 1, CurrentRect
.top
, -Width
, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
375 PatBlt(hDC
, CurrentRect
.left
, CurrentRect
.bottom
, CurrentRect
.right
- CurrentRect
.left
, -Height
, PATCOPY
);
376 PatBlt(hDC
, CurrentRect
.right
, CurrentRect
.top
, -Width
, CurrentRect
.bottom
- CurrentRect
.top
, PATCOPY
);
379 InflateRect(&CurrentRect
, -Width
, -Height
);
383 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
385 DWORD CaptionFlags
= DC_ICON
| DC_TEXT
| DC_BUTTONS
;
387 BOOL Gradient
= FALSE
;
389 if(SystemParametersInfoW(SPI_GETGRADIENTCAPTIONS
, 0, &Gradient
, 0) && Gradient
)
391 CaptionFlags
|= DC_GRADIENT
;
394 TempRect
= CurrentRect
;
398 CaptionFlags
|= DC_ACTIVE
;
401 if (ExStyle
& WS_EX_TOOLWINDOW
)
403 CaptionFlags
|= DC_SMALLCAP
;
404 TempRect
.bottom
= TempRect
.top
+ GetSystemMetrics(SM_CYSMCAPTION
) - 1;
405 CurrentRect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
409 TempRect
.bottom
= TempRect
.top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
410 CurrentRect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
413 DrawCaption(hWnd
, hDC
, &TempRect
, CaptionFlags
);
416 if (Style
& WS_SYSMENU
)
418 UserDrawCaptionButton(&TempRect
, Style
, ExStyle
, hDC
, FALSE
, DFCS_CAPTIONCLOSE
);
419 if ((Style
& (WS_MAXIMIZEBOX
| WS_MINIMIZEBOX
)) && !(ExStyle
& WS_EX_TOOLWINDOW
))
421 UserDrawCaptionButton(&TempRect
, Style
, ExStyle
, hDC
, FALSE
, DFCS_CAPTIONMIN
);
422 UserDrawCaptionButton(&TempRect
, Style
, ExStyle
, hDC
, FALSE
, DFCS_CAPTIONMAX
);
425 if(!(Style
& WS_MINIMIZE
))
427 /* Line under caption */
428 PreviousPen
= SelectObject(hDC
, GetSysColorPen(
429 ((ExStyle
& (WS_EX_STATICEDGE
| WS_EX_CLIENTEDGE
|
430 WS_EX_DLGMODALFRAME
)) == WS_EX_STATICEDGE
) ?
431 COLOR_WINDOWFRAME
: COLOR_3DFACE
));
432 MoveToEx(hDC
, TempRect
.left
, TempRect
.bottom
, NULL
);
433 LineTo(hDC
, TempRect
.right
, TempRect
.bottom
);
434 SelectObject(hDC
, PreviousPen
);
438 if(!(Style
& WS_MINIMIZE
))
440 HMENU menu
= GetMenu(hWnd
);
442 if (menu
&& !(Style
& WS_CHILD
))
444 TempRect
= CurrentRect
;
445 TempRect
.bottom
= TempRect
.top
+ (UINT
)NtUserSetMenuBarHeight(menu
, 0);
446 CurrentRect
.top
+= MenuDrawMenuBar(hDC
, &TempRect
, hWnd
, FALSE
);
449 if (ExStyle
& WS_EX_CLIENTEDGE
)
451 DrawEdge(hDC
, &CurrentRect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
454 /* Draw the scrollbars */
455 if ((Style
& WS_VSCROLL
) && (Style
& WS_HSCROLL
) &&
456 IntIsScrollBarVisible(hWnd
, OBJID_VSCROLL
) && IntIsScrollBarVisible(hWnd
, OBJID_HSCROLL
))
458 RECT ParentClientRect
;
460 TempRect
= CurrentRect
;
461 if (ExStyle
& WS_EX_LEFTSCROLLBAR
)
462 TempRect
.right
= TempRect
.left
+ GetSystemMetrics(SM_CXVSCROLL
);
464 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXVSCROLL
);
465 TempRect
.top
= TempRect
.bottom
- GetSystemMetrics(SM_CYHSCROLL
);
466 FillRect(hDC
, &TempRect
, GetSysColorBrush(COLOR_BTNFACE
));
467 /* FIXME: Correct drawing of size-box with WS_EX_LEFTSCROLLBAR */
469 GetClientRect(Parent
, &ParentClientRect
);
470 if (HASSIZEGRIP(Style
, ExStyle
, GetWindowLongW(Parent
, GWL_STYLE
), WindowRect
, ParentClientRect
))
472 DrawFrameControl(hDC
, &TempRect
, DFC_SCROLL
, DFCS_SCROLLSIZEGRIP
);
474 IntDrawScrollBar(hWnd
, hDC
, SB_VERT
);
475 IntDrawScrollBar(hWnd
, hDC
, SB_HORZ
);
479 if (Style
& WS_VSCROLL
&& IntIsScrollBarVisible(hWnd
, OBJID_VSCROLL
))
480 IntDrawScrollBar(hWnd
, hDC
, SB_VERT
);
481 else if (Style
& WS_HSCROLL
&& IntIsScrollBarVisible(hWnd
, OBJID_HSCROLL
))
482 IntDrawScrollBar(hWnd
, hDC
, SB_HORZ
);
486 ReleaseDC(hWnd
, hDC
);
492 DefWndNCCalcSize(HWND hWnd
, BOOL CalcSizeStruct
, RECT
*Rect
)
495 DWORD Style
= GetClassLongW(hWnd
, GCL_STYLE
);
498 RECT OrigRect
= *Rect
;
502 if (Style
& CS_VREDRAW
)
504 Result
|= WVR_VREDRAW
;
506 if (Style
& CS_HREDRAW
)
508 Result
|= WVR_HREDRAW
;
510 Result
|= WVR_VALIDRECTS
;
513 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
514 ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
516 if (!(Style
& WS_MINIMIZE
))
518 HMENU menu
= GetMenu(hWnd
);
520 if (UserHasWindowEdge(Style
, ExStyle
))
522 UserGetWindowBorders(Style
, ExStyle
, &WindowBorders
, FALSE
);
523 InflateRect(Rect
, -WindowBorders
.cx
, -WindowBorders
.cy
);
525 if ((ExStyle
& WS_EX_STATICEDGE
) || (Style
& WS_BORDER
))
527 InflateRect(Rect
, -1, -1);
530 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
532 if (ExStyle
& WS_EX_TOOLWINDOW
)
533 Rect
->top
+= GetSystemMetrics(SM_CYSMCAPTION
);
535 Rect
->top
+= GetSystemMetrics(SM_CYCAPTION
);
538 if (menu
&& !(Style
& WS_CHILD
))
540 HDC hDC
= GetWindowDC(hWnd
);
543 RECT CliRect
= *Rect
;
544 CliRect
.bottom
-= OrigRect
.top
;
545 CliRect
.right
-= OrigRect
.left
;
546 CliRect
.left
-= OrigRect
.left
;
547 CliRect
.top
-= OrigRect
.top
;
548 Rect
->top
+= MenuDrawMenuBar(hDC
, &CliRect
, hWnd
, TRUE
);
549 ReleaseDC(hWnd
, hDC
);
553 if (ExStyle
& WS_EX_CLIENTEDGE
)
555 InflateRect(Rect
, -2 * GetSystemMetrics(SM_CXBORDER
),
556 -2 * GetSystemMetrics(SM_CYBORDER
));
559 if(Style
& (WS_VSCROLL
| WS_HSCROLL
))
562 SETSCROLLBARINFO ssbi
;
564 sbi
.cbSize
= sizeof(SCROLLBARINFO
);
565 if((Style
& WS_VSCROLL
) && NtUserGetScrollBarInfo(hWnd
, OBJID_VSCROLL
, &sbi
))
568 LONG sx
= Rect
->right
;
570 sx
-= GetSystemMetrics(SM_CXVSCROLL
);
571 for(i
= 0; i
<= CCHILDREN_SCROLLBAR
; i
++)
572 ssbi
.rgstate
[i
] = sbi
.rgstate
[i
];
574 ssbi
.rgstate
[0] |= STATE_SYSTEM_OFFSCREEN
;
576 ssbi
.rgstate
[0] &= ~STATE_SYSTEM_OFFSCREEN
;
577 NtUserSetScrollBarInfo(hWnd
, OBJID_VSCROLL
, &ssbi
);
578 if(ssbi
.rgstate
[0] & STATE_SYSTEM_OFFSCREEN
)
579 Style
&= ~WS_VSCROLL
;
582 Style
&= ~WS_VSCROLL
;
584 if((Style
& WS_HSCROLL
) && NtUserGetScrollBarInfo(hWnd
, OBJID_HSCROLL
, &sbi
))
587 LONG sy
= Rect
->bottom
;
589 sy
-= GetSystemMetrics(SM_CYHSCROLL
);
590 for(i
= 0; i
<= CCHILDREN_SCROLLBAR
; i
++)
591 ssbi
.rgstate
[i
] = sbi
.rgstate
[i
];
593 ssbi
.rgstate
[0] |= STATE_SYSTEM_OFFSCREEN
;
595 ssbi
.rgstate
[0] &= ~STATE_SYSTEM_OFFSCREEN
;
596 NtUserSetScrollBarInfo(hWnd
, OBJID_HSCROLL
, &ssbi
);
597 if(ssbi
.rgstate
[0] & STATE_SYSTEM_OFFSCREEN
)
598 Style
&= ~WS_HSCROLL
;
601 Style
&= ~WS_HSCROLL
;
604 if ((Style
& WS_VSCROLL
) && (Style
& WS_HSCROLL
))
606 if ((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
607 Rect
->left
+= GetSystemMetrics(SM_CXVSCROLL
);
609 Rect
->right
-= GetSystemMetrics(SM_CXVSCROLL
);
610 Rect
->bottom
-= GetSystemMetrics(SM_CYHSCROLL
);
614 if (Style
& WS_VSCROLL
)
616 if ((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
617 Rect
->left
+= GetSystemMetrics(SM_CXVSCROLL
);
619 Rect
->right
-= GetSystemMetrics(SM_CXVSCROLL
);
621 else if (Style
& WS_HSCROLL
)
622 Rect
->bottom
-= GetSystemMetrics(SM_CYHSCROLL
);
624 if (Rect
->top
> Rect
->bottom
)
625 Rect
->bottom
= Rect
->top
;
626 if (Rect
->left
> Rect
->right
)
627 Rect
->right
= Rect
->left
;
631 Rect
->right
= Rect
->left
;
632 Rect
->bottom
= Rect
->top
;
639 DefWndNCActivate(HWND hWnd
, WPARAM wParam
)
641 DefWndNCPaint(hWnd
, (HRGN
)1, wParam
);
647 * - Check the scrollbar handling
650 DefWndNCHitTest(HWND hWnd
, POINT Point
)
652 RECT WindowRect
, ClientRect
, OrigWndRect
;
655 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
656 ULONG ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
658 GetWindowRect(hWnd
, &WindowRect
);
659 if (!PtInRect(&WindowRect
, Point
))
663 OrigWndRect
= WindowRect
;
665 if (UserHasWindowEdge(Style
, ExStyle
))
669 UserGetWindowBorders(Style
, ExStyle
, &WindowBorders
, FALSE
);
670 InflateRect(&WindowRect
, -WindowBorders
.cx
, -WindowBorders
.cy
);
671 XSize
= GetSystemMetrics(SM_CXSIZE
) * GetSystemMetrics(SM_CXBORDER
);
672 YSize
= GetSystemMetrics(SM_CYSIZE
) * GetSystemMetrics(SM_CYBORDER
);
673 if (!PtInRect(&WindowRect
, Point
))
677 ThickFrame
= (Style
& WS_THICKFRAME
);
678 if (Point
.y
< WindowRect
.top
)
680 if(Style
& WS_MINIMIZE
)
684 if (Point
.x
< (WindowRect
.left
+ XSize
))
686 if (Point
.x
>= (WindowRect
.right
- XSize
))
690 if (Point
.y
>= WindowRect
.bottom
)
692 if(Style
& WS_MINIMIZE
)
696 if (Point
.x
< (WindowRect
.left
+ XSize
))
698 if (Point
.x
>= (WindowRect
.right
- XSize
))
699 return HTBOTTOMRIGHT
;
702 if (Point
.x
< WindowRect
.left
)
704 if(Style
& WS_MINIMIZE
)
708 if (Point
.y
< (WindowRect
.top
+ YSize
))
710 if (Point
.y
>= (WindowRect
.bottom
- YSize
))
714 if (Point
.x
>= WindowRect
.right
)
716 if(Style
& WS_MINIMIZE
)
720 if (Point
.y
< (WindowRect
.top
+ YSize
))
722 if (Point
.y
>= (WindowRect
.bottom
- YSize
))
723 return HTBOTTOMRIGHT
;
730 if (ExStyle
& WS_EX_STATICEDGE
)
731 InflateRect(&WindowRect
,
732 -GetSystemMetrics(SM_CXBORDER
),
733 -GetSystemMetrics(SM_CYBORDER
));
734 if (!PtInRect(&WindowRect
, Point
))
738 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
740 if (ExStyle
& WS_EX_TOOLWINDOW
)
741 WindowRect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
743 WindowRect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
744 if (!PtInRect(&WindowRect
, Point
))
746 if (Style
& WS_SYSMENU
)
748 if (ExStyle
& WS_EX_TOOLWINDOW
)
750 WindowRect
.right
-= GetSystemMetrics(SM_CXSMSIZE
);
754 WindowRect
.left
+= GetSystemMetrics(SM_CXSIZE
);
755 WindowRect
.right
-= GetSystemMetrics(SM_CXSIZE
);
758 if (Point
.x
<= WindowRect
.left
)
760 if (WindowRect
.right
<= Point
.x
)
762 if (Style
& WS_MAXIMIZEBOX
|| Style
& WS_MINIMIZEBOX
)
763 WindowRect
.right
-= GetSystemMetrics(SM_CXSIZE
);
764 if (Point
.x
>= WindowRect
.right
)
766 if (Style
& WS_MINIMIZEBOX
)
767 WindowRect
.right
-= GetSystemMetrics(SM_CXSIZE
);
768 if (Point
.x
>= WindowRect
.right
)
774 if(!(Style
& WS_MINIMIZE
))
779 ScreenToClient(hWnd
, &ClientPoint
);
780 GetClientRect(hWnd
, &ClientRect
);
782 if (PtInRect(&ClientRect
, ClientPoint
))
787 if ((menu
= GetMenu(hWnd
)) && !(Style
& WS_CHILD
))
789 if (Point
.x
> 0 && Point
.x
< WindowRect
.right
&& ClientPoint
.y
< 0)
793 if (ExStyle
& WS_EX_CLIENTEDGE
)
795 InflateRect(&WindowRect
, -2 * GetSystemMetrics(SM_CXBORDER
),
796 -2 * GetSystemMetrics(SM_CYBORDER
));
799 if ((Style
& WS_VSCROLL
) && (Style
& WS_HSCROLL
) &&
800 (WindowRect
.bottom
- WindowRect
.top
) > GetSystemMetrics(SM_CYHSCROLL
))
802 RECT ParentRect
, TempRect
= WindowRect
, TempRect2
= WindowRect
;
803 HWND Parent
= GetParent(hWnd
);
805 TempRect
.bottom
-= GetSystemMetrics(SM_CYHSCROLL
);
806 if ((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
807 TempRect
.right
= TempRect
.left
+ GetSystemMetrics(SM_CXVSCROLL
);
809 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXVSCROLL
);
810 if (PtInRect(&TempRect
, Point
))
813 TempRect2
.top
= TempRect2
.bottom
- GetSystemMetrics(SM_CYHSCROLL
);
814 if ((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
815 TempRect2
.left
+= GetSystemMetrics(SM_CXVSCROLL
);
817 TempRect2
.right
-= GetSystemMetrics(SM_CXVSCROLL
);
818 if (PtInRect(&TempRect2
, Point
))
821 TempRect
.top
= TempRect2
.top
;
822 TempRect
.bottom
= TempRect2
.bottom
;
824 GetClientRect(Parent
, &ParentRect
);
825 if (PtInRect(&TempRect
, Point
) && HASSIZEGRIP(Style
, ExStyle
,
826 GetWindowLongW(Parent
, GWL_STYLE
), OrigWndRect
, ParentRect
))
828 if ((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
831 return HTBOTTOMRIGHT
;
836 if (Style
& WS_VSCROLL
)
838 RECT TempRect
= WindowRect
;
840 if ((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
841 TempRect
.right
= TempRect
.left
+ GetSystemMetrics(SM_CXVSCROLL
);
843 TempRect
.left
= TempRect
.right
- GetSystemMetrics(SM_CXVSCROLL
);
844 if (PtInRect(&TempRect
, Point
))
847 if (Style
& WS_HSCROLL
)
849 RECT TempRect
= WindowRect
;
850 TempRect
.top
= TempRect
.bottom
- GetSystemMetrics(SM_CYHSCROLL
);
851 if (PtInRect(&TempRect
, Point
))
861 DefWndDoButton(HWND hWnd
, WPARAM wParam
)
865 BOOL Pressed
= TRUE
, OldState
;
867 ULONG ButtonType
, Style
;
869 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
873 if (!(Style
& WS_SYSMENU
))
875 ButtonType
= DFCS_CAPTIONCLOSE
;
879 if (!(Style
& WS_MINIMIZEBOX
))
881 ButtonType
= DFCS_CAPTIONMIN
;
882 SCMsg
= ((Style
& WS_MINIMIZE
) ? SC_RESTORE
: SC_MINIMIZE
);
885 if (!(Style
& WS_MAXIMIZEBOX
))
887 ButtonType
= DFCS_CAPTIONMAX
;
888 SCMsg
= ((Style
& WS_MAXIMIZE
) ? SC_RESTORE
: SC_MAXIMIZE
);
897 * FIXME: Not sure where to do this, but we must flush the pending
898 * window updates when someone clicks on the close button and at
899 * the same time the window is overlapped with another one. This
900 * looks like a good place for now...
904 WindowDC
= GetWindowDC(hWnd
);
905 UserDrawCaptionButtonWnd(hWnd
, WindowDC
, TRUE
, ButtonType
);
911 if (GetMessageW(&Msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
) <= 0)
914 if (Msg
.message
== WM_LBUTTONUP
)
917 if (Msg
.message
!= WM_MOUSEMOVE
)
921 Pressed
= (DefWndNCHitTest(hWnd
, Msg
.pt
) == wParam
);
922 if (Pressed
!= OldState
)
923 UserDrawCaptionButtonWnd(hWnd
, WindowDC
, Pressed
, ButtonType
);
927 UserDrawCaptionButtonWnd(hWnd
, WindowDC
, FALSE
, ButtonType
);
929 ReleaseDC(hWnd
, WindowDC
);
931 SendMessageW(hWnd
, WM_SYSCOMMAND
, SCMsg
, 0);
936 DefWndNCLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
942 HWND hTopWnd
= GetAncestor(hWnd
, GA_ROOT
);
943 if (SetActiveWindow(hTopWnd
) || GetActiveWindow() == hTopWnd
)
945 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
951 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_SYSMENU
)
953 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
,
960 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTMENU
, lParam
);
965 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
970 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
977 DefWndDoButton(hWnd
, wParam
);
989 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- (HTLEFT
- WMSZ_LEFT
), lParam
);
998 DefWndNCLButtonDblClk(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1002 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1007 /* Maximize/Restore the window */
1008 if((Style
& WS_CAPTION
) == WS_CAPTION
&& (Style
& WS_MAXIMIZEBOX
))
1010 SendMessageW(hWnd
, WM_SYSCOMMAND
, ((Style
& (WS_MINIMIZE
| WS_MAXIMIZE
)) ? SC_RESTORE
: SC_MAXIMIZE
), 0);
1016 SendMessageW(hWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1020 return DefWndNCLButtonDown(hWnd
, wParam
, lParam
);
1026 DefWndTrackScrollBar(HWND hWnd
, WPARAM wParam
, POINT Point
)
1030 if ((wParam
& 0xfff0) == SC_HSCROLL
)
1032 if ((wParam
& 0x0f) != HTHSCROLL
)
1034 ScrollBar
= SB_HORZ
;
1038 if ((wParam
& 0x0f) != HTVSCROLL
)
1040 ScrollBar
= SB_VERT
;
1046 /* PUBLIC FUNCTIONS ***********************************************************/
1052 AdjustWindowRectEx(LPRECT lpRect
,
1061 lpRect
->top
-= GetSystemMetrics(SM_CYMENU
);
1063 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1065 if (dwExStyle
& WS_EX_TOOLWINDOW
)
1066 lpRect
->top
-= GetSystemMetrics(SM_CYSMCAPTION
);
1068 lpRect
->top
-= GetSystemMetrics(SM_CYCAPTION
);
1070 UserGetWindowBorders(dwStyle
, dwExStyle
, &BorderSize
, TRUE
);
1084 AdjustWindowRect(LPRECT lpRect
,
1088 return AdjustWindowRectEx(lpRect
, dwStyle
, bMenu
, 0);
1091 // Enabling this will cause captions to draw smoother, but slower:
1092 #define DOUBLE_BUFFER_CAPTION
1098 DrawCaption(HWND hWnd
, HDC hDC
, LPCRECT lprc
, UINT uFlags
)
1100 NONCLIENTMETRICSW nclm
;
1101 BOOL result
= FALSE
;
1103 UINT VCenter
= 0, Padding
= 0, Height
;
1107 HFONT hOldFont
= NULL
;
1108 HBRUSH OldBrush
= NULL
;
1111 COLORREF OldTextColor
;
1113 #ifdef DOUBLE_BUFFER_CAPTION
1114 HBITMAP MemBMP
= NULL
, OldBMP
= NULL
;
1116 MemDC
= CreateCompatibleDC(hDC
);
1117 if (! MemDC
) goto cleanup
;
1118 MemBMP
= CreateCompatibleBitmap(hDC
, lprc
->right
- lprc
->left
, lprc
->bottom
- lprc
->top
);
1119 if (! MemBMP
) goto cleanup
;
1120 OldBMP
= SelectObject(MemDC
, MemBMP
);
1121 if (! OldBMP
) goto cleanup
;
1125 OffsetViewportOrgEx(MemDC
, lprc
->left
, lprc
->top
, NULL
);
1128 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1130 /* Windows behaves like this */
1131 Height
= GetSystemMetrics(SM_CYCAPTION
) - 1;
1133 VCenter
= (lprc
->bottom
- lprc
->top
) / 2;
1134 Padding
= VCenter
- (Height
/ 2);
1137 r
.right
= r
.left
+ (lprc
->right
- lprc
->left
);
1139 r
.bottom
= r
.top
+ (Height
/ 2);
1141 // Draw the caption background
1142 if (uFlags
& DC_INBUTTON
)
1144 OldBrush
= SelectObject(MemDC
, GetSysColorBrush(uFlags
& DC_ACTIVE
? COLOR_BTNFACE
: COLOR_BTNSHADOW
) );
1145 if (! OldBrush
) goto cleanup
;
1146 if (! PatBlt(MemDC
, 0, 0, lprc
->right
- lprc
->left
, lprc
->bottom
- lprc
->top
, PATCOPY
)) goto cleanup
;
1150 if (uFlags
& DC_GRADIENT
)
1152 static GRADIENT_RECT gcap
= {0, 1};
1157 r
.right
= (lprc
->right
- lprc
->left
);
1158 if (uFlags
& DC_SMALLCAP
)
1159 ButtonWidth
= GetSystemMetrics(SM_CXSMSIZE
) - 2;
1161 ButtonWidth
= GetSystemMetrics(SM_CXSIZE
) - 2;
1163 //if (Style & WS_SYSMENU)
1165 // r.right -= 3 + ButtonWidth;
1166 // if (! (uFlags & DC_SMALLCAP))
1168 // if(Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
1169 // r.right -= 2 + 2 * ButtonWidth;
1176 Colors
[0] = GetSysColor((uFlags
& DC_ACTIVE
) ? COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
);
1177 Colors
[1] = GetSysColor((uFlags
& DC_ACTIVE
) ? COLOR_GRADIENTACTIVECAPTION
: COLOR_GRADIENTINACTIVECAPTION
);
1181 vert
[0].Red
= GetRValue(Colors
[0]) << 8;
1182 vert
[0].Green
= GetGValue(Colors
[0]) << 8;
1183 vert
[0].Blue
= GetBValue(Colors
[0]) << 8;
1186 vert
[1].x
= r
.right
;
1187 vert
[1].y
= lprc
->bottom
- lprc
->top
;
1188 vert
[1].Red
= GetRValue(Colors
[1]) << 8;
1189 vert
[1].Green
= GetGValue(Colors
[1]) << 8;
1190 vert
[1].Blue
= GetBValue(Colors
[1]) << 8;
1193 GdiGradientFill(MemDC
, vert
, 2, &gcap
, 1, GRADIENT_FILL_RECT_V
);
1195 if ((uFlags
& DC_ICON
) && (Style
& WS_SYSMENU
) && !(uFlags
& DC_SMALLCAP
))
1198 SetBkMode( MemDC
, TRANSPARENT
);
1199 xx
= GetSystemMetrics(SM_CXSIZE
) + Padding
;
1200 if (UserDrawSysMenuButton(hWnd
, MemDC
, &r
, FALSE
))
1207 SelectObject(MemDC
, OldBrush
);
1210 //xx = lprc->right - lprc->left - r.right;
1213 // OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION));
1214 // if (!OldBrush) goto cleanup;
1215 // PatBlt(MemDC, r.right, 0, xx, lprc->bottom - lprc->top, PATCOPY);
1220 OldBrush
= SelectObject(MemDC
, GetSysColorBrush(uFlags
& DC_ACTIVE
? COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
) );
1221 if (! OldBrush
) goto cleanup
;
1222 if (! PatBlt(MemDC
, 0, 0, lprc
->right
- lprc
->left
, lprc
->bottom
- lprc
->top
, PATCOPY
)) goto cleanup
;
1226 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_GRADIENT
) && (Style
& WS_SYSMENU
) && !(uFlags
& DC_SMALLCAP
))
1228 /* For some reason the icon isn't centered correctly... */
1230 if (UserDrawSysMenuButton(hWnd
, MemDC
, &r
, FALSE
))
1231 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + Padding
;
1237 r
.bottom
= r
.top
+ Height
;
1239 if ((uFlags
& DC_TEXT
) && (NtUserInternalGetWindowText( hWnd
, buffer
, sizeof(buffer
)/sizeof(buffer
[0]) )))
1241 if(!(uFlags
& DC_GRADIENT
))
1243 r
.right
= (lprc
->right
- lprc
->left
);
1244 if (uFlags
& DC_SMALLCAP
)
1245 ButtonWidth
= GetSystemMetrics(SM_CXSMSIZE
) - 2;
1247 ButtonWidth
= GetSystemMetrics(SM_CXSIZE
) - 2;
1249 if (Style
& WS_SYSMENU
)
1251 r
.right
-= 3 + ButtonWidth
;
1252 if (! (uFlags
& DC_SMALLCAP
))
1254 if(Style
& (WS_MAXIMIZEBOX
| WS_MINIMIZEBOX
))
1255 r
.right
-= 2 + 2 * ButtonWidth
;
1263 nclm
.cbSize
= sizeof(nclm
);
1264 if (! SystemParametersInfoW(SPI_GETNONCLIENTMETRICS
, sizeof(NONCLIENTMETRICSW
), &nclm
, 0)) goto cleanup
;
1266 SetBkMode( MemDC
, TRANSPARENT
);
1267 if (uFlags
& DC_SMALLCAP
)
1268 hFont
= CreateFontIndirectW(&nclm
.lfSmCaptionFont
);
1270 hFont
= CreateFontIndirectW(&nclm
.lfCaptionFont
);
1272 if (! hFont
) goto cleanup
;
1274 hOldFont
= SelectObject(MemDC
, hFont
);
1275 if (! hOldFont
) goto cleanup
;
1277 if (uFlags
& DC_INBUTTON
)
1278 OldTextColor
= SetTextColor(MemDC
, GetSysColor(uFlags
& DC_ACTIVE
? COLOR_BTNTEXT
: COLOR_GRAYTEXT
));
1280 OldTextColor
= SetTextColor(MemDC
, GetSysColor(uFlags
& DC_ACTIVE
? COLOR_CAPTIONTEXT
: COLOR_INACTIVECAPTIONTEXT
));
1282 DrawTextW(MemDC
, buffer
, wcslen(buffer
), &r
, DT_VCENTER
| DT_END_ELLIPSIS
);
1284 SetTextColor(MemDC
, OldTextColor
);
1288 if (uFlags
& DC_BUTTONS
)
1290 // Windows XP draws the caption buttons with DC_BUTTONS
1291 // r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1292 // UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE);
1293 // r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
1294 // UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN);
1295 // UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX);
1299 #ifdef DOUBLE_BUFFER_CAPTION
1300 if (! BitBlt(hDC
, lprc
->left
, lprc
->top
, lprc
->right
- lprc
->left
, lprc
->bottom
- lprc
->top
,
1301 MemDC
, 0, 0, SRCCOPY
)) goto cleanup
;
1309 if (OldBrush
) SelectObject(MemDC
, OldBrush
);
1310 if (hOldFont
) SelectObject(MemDC
, hOldFont
);
1311 if (hFont
) DeleteObject(hFont
);
1312 #ifdef DOUBLE_BUFFER_CAPTION
1313 if (OldBMP
) SelectObject(MemDC
, OldBMP
);
1314 if (MemBMP
) DeleteObject(MemBMP
);
1317 OffsetViewportOrgEx(MemDC
, -lprc
->left
, -lprc
->top
, NULL
);
1363 /***********************************************************************
1366 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
1367 * but without the borders (if any).
1368 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
1370 static void FASTCALL
1371 NcGetInsideRect(HWND Wnd
, RECT
*Rect
)
1376 GetWindowRect(Wnd
, Rect
);
1377 Rect
->right
= Rect
->right
- Rect
->left
;
1379 Rect
->bottom
= Rect
->bottom
- Rect
->top
;
1382 Style
= GetWindowLongW(Wnd
, GWL_STYLE
);
1383 if (0 != (Style
& WS_ICONIC
))
1388 /* Remove frame from rectangle */
1389 ExStyle
= GetWindowLongW(Wnd
, GWL_EXSTYLE
);
1390 if (HAS_THICKFRAME(Style
, ExStyle
))
1392 InflateRect(Rect
, - GetSystemMetrics(SM_CXFRAME
), - GetSystemMetrics(SM_CYFRAME
));
1394 else if (HAS_DLGFRAME(Style
, ExStyle
))
1396 InflateRect(Rect
, - GetSystemMetrics(SM_CXDLGFRAME
), - GetSystemMetrics(SM_CYDLGFRAME
));
1398 else if (HAS_THINFRAME(Style
, ExStyle
))
1400 InflateRect(Rect
, - GetSystemMetrics(SM_CXBORDER
), - GetSystemMetrics(SM_CYBORDER
));
1403 /* We have additional border information if the window
1404 * is a child (but not an MDI child) */
1405 if (0 != (Style
& WS_CHILD
)
1406 && 0 == (ExStyle
& WS_EX_MDICHILD
))
1408 if (0 != (ExStyle
& WS_EX_CLIENTEDGE
))
1410 InflateRect(Rect
, - GetSystemMetrics(SM_CXEDGE
), - GetSystemMetrics(SM_CYEDGE
));
1412 if (0 != (ExStyle
& WS_EX_STATICEDGE
))
1414 InflateRect(Rect
, - GetSystemMetrics(SM_CXBORDER
), - GetSystemMetrics(SM_CYBORDER
));
1419 /***********************************************************************
1423 NcGetSysPopupPos(HWND Wnd
, RECT
*Rect
)
1429 GetWindowRect(Wnd
, Rect
);
1433 NcGetInsideRect(Wnd
, Rect
);
1434 GetWindowRect(Wnd
, &WindowRect
);
1435 OffsetRect(Rect
, WindowRect
.left
, WindowRect
.top
);
1436 if (0 != (GetWindowLongW(Wnd
, GWL_STYLE
) & WS_CHILD
))
1438 ClientToScreen(GetParent(Wnd
), (POINT
*) Rect
);
1440 Rect
->right
= Rect
->left
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1441 Rect
->bottom
= Rect
->top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;