1 /* $Id: defwnd.c,v 1.73 2003/08/20 21:42:27 gvg Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/windows/window.c
6 * PURPOSE: Window management
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * 06-06-2001 CSH Created
12 /* INCLUDES ******************************************************************/
17 #include <user32/wininternal.h>
26 /* GLOBALS *******************************************************************/
28 static HBITMAP hbSysMenu
;
29 /* TODO: widgets will be cached here.
30 static HBITMAP hbClose;
31 static HBITMAP hbCloseD;
32 static HBITMAP hbMinimize;
33 static HBITMAP hbMinimizeD;
34 static HBITMAP hbRestore;
35 static HBITMAP hbRestoreD;
36 static HBITMAP hbMaximize;
37 static HBITMAP hbScrUp;
38 static HBITMAP hbScrDwn;
39 static HBITMAP hbScrLeft;
40 static HBITMAP hbScrRight;
44 static COLORREF SysColours
[29] =
46 RGB(224, 224, 224) /* COLOR_SCROLLBAR */,
47 RGB(58, 110, 165) /* COLOR_BACKGROUND */,
48 RGB(0, 0, 128) /* COLOR_ACTIVECAPTION */,
49 RGB(128, 128, 128) /* COLOR_INACTIVECAPTION */,
50 RGB(192, 192, 192) /* COLOR_MENU */,
51 RGB(192, 192, 192) /* COLOR_WINDOW */,
52 RGB(192, 192, 192) /* COLOR_WINDOWFRAME */,
53 RGB(0, 0, 0) /* COLOR_MENUTEXT */,
54 RGB(0, 0, 0) /* COLOR_WINDOWTEXT */,
55 RGB(255, 255, 255) /* COLOR_CAPTIONTEXT */,
56 RGB(128, 128, 128) /* COLOR_ACTIVEBORDER */,
57 RGB(255, 255, 255) /* COLOR_INACTIVEBORDER */,
58 RGB(255, 255, 232) /* COLOR_APPWORKSPACE */,
59 RGB(224, 224, 224) /* COLOR_HILIGHT */,
60 RGB(0, 0, 128) /* COLOR_HILIGHTTEXT */,
61 RGB(192, 192, 192) /* COLOR_BTNFACE */,
62 RGB(128, 128, 128) /* COLOR_BTNSHADOW */,
63 RGB(192, 192, 192) /* COLOR_GRAYTEXT */,
64 RGB(0, 0, 0) /* COLOR_BTNTEXT */,
65 RGB(192, 192, 192) /* COLOR_INACTIVECAPTIONTEXT */,
66 RGB(255, 255, 255) /* COLOR_BTNHILIGHT */,
67 RGB(32, 32, 32) /* COLOR_3DDKSHADOW */,
68 RGB(192, 192, 192) /* COLOR_3DLIGHT */,
69 RGB(0, 0, 0) /* COLOR_INFOTEXT */,
70 RGB(255, 255, 192) /* COLOR_INFOBK */,
71 RGB(184, 180, 184) /* COLOR_ALTERNATEBTNFACE */,
72 RGB(0, 0, 255) /* COLOR_HOTLIGHT */,
73 RGB(16, 132, 208) /* COLOR_GRADIENTACTIVECAPTION */,
74 RGB(181, 181, 181) /* COLOR_GRADIENTINACTIVECAPTION */,
77 static ATOM AtomInternalPos
;
79 /* Bits in the dwKeyData */
80 #define KEYDATA_ALT 0x2000
82 /* FUNCTIONS *****************************************************************/
85 IsMaxBoxActive(HWND hWnd
)
87 ULONG uStyle
= GetWindowLongW( hWnd
, GWL_STYLE
);
88 return (uStyle
& WS_MAXIMIZEBOX
);
92 IsCloseBoxActive( HWND hWnd
)
94 ULONG uStyle
= GetWindowLongW(hWnd
, GWL_STYLE
);
95 return ( uStyle
& WS_SYSMENU
);
99 IsMinBoxActive( HWND hWnd
)
101 ULONG uStyle
= GetWindowLongW( hWnd
, GWL_STYLE
);
102 return (uStyle
& WS_MINIMIZEBOX
);
106 UIGetFrameSizeX( HWND hWnd
)
108 ULONG uStyle
= GetWindowLongW( hWnd
, GWL_STYLE
);
110 if ( uStyle
& WS_THICKFRAME
)
111 return GetSystemMetrics( SM_CXSIZEFRAME
);
113 return GetSystemMetrics( SM_CXFRAME
);
117 UIGetFrameSizeY( HWND hWnd
)
119 ULONG uStyle
= GetWindowLongW( hWnd
, GWL_STYLE
);
121 if ( uStyle
& WS_THICKFRAME
)
122 return GetSystemMetrics( SM_CYSIZEFRAME
);
124 return GetSystemMetrics( SM_CYFRAME
);
128 UserSetupInternalPos( VOID
)
131 AtomInternalPos
= GlobalAddAtomA(Str
);
139 GetSysColor(int nIndex
)
141 return SysColours
[nIndex
];
146 GetSysColorPen( int nIndex
)
148 return(CreatePen(PS_SOLID
, 1, SysColours
[nIndex
]));
156 GetSysColorBrush( int nIndex
)
158 return(CreateSolidBrush(SysColours
[nIndex
]));
166 DefFrameProcA( HWND hWnd
,
180 DefFrameProcW(HWND hWnd
,
191 UserGetInternalPos(HWND hWnd
)
194 lpPos
= (PINTERNALPOS
)GetPropA(hWnd
, (LPSTR
)(DWORD
)AtomInternalPos
);
199 DefWndRedrawIconTitle(HWND hWnd
)
201 PINTERNALPOS lpPos
= (PINTERNALPOS
)GetPropA(hWnd
,
202 (LPSTR
)(DWORD
)AtomInternalPos
);
205 if (lpPos
->IconTitle
!= NULL
)
207 SendMessageA(lpPos
->IconTitle
, WM_SHOWWINDOW
, TRUE
, 0);
208 InvalidateRect(lpPos
->IconTitle
, NULL
, TRUE
);
217 UserHasMenu(HWND hWnd
, ULONG Style
)
219 return(!(Style
& WS_CHILD
) && GetMenu(hWnd
) != 0);
224 UserHasAnyFrameStyle(ULONG Style
, ULONG ExStyle
)
226 return((Style
& (WS_THICKFRAME
| WS_DLGFRAME
| WS_BORDER
)) ||
227 (ExStyle
& WS_EX_DLGMODALFRAME
) ||
228 (!(Style
& (WS_CHILD
| WS_POPUP
))));
233 UserHasDlgFrameStyle(ULONG Style
, ULONG ExStyle
)
235 return((ExStyle
& WS_EX_DLGMODALFRAME
) ||
236 ((Style
& WS_DLGFRAME
) && (!(Style
& WS_THICKFRAME
))));
241 UserHasThickFrameStyle(ULONG Style
, ULONG ExStyle
)
243 return((Style
& WS_THICKFRAME
) &&
244 (!((Style
& (WS_DLGFRAME
| WS_BORDER
)) == WS_DLGFRAME
)));
249 UserHasThinFrameStyle(ULONG Style
, ULONG ExStyle
)
251 return((Style
& WS_BORDER
) ||
252 (!(Style
& (WS_CHILD
| WS_POPUP
))));
257 UserHasBigFrameStyle(ULONG Style
, ULONG ExStyle
)
259 return((Style
& (WS_THICKFRAME
| WS_DLGFRAME
)) ||
260 (ExStyle
& WS_EX_DLGMODALFRAME
));
264 UserGetInsideRectNC( HWND hWnd
, RECT
*rect
)
270 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
271 ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
272 GetWindowRect(hWnd
, &WindowRect
);
273 rect
->top
= rect
->left
= 0;
274 rect
->right
= WindowRect
.right
- WindowRect
.left
;
275 rect
->bottom
= WindowRect
.bottom
- WindowRect
.top
;
277 if (Style
& WS_ICONIC
)
282 /* Remove frame from rectangle */
283 if (UserHasThickFrameStyle(Style
, ExStyle
))
285 InflateRect( rect
, -GetSystemMetrics(SM_CXFRAME
),
286 -GetSystemMetrics(SM_CYFRAME
) );
290 if (UserHasDlgFrameStyle(Style
, ExStyle
))
292 InflateRect( rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
293 -GetSystemMetrics(SM_CYDLGFRAME
));
294 /* FIXME: this isn't in NC_AdjustRect? why not? */
295 if (ExStyle
& WS_EX_DLGMODALFRAME
)
296 InflateRect( rect
, -1, 0 );
300 if (UserHasThinFrameStyle(Style
, ExStyle
))
302 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
303 -GetSystemMetrics(SM_CYBORDER
));
310 UserDrawSysMenuButton( HWND hWnd
, HDC hDC
, LPRECT Rect
, BOOL down
)
313 HBITMAP hSavedBitmap
;
314 WINBOOL result
= FALSE
;
316 hbSysMenu
= (HBITMAP
)LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE
));
317 hDcMem
= CreateCompatibleDC(hDC
);
318 if (! hDcMem
) goto cleanup
;
319 hSavedBitmap
= SelectObject(hDcMem
, hbSysMenu
);
320 if (! hSavedBitmap
) goto cleanup
;
322 BitBlt(hDC
, Rect
->left
+ 2, Rect
->top
+
324 (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
) ?
325 GetSystemMetrics(SM_CXSIZE
): 0, 0, SRCCOPY
);
332 if(hSavedBitmap
) SelectObject(hDcMem
, hSavedBitmap
);
338 /* FIXME: Cache bitmaps, then just bitblt instead of calling DFC() (and
339 wasting precious CPU cycles) every time */
342 UserDrawCaptionButton( HWND hWnd
, HDC hDC
, BOOL bDown
, ULONG Type
)
345 INT iBmpWidth
= GetSystemMetrics(SM_CXSIZE
) - 2;
346 INT iBmpHeight
= GetSystemMetrics(SM_CYSIZE
) - 4;
348 INT OffsetX
= UIGetFrameSizeX( hWnd
);
349 INT OffsetY
= UIGetFrameSizeY( hWnd
);
351 if(!(GetWindowLongW( hWnd
, GWL_STYLE
) & WS_SYSMENU
))
356 GetWindowRect( hWnd
, &rect
);
358 rect
.right
= rect
.right
- rect
.left
;
359 rect
.bottom
= rect
.bottom
- rect
.top
;
360 rect
.left
= rect
.top
= 0;
364 case DFCS_CAPTIONMIN
:
366 if ((GetWindowLongW( hWnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
) == TRUE
)
367 return; /* ToolWindows don't have min/max buttons */
370 rect
.right
- OffsetX
- (iBmpWidth
*3) - 5,
372 rect
.right
- (iBmpWidth
* 2) - OffsetX
- 5,
373 rect
.top
+ iBmpHeight
+ OffsetY
+ 2 );
374 DrawFrameControl( hDC
, &rect
, DFC_CAPTION
,
375 DFCS_CAPTIONMIN
| (bDown
? DFCS_PUSHED
: 0) |
376 (IsMinBoxActive(hWnd
) ? 0 : DFCS_INACTIVE
) );
379 case DFCS_CAPTIONMAX
:
381 if ((GetWindowLongW( hWnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
) == TRUE
)
382 return; /* ToolWindows don't have min/max buttons */
384 rect
.right
- OffsetX
- (iBmpWidth
*2) - 5,
386 rect
.right
- iBmpWidth
- OffsetX
- 5,
387 rect
.top
+ iBmpHeight
+ OffsetY
+ 2 );
389 DrawFrameControl( hDC
, &rect
, DFC_CAPTION
,
390 (IsZoomed(hWnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
) |
391 (bDown
? DFCS_PUSHED
: 0) |
392 (IsMaxBoxActive(hWnd
) ? 0 : DFCS_INACTIVE
) );
395 case DFCS_CAPTIONCLOSE
:
398 rect
.right
- OffsetX
- iBmpWidth
- 3,
400 rect
.right
- OffsetX
- 3,
401 rect
.top
+ iBmpHeight
+ OffsetY
+ 2 );
403 DrawFrameControl( hDC
, &rect
, DFC_CAPTION
,
405 (bDown
? DFCS_PUSHED
: 0) |
406 (IsCloseBoxActive(hWnd
) ? 0 : DFCS_INACTIVE
)) );
412 // Enabling this will cause captions to draw smoother, but slower:
413 // #define DOUBLE_BUFFER_CAPTION
414 // NOTE: Double buffering appears to be broken for this at the moment
427 NONCLIENTMETRICSW nclm
;
430 UINT VCenter
= 0, Padding
= 0;
434 HBRUSH OldBrush
= NULL
;
437 #ifdef DOUBLE_BUFFER_CAPTION
438 HBITMAP MemBMP
= NULL
,
441 MemDC
= CreateCompatibleDC(hDC
);
442 if (! MemDC
) goto cleanup
;
443 MemBMP
= CreateCompatibleBitmap(hDC
, lprc
->right
- lprc
->left
, lprc
->bottom
- lprc
->top
);
444 if (! MemBMP
) goto cleanup
;
445 OldBMP
= SelectObject(MemDC
, MemBMP
);
446 if (! OldBMP
) goto cleanup
;
450 OffsetViewportOrgEx(MemDC
, lprc
->left
, lprc
->top
, NULL
);
453 // If DC_GRADIENT is specified, a Win 98/2000 style caption gradient should
454 // be painted. For now, that flag is ignored:
455 // Windows 98/Me, Windows 2000/XP: When this flag is set, the function uses
456 // COLOR_GRADIENTACTIVECAPTION (if the DC_ACTIVE flag was set) or
457 // COLOR_GRADIENTINACTIVECAPTION for the title-bar color.
459 // Draw the caption background
460 if (uFlags
& DC_INBUTTON
)
462 OldBrush
= SelectObject(MemDC
, GetSysColorBrush(uFlags
& DC_ACTIVE
? COLOR_BTNFACE
: COLOR_BTNSHADOW
) );
463 if (! OldBrush
) goto cleanup
;
464 if (! PatBlt(MemDC
, 0, 0, lprc
->right
- lprc
->left
, lprc
->bottom
- lprc
->top
, PATCOPY
)) goto cleanup
;
468 // DC_GRADIENT check should go here somewhere
469 OldBrush
= SelectObject(MemDC
, GetSysColorBrush(uFlags
& DC_ACTIVE
? COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
) );
470 if (! OldBrush
) goto cleanup
;
471 if (! PatBlt(MemDC
, 0, 0, lprc
->right
- lprc
->left
, lprc
->bottom
- lprc
->top
, PATCOPY
)) goto cleanup
;
474 VCenter
= (lprc
->bottom
- lprc
->top
) / 2;
475 Padding
= VCenter
- (GetSystemMetrics(SM_CYCAPTION
) / 2);
478 r
.right
= r
.left
+ (lprc
->right
- lprc
->left
);
480 r
.bottom
= r
.top
+ (GetSystemMetrics(SM_CYCAPTION
) / 2);
482 if (uFlags
& DC_ICON
)
484 // For some reason the icon isn't centered correctly...
486 UserDrawSysMenuButton(hWnd
, MemDC
, &r
, FALSE
);
493 if ((uFlags
& DC_TEXT
) && (GetWindowTextW( hWnd
, buffer
, sizeof(buffer
)/sizeof(buffer
[0]) )))
495 // Duplicate odd behaviour from Windows:
496 if ((! uFlags
& DC_SMALLCAP
) || (uFlags
& DC_ICON
) || (uFlags
& DC_INBUTTON
) ||
497 (! uFlags
& DC_ACTIVE
))
498 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + Padding
;
500 r
.right
= (lprc
->right
- lprc
->left
);
502 nclm
.cbSize
= sizeof(nclm
);
503 if (! SystemParametersInfoW(SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0)) goto cleanup
;
505 if (uFlags
& DC_INBUTTON
)
506 SetTextColor(MemDC
, SysColours
[ uFlags
& DC_ACTIVE
? COLOR_BTNTEXT
: COLOR_GRAYTEXT
]);
508 SetTextColor(MemDC
, SysColours
[ uFlags
& DC_ACTIVE
? COLOR_CAPTIONTEXT
: COLOR_INACTIVECAPTIONTEXT
]);
510 SetBkMode( MemDC
, TRANSPARENT
);
511 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_EX_TOOLWINDOW
)
512 // if (uFlags & DC_SMALLCAP) // incorrect
513 hFont
= CreateFontIndirectW(&nclm
.lfSmCaptionFont
);
515 hFont
= CreateFontIndirectW(&nclm
.lfCaptionFont
);
517 if (! hFont
) goto cleanup
;
519 hOldFont
= SelectObject(MemDC
, hFont
);
520 if (! hOldFont
) goto cleanup
;
522 DrawTextW(MemDC
, buffer
, wcslen(buffer
), &r
, DT_VCENTER
| DT_END_ELLIPSIS
);
524 // TextOutW(hDC, r.left + (GetSystemMetrics(SM_CXDLGFRAME) * 2), lprc->top + (nclm.lfCaptionFont.lfHeight / 2), buffer, wcslen(buffer));
527 if (uFlags
& DC_BUTTONS
)
529 // Windows XP draws the caption buttons with DC_BUTTONS
530 // r.left += GetSystemMetrics(SM_CXSIZE) + 1;
531 // UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE);
532 // r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
533 // UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN);
534 // UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX);
537 #ifdef DOUBLE_BUFFER_CAPTION
538 if (! BitBlt(hDC
, lprc
->left
, lprc
->top
, lprc
->right
- lprc
->left
, lprc
->bottom
- lprc
->top
,
539 MemDC
, 0, 0, SRCCOPY
)) goto cleanup
;
547 if (OldBrush
) SelectObject(MemDC
, OldBrush
);
548 if (hOldFont
) SelectObject(MemDC
, hOldFont
);
549 if (hFont
) DeleteObject(hFont
);
550 #ifdef DOUBLE_BUFFER_CAPTION
551 if (OldBMP
) SelectObject(MemDC
, OldBMP
);
552 if (MemBMP
) DeleteObject(MemBMP
);
555 OffsetViewportOrgEx(MemDC
, -lprc
->left
, -lprc
->top
, NULL
);
575 capflags
= DC_ICON
| DC_TEXT
;
576 capflags
|= (active
& DC_ACTIVE
);
578 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_EX_TOOLWINDOW
)
579 capflags
|= DC_SMALLCAP
;
582 // PatBlt(hDC,rect->left + GetSystemMetrics(SM_CXFRAME), rect->top +
583 // GetSystemMetrics(SM_CYFRAME), rect->right - (GetSystemMetrics(SM_CXFRAME) * 2), (rect->top +
584 // GetSystemMetrics(SM_CYCAPTION)) - 1, PATCOPY );
586 r
.left
+= GetSystemMetrics(SM_CXFRAME
);
587 r
.top
+= GetSystemMetrics(SM_CYFRAME
);
588 r
.right
-= GetSystemMetrics(SM_CXFRAME
);
589 r
.bottom
= r
.top
+ GetSystemMetrics(SM_CYCAPTION
);
590 // GetSystemMetrics(SM_CYCAPTION)) - 1, PATCOPY );
592 DrawCaption(hWnd
, hDC
, &r
, capflags
);
594 if (style
& WS_SYSMENU
)
596 // UserDrawSysMenuButton( hWnd, hDC, FALSE);
597 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
598 UserDrawCaptionButton( hWnd
, hDC
, FALSE
, DFCS_CAPTIONCLOSE
);
599 r
.right
-= GetSystemMetrics(SM_CXSMSIZE
) + 1;
600 UserDrawCaptionButton( hWnd
, hDC
, FALSE
, DFCS_CAPTIONMIN
);
601 UserDrawCaptionButton( hWnd
, hDC
, FALSE
, DFCS_CAPTIONMAX
);
607 UserDrawFrameNC(HWND hWnd
, RECT
* rect
, BOOL dlgFrame
, BOOL active
)
609 HDC hDC
= GetWindowDC(hWnd
);
610 SelectObject( hDC
, GetSysColorBrush(COLOR_WINDOW
) );
611 DrawEdge(hDC
, rect
,EDGE_RAISED
, BF_RECT
| BF_MIDDLE
);
616 SCROLL_DrawScrollBar (HWND hWnd
, HDC hDC
, INT nBar
, BOOL arrows
, BOOL interior
);
619 DefWndDoPaintNC(HWND hWnd
, HRGN clip
)
628 // This won't work because it conflicts with BS_BITMAP :
629 if (GetActiveWindow() == hWnd
) Active
= TRUE
;
630 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
631 ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
633 hDC
= GetDCEx(hWnd
, (clip
> (HRGN
)1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
634 ((clip
> (HRGN
)1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0));
640 /* FIXME: Test whether we need to draw anything at all. */
642 GetWindowRect(hWnd
, &rect
);
643 rect
.right
= rect
.right
- rect
.left
;
644 rect
.bottom
= rect
.bottom
- rect
.top
;
645 rect
.top
= rect
.left
= 0;
646 SelectObject(hDC
, GetSysColorPen(COLOR_WINDOWFRAME
));
647 if (UserHasThickFrameStyle(Style
, ExStyle
))
649 UserDrawFrameNC(hWnd
, &rect
, FALSE
, Active
);
650 wFrame
= GetSystemMetrics(SM_CXSIZEFRAME
);
652 else if (UserHasDlgFrameStyle(Style
, ExStyle
))
654 UserDrawFrameNC(hWnd
, &rect
, TRUE
, Active
);
655 wFrame
= GetSystemMetrics(SM_CXDLGFRAME
);
657 if (Style
& WS_CAPTION
)
660 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
);
661 rect
.top
+= GetSystemMetrics(SM_CYSIZE
) +
662 GetSystemMetrics(SM_CYBORDER
);
663 UserDrawCaptionNC(hDC
, &r
, hWnd
, Style
, Active
);
667 if (UserHasMenu(hWnd
, Style
))
670 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
);
673 rect
.top
+= MenuDrawMenuBar(hDC
, &r
, hWnd
, FALSE
);
676 /* Draw scrollbars */
677 if (Style
& WS_VSCROLL
)
678 SCROLL_DrawScrollBar(hWnd
, hDC
, SB_VERT
, TRUE
, TRUE
);
679 if (Style
& WS_HSCROLL
)
680 SCROLL_DrawScrollBar(hWnd
, hDC
, SB_HORZ
, TRUE
, TRUE
);
682 /* FIXME: Draw size box.*/
684 ReleaseDC(hWnd
, hDC
);
689 DefWndPaintNC(HWND hWnd
, HRGN clip
)
691 if (IsWindowVisible(hWnd
))
695 DefWndRedrawIconTitle(hWnd
);
699 DefWndDoPaintNC(hWnd
, clip
);
707 DefWndHitTestNC(HWND hWnd
, POINT Point
)
710 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
711 ULONG ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
713 GetWindowRect(hWnd
, &WindowRect
);
714 if (!PtInRect(&WindowRect
, Point
))
718 if (Style
& WS_MINIMIZE
)
722 if (UserHasThickFrameStyle(Style
, ExStyle
))
724 InflateRect(&WindowRect
, -GetSystemMetrics(SM_CXFRAME
),
725 -GetSystemMetrics(SM_CYFRAME
));
726 if (!PtInRect(&WindowRect
, Point
))
728 if (Point
.y
< WindowRect
.top
)
730 if (Point
.x
< (WindowRect
.left
+ GetSystemMetrics(SM_CXSIZE
)))
734 if (Point
.x
>= (WindowRect
.right
- GetSystemMetrics(SM_CXSIZE
)))
740 if (Point
.y
>= WindowRect
.bottom
)
742 if (Point
.x
< (WindowRect
.left
+ GetSystemMetrics(SM_CXSIZE
)))
744 return(HTBOTTOMLEFT
);
746 if (Point
.x
>= (WindowRect
.right
- GetSystemMetrics(SM_CXSIZE
)))
748 return(HTBOTTOMRIGHT
);
752 if (Point
.x
< WindowRect
.left
)
754 if (Point
.y
< (WindowRect
.top
+ GetSystemMetrics(SM_CYSIZE
)))
758 if (Point
.y
>= (WindowRect
.bottom
- GetSystemMetrics(SM_CYSIZE
)))
760 return(HTBOTTOMLEFT
);
764 if (Point
.x
>= WindowRect
.right
)
766 if (Point
.y
< (WindowRect
.top
+ GetSystemMetrics(SM_CYSIZE
)))
770 if (Point
.y
>= (WindowRect
.bottom
- GetSystemMetrics(SM_CYSIZE
)))
772 return(HTBOTTOMRIGHT
);
780 if (UserHasDlgFrameStyle(Style
, ExStyle
))
782 InflateRect(&WindowRect
, -GetSystemMetrics(SM_CXDLGFRAME
),
783 -GetSystemMetrics(SM_CYDLGFRAME
));
785 else if (UserHasThinFrameStyle(Style
, ExStyle
))
787 InflateRect(&WindowRect
, -GetSystemMetrics(SM_CXBORDER
),
788 -GetSystemMetrics(SM_CYBORDER
));
790 if (!PtInRect(&WindowRect
, Point
))
796 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
798 WindowRect
.top
+= (GetSystemMetrics(SM_CYCAPTION
) -
799 GetSystemMetrics(SM_CYBORDER
));
800 if (!PtInRect(&WindowRect
, Point
))
802 if ((Style
& WS_SYSMENU
) && !(ExStyle
& WS_EX_TOOLWINDOW
))
804 WindowRect
.left
+= GetSystemMetrics(SM_CXSIZE
);
805 WindowRect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
807 if (Point
.x
<= WindowRect
.left
)
811 if (WindowRect
.right
<= Point
.x
)
816 if (Style
& WS_MAXIMIZEBOX
|| Style
& WS_MINIMIZEBOX
)
818 WindowRect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
820 if (Point
.x
>= WindowRect
.right
)
825 if (Style
& WS_MINIMIZEBOX
)
827 WindowRect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
829 if (Point
.x
>= WindowRect
.right
)
837 ScreenToClient(hWnd
, &Point
);
838 GetClientRect(hWnd
, &WindowRect
);
840 if (PtInRect(&WindowRect
, Point
))
845 if (Style
& WS_VSCROLL
)
847 WindowRect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
848 if (PtInRect(&WindowRect
, Point
))
854 if (Style
& WS_HSCROLL
)
856 WindowRect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
857 if (PtInRect(&WindowRect
, Point
))
859 if ((Style
& WS_VSCROLL
) &&
860 (Point
.x
>= (WindowRect
.right
- GetSystemMetrics(SM_CXVSCROLL
))))
868 if (UserHasMenu(hWnd
, Style
))
870 if (Point
.y
< 0 && Point
.x
>= 0 && Point
.x
<= WindowRect
.right
)
880 DefWndHandleLButtonDownNC(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
886 HWND hTopWnd
= GetAncestor(hWnd
, GA_ROOT
);
887 if (SetActiveWindow(hTopWnd
) || GetActiveWindow() == hTopWnd
)
889 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
895 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_SYSMENU
)
897 if (!(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
899 HDC hDC
= GetWindowDC(hWnd
);
900 // UserDrawSysMenuButton(hWnd, hDC, TRUE);
901 ReleaseDC(hWnd
, hDC
);
903 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
,
910 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
915 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
920 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
925 UserDrawCaptionButton( hWnd
, GetWindowDC(hWnd
), IsMinBoxActive(hWnd
), DFCS_CAPTIONMIN
);
930 UserDrawCaptionButton( hWnd
, GetWindowDC(hWnd
), IsMaxBoxActive(hWnd
), DFCS_CAPTIONMAX
);
935 UserDrawCaptionButton( hWnd
, GetWindowDC(hWnd
), TRUE
, DFCS_CAPTIONCLOSE
);
947 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
956 DefWndHandleLButtonDblClkNC(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
964 DefWndHandleLButtonUpNC(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
966 UserDrawCaptionButton( hWnd
, GetWindowDC(hWnd
), FALSE
, DFCS_CAPTIONMIN
);
967 UserDrawCaptionButton( hWnd
, GetWindowDC(hWnd
), FALSE
, DFCS_CAPTIONMAX
);
968 UserDrawCaptionButton( hWnd
, GetWindowDC(hWnd
), FALSE
, DFCS_CAPTIONCLOSE
);
973 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
978 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
983 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
992 DefWndHandleActiveNC(HWND hWnd
, WPARAM wParam
)
1000 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
1007 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1009 /* Not for child windows. */
1010 if (hWnd
!= (HWND
)wParam
)
1015 switch(LOWORD(lParam
))
1019 WORD Msg
= HIWORD(lParam
);
1020 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
1021 Msg
== WM_RBUTTONDOWN
)
1030 HICON hCursor
= (HICON
)GetClassLongW(hWnd
, GCL_HCURSOR
);
1042 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
1048 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
1054 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
1060 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
1063 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
1067 DefWndStartSizeMove(HWND hWnd
, WPARAM wParam
, POINT
*capturePoint
)
1073 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1075 GetWindowRect(hWnd
, &rectWindow
);
1077 if ((wParam
& 0xfff0) == SC_MOVE
)
1079 /* Move pointer at the center of the caption */
1081 UserGetInsideRectNC(hWnd
, &rect
);
1082 if (Style
& WS_SYSMENU
)
1083 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
1084 if (Style
& WS_MINIMIZEBOX
)
1085 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1086 if (Style
& WS_MAXIMIZEBOX
)
1087 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1088 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
1089 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
1090 hittest
= HTCAPTION
;
1097 GetMessageW(&msg
, NULL
, 0, 0);
1101 hittest
= DefWndHitTestNC(hWnd
, msg
.pt
);
1102 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
1114 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
1115 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
1119 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
1120 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
1124 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
1125 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
1129 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
1130 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
1133 case VK_ESCAPE
: return 0;
1139 SetCursorPos( pt
.x
, pt
.y
);
1140 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
));
1144 #define ON_LEFT_BORDER(hit) \
1145 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
1146 #define ON_RIGHT_BORDER(hit) \
1147 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
1148 #define ON_TOP_BORDER(hit) \
1149 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
1150 #define ON_BOTTOM_BORDER(hit) \
1151 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
1154 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
1155 ULONG width
, ULONG height
, DWORD rop
)
1157 HBRUSH hbrush
= SelectObject( hdc
, GetStockObject( GRAY_BRUSH
) );
1158 PatBlt( hdc
, rect
->left
, rect
->top
,
1159 rect
->right
- rect
->left
- width
, height
, rop
);
1160 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
1161 rect
->bottom
- rect
->top
- height
, rop
);
1162 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
1163 rect
->right
- rect
->left
- width
, -height
, rop
);
1164 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
1165 rect
->bottom
- rect
->top
- height
, rop
);
1166 SelectObject( hdc
, hbrush
);
1170 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
1174 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
),
1175 GetSystemMetrics(SM_CYFRAME
), PATINVERT
);
1177 else DrawFocusRect( hdc
, rect
);
1181 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
1184 RECT sizingRect
, mouseRect
, origRect
;
1186 LONG hittest
= (LONG
)(wParam
& 0x0f);
1187 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
1188 POINT minTrack
, maxTrack
;
1189 POINT capturePoint
, pt
;
1190 ULONG Style
= GetWindowLongW(hwnd
, GWL_STYLE
);
1191 ULONG ExStyle
= GetWindowLongW(hwnd
, GWL_EXSTYLE
);
1192 BOOL thickframe
= UserHasThickFrameStyle(Style
, ExStyle
);
1193 BOOL iconic
= Style
& WS_MINIMIZE
;
1195 DWORD dwPoint
= GetMessagePos();
1196 BOOL DragFullWindows
= FALSE
;
1199 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
1201 pt
.x
= SLOWORD(dwPoint
);
1202 pt
.y
= SHIWORD(dwPoint
);
1205 if (IsZoomed(hwnd
) || !IsWindowVisible(hwnd
))
1210 if ((wParam
& 0xfff0) == SC_MOVE
)
1214 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
1227 if (hittest
&& hittest
!= HTSYSMENU
)
1234 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
1243 if (Style
& WS_CHILD
)
1245 hWndParent
= GetParent(hwnd
);
1248 /* Get min/max info */
1250 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
1251 GetWindowRect(hwnd
, &sizingRect
);
1252 origRect
= sizingRect
;
1253 if (Style
& WS_CHILD
)
1255 GetClientRect(hWndParent
, &mouseRect
);
1259 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
),
1260 GetSystemMetrics(SM_CYSCREEN
));
1262 if (ON_LEFT_BORDER(hittest
))
1264 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
1265 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
1267 else if (ON_RIGHT_BORDER(hittest
))
1269 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
1270 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
1272 if (ON_TOP_BORDER(hittest
))
1274 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
1275 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
1277 else if (ON_BOTTOM_BORDER(hittest
))
1279 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
1280 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
1282 if (Style
& WS_CHILD
)
1284 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
1286 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
1288 if (GetCapture() != hwnd
) SetCapture( hwnd
);
1290 if (Style
& WS_CHILD
)
1292 /* Retrieve a default cache DC (without using the window style) */
1293 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
1300 if( iconic
) /* create a cursor for dragging */
1302 HICON hIcon
= (HICON
)GetClassLongW(hwnd
, GCL_HICON
);
1303 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
1304 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
1305 if( !hDragCursor
) iconic
= FALSE
;
1308 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
1309 if( !iconic
&& !DragFullWindows
)
1311 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
1318 GetMessageW(&msg
, 0, 0, 0);
1320 /* Exit on button-up, Return, or Esc */
1321 if ((msg
.message
== WM_LBUTTONUP
) ||
1322 ((msg
.message
== WM_KEYDOWN
) &&
1323 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
1325 if (msg
.message
== WM_PAINT
)
1327 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
1328 UpdateWindow( msg
.hwnd
);
1329 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
1333 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
1334 continue; /* We are not interested in other messages */
1338 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
1340 case VK_UP
: pt
.y
-= 8; break;
1341 case VK_DOWN
: pt
.y
+= 8; break;
1342 case VK_LEFT
: pt
.x
-= 8; break;
1343 case VK_RIGHT
: pt
.x
+= 8; break;
1346 pt
.x
= max( pt
.x
, mouseRect
.left
);
1347 pt
.x
= min( pt
.x
, mouseRect
.right
);
1348 pt
.y
= max( pt
.y
, mouseRect
.top
);
1349 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
1351 dx
= pt
.x
- capturePoint
.x
;
1352 dy
= pt
.y
- capturePoint
.y
;
1360 if( iconic
) /* ok, no system popup tracking */
1362 hOldCursor
= SetCursor(hDragCursor
);
1364 WinPosShowIconTitle( hwnd
, FALSE
);
1368 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
1371 RECT newRect
= sizingRect
;
1372 WPARAM wpSizingHit
= 0;
1374 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
1375 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
1376 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
1377 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
1378 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
1379 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
1382 /* determine the hit location */
1383 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
1384 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
1385 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
1389 if(!DragFullWindows
)
1390 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
1392 /* To avoid any deadlocks, all the locks on the windows
1393 structures must be suspended before the SetWindowPos */
1394 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
1395 newRect
.right
- newRect
.left
,
1396 newRect
.bottom
- newRect
.top
,
1397 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
1400 sizingRect
= newRect
;
1408 if( moved
) /* restore cursors, show icon title later on */
1410 ShowCursor( FALSE
);
1411 SetCursor( hOldCursor
);
1413 DestroyCursor( hDragCursor
);
1415 else if(!DragFullWindows
)
1416 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
1418 if (Style
& WS_CHILD
)
1419 ReleaseDC( hWndParent
, hdc
);
1421 ReleaseDC( 0, hdc
);
1423 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
1424 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
1426 /* window moved or resized */
1429 /* if the moving/resizing isn't canceled call SetWindowPos
1430 * with the new position or the new size of the window
1432 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
1434 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
1435 if(!DragFullWindows
)
1436 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
1437 sizingRect
.right
- sizingRect
.left
,
1438 sizingRect
.bottom
- sizingRect
.top
,
1439 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
1441 else { /* restore previous size/position */
1443 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
1444 origRect
.right
- origRect
.left
,
1445 origRect
.bottom
- origRect
.top
,
1446 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
1450 if( IsWindow(hwnd
) )
1451 if( Style
& WS_MINIMIZE
)
1453 /* Single click brings up the system menu when iconized */
1457 if( Style
& WS_SYSMENU
)
1458 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1459 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
1461 else WinPosShowIconTitle( hwnd
, TRUE
);
1467 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, POINT Pt
)
1469 switch (wParam
& 0xfff0)
1473 DefWndDoSizeMove(hWnd
, wParam
);
1476 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
1479 MenuTrackMouseMenuBar(hWnd
, wParam
, Pt
);
1482 MenuTrackKbdMenuBar(hWnd
, wParam
, Pt
.x
);
1485 /* FIXME: Implement */
1495 DefWndAdjustRect(RECT
* Rect
, ULONG Style
, BOOL Menu
, ULONG ExStyle
)
1497 if (Style
& WS_ICONIC
)
1502 if (UserHasThickFrameStyle(Style
, ExStyle
))
1504 InflateRect(Rect
, GetSystemMetrics(SM_CXFRAME
),
1505 GetSystemMetrics(SM_CYFRAME
));
1507 else if (UserHasDlgFrameStyle(Style
, ExStyle
))
1509 InflateRect(Rect
, GetSystemMetrics(SM_CXDLGFRAME
),
1510 GetSystemMetrics(SM_CYDLGFRAME
));
1512 else if (UserHasThinFrameStyle(Style
, ExStyle
))
1514 InflateRect(Rect
, GetSystemMetrics(SM_CXBORDER
),
1515 GetSystemMetrics(SM_CYBORDER
));
1517 if (Style
& WS_CAPTION
)
1519 Rect
->top
-= (GetSystemMetrics(SM_CYCAPTION
) -
1520 GetSystemMetrics(SM_CYBORDER
)) + 1;
1524 Rect
->top
-= GetSystemMetrics(SM_CYMENU
) + GetSystemMetrics(SM_CYBORDER
);
1526 if (Style
& WS_VSCROLL
)
1528 Rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
) - 1;
1529 if (UserHasAnyFrameStyle(Style
, ExStyle
))
1534 if (Style
& WS_HSCROLL
)
1536 Rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
) - 1;
1537 if (UserHasAnyFrameStyle(Style
, ExStyle
))
1546 DefWndNCCalcSize(HWND hWnd
, RECT
* Rect
)
1549 LONG Style
= GetClassLongW(hWnd
, GCL_STYLE
);
1550 RECT TmpRect
= {0, 0, 0, 0};
1552 if (Style
& CS_VREDRAW
)
1554 Result
|= WVR_VREDRAW
;
1556 if (Style
& CS_HREDRAW
)
1558 Result
|= WVR_HREDRAW
;
1561 if (!(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1563 DefWndAdjustRect(&TmpRect
, GetWindowLongW(hWnd
, GWL_STYLE
),
1564 FALSE
, GetWindowLongW(hWnd
, GWL_EXSTYLE
));
1565 Rect
->left
-= TmpRect
.left
;
1566 Rect
->top
-= TmpRect
.top
;
1567 Rect
->right
-= TmpRect
.right
;
1568 Rect
->bottom
-= TmpRect
.bottom
;
1569 if (UserHasMenu(hWnd
, GetWindowLongW(hWnd
, GWL_EXSTYLE
)))
1571 Rect
->top
+= MenuGetMenuBarHeight(hWnd
,
1572 Rect
->right
- Rect
->left
,
1576 Rect
->bottom
= max(Rect
->top
, Rect
->bottom
);
1577 Rect
->right
= max(Rect
->left
, Rect
->right
);
1584 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
1592 User32DefWindowProc(HWND hWnd
,
1602 return(DefWndPaintNC(hWnd
, (HRGN
)wParam
));
1604 case WM_WINDOWPOSCHANGING
:
1611 Point
.x
= SLOWORD(lParam
);
1612 Point
.y
= SHIWORD(lParam
);
1613 return(DefWndHitTestNC(hWnd
, Point
));
1616 case WM_NCLBUTTONDOWN
:
1618 return(DefWndHandleLButtonDownNC(hWnd
, wParam
, lParam
));
1621 case WM_NCLBUTTONUP
:
1623 return(DefWndHandleLButtonUpNC(hWnd
, wParam
, lParam
));
1626 case WM_LBUTTONDBLCLK
:
1627 case WM_NCLBUTTONDBLCLK
:
1629 return(DefWndHandleLButtonDblClkNC(hWnd
, wParam
, lParam
));
1632 case WM_NCRBUTTONDOWN
:
1634 if (wParam
== HTCAPTION
)
1647 if (hWnd
== GetCapture())
1651 Pt
.x
= SLOWORD(lParam
);
1652 Pt
.y
= SHIWORD(lParam
);
1653 ClientToScreen(hWnd
, &Pt
);
1654 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1657 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1661 SendMessageA (hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1666 case WM_NCRBUTTONUP
:
1668 /* Wine does nothing here. */
1672 case WM_CONTEXTMENU
:
1674 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1678 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1682 SendMessageA(hWnd
, WM_CONTEXTMENU
, wParam
, lParam
);
1690 Pt
.x
= SLOWORD(lParam
);
1691 Pt
.y
= SHIWORD(lParam
);
1693 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1695 ScreenToClient(GetParent(hWnd
), &Pt
);
1698 HitCode
= DefWndHitTestNC(hWnd
, Pt
);
1700 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1702 TrackPopupMenu(GetSystemMenu(hWnd
, FALSE
),
1703 TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1704 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1712 return(DefWndHandleActiveNC(hWnd
, wParam
));
1729 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1733 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1734 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1738 GetWindowRect(hWnd
, &WindowRect
);
1739 x
= (WindowRect
.right
- WindowRect
.left
-
1740 GetSystemMetrics(SM_CXICON
)) / 2;
1741 y
= (WindowRect
.bottom
- WindowRect
.top
-
1742 GetSystemMetrics(SM_CYICON
)) / 2;
1743 DrawIcon(hDC
, x
, y
, hIcon
);
1745 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_CLIENTEDGE
)
1748 GetClientRect(hWnd
, &WindowRect
);
1749 DrawEdge(hDC
, &WindowRect
, EDGE_SUNKEN
, BF_RECT
);
1751 EndPaint(hWnd
, &Ps
);
1759 hRgn
= CreateRectRgn(0, 0, 0, 0);
1760 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1762 RedrawWindow(hWnd
, NULL
, hRgn
,
1763 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1772 DefWndSetRedraw(hWnd
, wParam
);
1778 DestroyWindow(hWnd
);
1782 case WM_MOUSEACTIVATE
:
1784 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1789 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1794 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1802 return((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1807 /* Check if the window is minimized. */
1808 if (LOWORD(lParam
) != WA_INACTIVE
&&
1809 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1818 if (GetWindowLongW(hWnd
, GWL_STYLE
& WS_CHILD
))
1822 return(SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1827 return(SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1835 case WM_ICONERASEBKGND
:
1839 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1844 if (0 == (((DWORD
) hBrush
) & 0xffff0000))
1846 hBrush
= GetSysColorBrush((DWORD
) hBrush
- 1);
1848 GetClipBox((HDC
)wParam
, &Rect
);
1849 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1858 /* FIXME: Implement colour controls. */
1862 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1864 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1869 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1874 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1883 return(DefWndHandleSetCursor(hWnd
, wParam
, lParam
));
1889 Pt
.x
= SLOWORD(lParam
);
1890 Pt
.y
= SHIWORD(lParam
);
1891 return(DefWndHandleSysCommand(hWnd
, wParam
, Pt
));
1894 /* FIXME: Handle key messages. */
1902 /* FIXME: Not done correctly */
1903 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_VISIBLE
&& !wParam
) ||
1904 (!(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_VISIBLE
) && wParam
))
1908 ShowWindow(hWnd
, wParam
? SW_SHOWNA
: SW_HIDE
);
1914 /* FIXME: Check for a desktop. */
1915 if (GetCapture() == hWnd
)
1927 /* FIXME: Implement this. */
1930 case WM_QUERYDROPOBJECT
:
1932 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1939 case WM_QUERYDRAGICON
:
1944 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1947 return((LRESULT
)hIcon
);
1949 for (Len
= 1; Len
< 64; Len
++)
1951 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1953 return((LRESULT
)hIcon
);
1956 return((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1959 /* FIXME: WM_ISACTIVEICON */
1961 case WM_NOTIFYFORMAT
:
1963 if (IsWindowUnicode(hWnd
))
1965 return(NFR_UNICODE
);
1975 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1976 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1977 SetClassLongW(hWnd
, Index
, lParam
);
1978 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1979 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1980 SWP_NOACTIVATE
| SWP_NOZORDER
);
1981 return((LRESULT
)hOldIcon
);
1986 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1987 return(GetClassLongW(hWnd
, Index
));
1994 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1998 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
2004 if (HIWORD(lParam
) & KEYDATA_ALT
)
2006 if (wParam
== VK_F4
) /* Try to close the window */
2008 //HWND hTopWnd = GetAncestor(hWnd, GA_ROOT);
2009 HWND hTopWnd
= hWnd
;
2010 if (!(GetClassLongW(hTopWnd
, GCL_STYLE
) & CS_NOCLOSE
))
2014 PostMessageW(hTopWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
2018 PostMessageA(hTopWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
2030 DefWindowProcA(HWND hWnd
,
2036 static LPSTR WindowTextAtom
= 0;
2043 CREATESTRUCTA
* Cs
= (CREATESTRUCTA
*)lParam
;
2044 if (HIWORD(Cs
->lpszName
))
2046 if (0 == WindowTextAtom
)
2049 (LPSTR
)(ULONG
)GlobalAddAtomA("USER32!WindowTextAtomA");
2051 WindowText
= RtlAllocateHeap(RtlGetProcessHeap(), 0,
2052 strlen(Cs
->lpszName
) * sizeof(CHAR
));
2053 strcpy(WindowText
, Cs
->lpszName
);
2054 SetPropA(hWnd
, WindowTextAtom
, WindowText
);
2061 return(DefWndNCCalcSize(hWnd
, (RECT
*)lParam
));
2064 case WM_WINDOWPOSCHANGING
:
2066 return(DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
2069 case WM_GETTEXTLENGTH
:
2071 if (WindowTextAtom
== 0 ||
2072 (WindowText
= GetPropA(hWnd
, WindowTextAtom
)) == NULL
)
2076 return(strlen(WindowText
));
2081 if (WindowTextAtom
== 0 ||
2082 (WindowText
= GetPropA(hWnd
, WindowTextAtom
)) == NULL
)
2086 *((PSTR
)lParam
) = '\0';
2090 strncpy((LPSTR
)lParam
, WindowText
, wParam
);
2091 return(min(wParam
, strlen(WindowText
)));
2096 if (0 == WindowTextAtom
)
2099 (LPSTR
)(DWORD
)GlobalAddAtomA("USER32!WindowTextAtomA");
2101 if (WindowTextAtom
!= 0 &&
2102 (WindowText
= GetPropA(hWnd
, WindowTextAtom
)) == NULL
)
2104 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText
);
2106 WindowText
= RtlAllocateHeap(RtlGetProcessHeap(), 0,
2107 strlen((PSTR
)lParam
) * sizeof(CHAR
));
2108 strcpy(WindowText
, (PSTR
)lParam
);
2109 SetPropA(hWnd
, WindowTextAtom
, WindowText
);
2110 if (0 != (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
))
2112 DefWndPaintNC(hWnd
, (HRGN
) 1);
2114 Result
= (LPARAM
) TRUE
;
2120 if (WindowTextAtom
!= 0 &&
2121 (WindowText
= RemovePropA(hWnd
, WindowTextAtom
)) == NULL
)
2123 RtlFreeHeap(GetProcessHeap(), 0, WindowText
);
2129 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2138 DefWindowProcW(HWND hWnd
,
2144 static LPWSTR WindowTextAtom
= 0;
2151 CREATESTRUCTW
* Cs
= (CREATESTRUCTW
*)lParam
;
2152 if (HIWORD(Cs
->lpszName
))
2154 if (0 == WindowTextAtom
)
2157 (LPWSTR
)(DWORD
)GlobalAddAtomW(L
"USER32!WindowTextAtomW");
2159 WindowText
= RtlAllocateHeap(RtlGetProcessHeap(), 0,
2160 wcslen(Cs
->lpszName
) * sizeof(WCHAR
));
2161 wcscpy(WindowText
, Cs
->lpszName
);
2162 SetPropW(hWnd
, WindowTextAtom
, WindowText
);
2169 return(DefWndNCCalcSize(hWnd
, (RECT
*)lParam
));
2172 case WM_WINDOWPOSCHANGING
:
2174 return(DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
2177 case WM_GETTEXTLENGTH
:
2179 if (WindowTextAtom
== 0 ||
2180 (WindowText
= GetPropW(hWnd
, WindowTextAtom
)) == NULL
)
2184 return(wcslen(WindowText
));
2189 if (WindowTextAtom
== 0 ||
2190 (WindowText
= GetPropW(hWnd
, WindowTextAtom
)) == NULL
)
2194 ((PWSTR
)lParam
) = '\0';
2198 wcsncpy((PWSTR
)lParam
, WindowText
, wParam
);
2199 return(min(wParam
, wcslen(WindowText
)));
2204 if (WindowTextAtom
== 0)
2207 (LPWSTR
)(DWORD
)GlobalAddAtomW(L
"USER32!WindowTextAtomW");
2209 if (WindowTextAtom
!= 0 &&
2210 (WindowText
= GetPropW(hWnd
, WindowTextAtom
)) == NULL
)
2212 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText
);
2214 WindowText
= RtlAllocateHeap(RtlGetProcessHeap(), 0,
2215 wcslen((PWSTR
)lParam
) * sizeof(WCHAR
));
2216 wcscpy(WindowText
, (PWSTR
)lParam
);
2217 SetPropW(hWnd
, WindowTextAtom
, WindowText
);
2218 if (0 != (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
))
2220 DefWndPaintNC(hWnd
, (HRGN
) 1);
2222 Result
= (LPARAM
) TRUE
;
2228 if (WindowTextAtom
!= 0 &&
2229 (WindowText
= RemovePropW(hWnd
, WindowTextAtom
)) == NULL
)
2231 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText
);
2237 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);