1 /* $Id: defwnd.c,v 1.102 2003/10/25 22:57:34 navaraf 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 LRESULT
DefWndNCPaint(HWND hWnd
, HRGN hRgn
);
27 LRESULT
DefWndNCCalcSize(HWND hWnd
, BOOL CalcSizeStruct
, RECT
*Rect
);
28 LRESULT
DefWndNCActivate(HWND hWnd
, WPARAM wParam
);
29 LRESULT
DefWndNCHitTest(HWND hWnd
, POINT Point
);
30 LRESULT
DefWndNCLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
31 LRESULT
DefWndNCLButtonDblClk(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
32 LRESULT
DefWndNCLButtonUp(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
34 /* GLOBALS *******************************************************************/
36 /* TODO: widgets will be cached here.
37 static HBITMAP hbClose;
38 static HBITMAP hbCloseD;
39 static HBITMAP hbMinimize;
40 static HBITMAP hbMinimizeD;
41 static HBITMAP hbRestore;
42 static HBITMAP hbRestoreD;
43 static HBITMAP hbMaximize;
44 static HBITMAP hbScrUp;
45 static HBITMAP hbScrDwn;
46 static HBITMAP hbScrLeft;
47 static HBITMAP hbScrRight;
51 static COLORREF SysColours
[] =
53 RGB(192, 192, 192) /* COLOR_SCROLLBAR */,
54 RGB(58, 110, 165) /* COLOR_BACKGROUND */,
55 RGB(0, 0, 128) /* COLOR_ACTIVECAPTION */,
56 RGB(128, 128, 128) /* COLOR_INACTIVECAPTION */,
57 RGB(192, 192, 192) /* COLOR_MENU */,
58 RGB(255, 255, 255) /* COLOR_WINDOW */,
59 RGB(0, 0, 0) /* COLOR_WINDOWFRAME */,
60 RGB(0, 0, 0) /* COLOR_MENUTEXT */,
61 RGB(0, 0, 0) /* COLOR_WINDOWTEXT */,
62 RGB(255, 255, 255) /* COLOR_CAPTIONTEXT */,
63 RGB(192, 192, 192) /* COLOR_ACTIVEBORDER */,
64 RGB(192, 192, 192) /* COLOR_INACTIVEBORDER */,
65 RGB(128, 128, 128) /* COLOR_APPWORKSPACE */,
66 RGB(0, 0, 128) /* COLOR_HILIGHT */,
67 RGB(255, 255, 255) /* COLOR_HILIGHTTEXT */,
68 RGB(192, 192, 192) /* COLOR_BTNFACE */,
69 RGB(128, 128, 128) /* COLOR_BTNSHADOW */,
70 RGB(128, 128, 128) /* COLOR_GRAYTEXT */,
71 RGB(0, 0, 0) /* COLOR_BTNTEXT */,
72 RGB(192, 192, 192) /* COLOR_INACTIVECAPTIONTEXT */,
73 RGB(255, 255, 255) /* COLOR_BTNHILIGHT */,
74 RGB(32, 32, 32) /* COLOR_3DDKSHADOW */,
75 RGB(224, 224, 224) /* COLOR_3DLIGHT */,
76 RGB(0, 0, 0) /* COLOR_INFOTEXT */,
77 RGB(255, 255, 192) /* COLOR_INFOBK */,
78 RGB(180, 180, 180) /* COLOR_ALTERNATEBTNFACE */,
79 RGB(0, 0, 255) /* COLOR_HOTLIGHT */,
80 RGB(16, 132, 208) /* COLOR_GRADIENTACTIVECAPTION */,
81 RGB(181, 181, 181) /* COLOR_GRADIENTINACTIVECAPTION */,
84 #define NUM_SYSCOLORS (sizeof(SysColours) / sizeof(SysColours[0]))
88 /* Bits in the dwKeyData */
89 #define KEYDATA_ALT 0x2000
91 /* FUNCTIONS *****************************************************************/
94 UserSetupInternalPos(VOID
)
97 AtomInternalPos
= GlobalAddAtomA(Str
);
104 GetSysColor(int nIndex
)
106 return SysColours
[nIndex
];
113 GetSysColorPen(int nIndex
)
115 static HPEN SysPens
[NUM_SYSCOLORS
];
117 if (nIndex
< 0 || NUM_SYSCOLORS
< nIndex
)
119 SetLastError(ERROR_INVALID_PARAMETER
);
123 /* FIXME should register this object with DeleteObject() so it
125 if (NULL
== SysPens
[nIndex
])
127 SysPens
[nIndex
] = CreatePen(PS_SOLID
, 1, SysColours
[nIndex
]);
130 return SysPens
[nIndex
];
137 GetSysColorBrush(int nIndex
)
139 static HBRUSH SysBrushes
[NUM_SYSCOLORS
];
141 if (nIndex
< 0 || NUM_SYSCOLORS
< nIndex
)
143 SetLastError(ERROR_INVALID_PARAMETER
);
147 /* FIXME should register this object with DeleteObject() so it
149 if (NULL
== SysBrushes
[nIndex
])
151 SysBrushes
[nIndex
] = (HBRUSH
) ((DWORD
) CreateSolidBrush(SysColours
[nIndex
]) | 0x00800000);
154 return SysBrushes
[nIndex
];
161 DefFrameProcA( HWND hWnd
,
175 DefFrameProcW(HWND hWnd
,
186 UserGetInternalPos(HWND hWnd
)
189 lpPos
= (PINTERNALPOS
)GetPropA(hWnd
, (LPSTR
)(DWORD
)AtomInternalPos
);
194 UserHasAnyFrameStyle(ULONG Style
, ULONG ExStyle
)
196 return ((Style
& (WS_THICKFRAME
| WS_DLGFRAME
| WS_BORDER
)) ||
197 (ExStyle
& WS_EX_DLGMODALFRAME
) ||
198 (!(Style
& (WS_CHILD
| WS_POPUP
))));
202 UserHasDlgFrameStyle(ULONG Style
, ULONG ExStyle
)
204 return ((ExStyle
& WS_EX_DLGMODALFRAME
) ||
205 ((Style
& WS_DLGFRAME
) && (!(Style
& WS_THICKFRAME
))));
209 UserHasThickFrameStyle(ULONG Style
, ULONG ExStyle
)
211 return ((Style
& WS_THICKFRAME
) &&
212 (!((Style
& (WS_DLGFRAME
| WS_BORDER
)) == WS_DLGFRAME
)));
216 UserHasThinFrameStyle(ULONG Style
, ULONG ExStyle
)
218 return ((Style
& WS_BORDER
) || (!(Style
& (WS_CHILD
| WS_POPUP
))));
222 UserHasBigFrameStyle(ULONG Style
, ULONG ExStyle
)
224 return ((Style
& (WS_THICKFRAME
| WS_DLGFRAME
)) ||
225 (ExStyle
& WS_EX_DLGMODALFRAME
));
229 UserGetInsideRectNC(HWND hWnd
, RECT
*rect
)
235 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
236 ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
237 GetWindowRect(hWnd
, &WindowRect
);
238 rect
->top
= rect
->left
= 0;
239 rect
->right
= WindowRect
.right
- WindowRect
.left
;
240 rect
->bottom
= WindowRect
.bottom
- WindowRect
.top
;
242 if (Style
& WS_ICONIC
)
247 /* Remove frame from rectangle */
248 if (UserHasThickFrameStyle(Style
, ExStyle
))
250 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
251 -GetSystemMetrics(SM_CYFRAME
));
255 if (UserHasDlgFrameStyle(Style
, ExStyle
))
257 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
258 -GetSystemMetrics(SM_CYDLGFRAME
));
259 /* FIXME: this isn't in NC_AdjustRect? why not? */
260 if (ExStyle
& WS_EX_DLGMODALFRAME
)
261 InflateRect( rect
, -1, 0 );
265 if (UserHasThinFrameStyle(Style
, ExStyle
))
267 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
268 -GetSystemMetrics(SM_CYBORDER
));
276 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
283 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
285 /* Not for child windows. */
286 if (hWnd
!= (HWND
)wParam
)
291 switch(LOWORD(lParam
))
295 WORD Msg
= HIWORD(lParam
);
296 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
297 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
306 HICON hCursor
= (HICON
)GetClassLongW(hWnd
, GCL_HCURSOR
);
318 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
324 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
330 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
336 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
339 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
343 DefWndStartSizeMove(HWND hWnd
, WPARAM wParam
, POINT
*capturePoint
)
349 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
351 GetWindowRect(hWnd
, &rectWindow
);
353 if ((wParam
& 0xfff0) == SC_MOVE
)
355 /* Move pointer at the center of the caption */
357 UserGetInsideRectNC(hWnd
, &rect
);
358 if (Style
& WS_SYSMENU
)
359 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
360 if (Style
& WS_MINIMIZEBOX
)
361 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
362 if (Style
& WS_MAXIMIZEBOX
)
363 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
364 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
365 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
373 GetMessageW(&msg
, NULL
, 0, 0);
377 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
378 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
390 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
391 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
395 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
396 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
400 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
401 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
405 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
406 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
409 case VK_ESCAPE
: return 0;
415 SetCursorPos( pt
.x
, pt
.y
);
416 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
));
420 #define ON_LEFT_BORDER(hit) \
421 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
422 #define ON_RIGHT_BORDER(hit) \
423 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
424 #define ON_TOP_BORDER(hit) \
425 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
426 #define ON_BOTTOM_BORDER(hit) \
427 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
430 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
431 ULONG width
, ULONG height
, DWORD rop
)
433 HBRUSH hbrush
= SelectObject( hdc
, GetStockObject( GRAY_BRUSH
) );
434 PatBlt( hdc
, rect
->left
, rect
->top
,
435 rect
->right
- rect
->left
- width
, height
, rop
);
436 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
437 rect
->bottom
- rect
->top
- height
, rop
);
438 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
439 rect
->right
- rect
->left
- width
, -height
, rop
);
440 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
441 rect
->bottom
- rect
->top
- height
, rop
);
442 SelectObject( hdc
, hbrush
);
446 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
450 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
),
451 GetSystemMetrics(SM_CYFRAME
), PATINVERT
);
453 else DrawFocusRect( hdc
, rect
);
457 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
460 RECT sizingRect
, mouseRect
, origRect
, clipRect
;
462 LONG hittest
= (LONG
)(wParam
& 0x0f);
463 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
464 POINT minTrack
, maxTrack
;
465 POINT capturePoint
, pt
;
466 ULONG Style
= GetWindowLongW(hwnd
, GWL_STYLE
);
467 ULONG ExStyle
= GetWindowLongW(hwnd
, GWL_EXSTYLE
);
468 BOOL thickframe
= UserHasThickFrameStyle(Style
, ExStyle
);
469 BOOL iconic
= Style
& WS_MINIMIZE
;
471 DWORD dwPoint
= GetMessagePos();
472 BOOL DragFullWindows
= FALSE
;
475 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
477 pt
.x
= SLOWORD(dwPoint
);
478 pt
.y
= SHIWORD(dwPoint
);
481 if (IsZoomed(hwnd
) || !IsWindowVisible(hwnd
))
486 if ((wParam
& 0xfff0) == SC_MOVE
)
490 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
503 if (hittest
&& hittest
!= HTSYSMENU
)
510 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
519 if (Style
& WS_CHILD
)
521 hWndParent
= GetParent(hwnd
);
524 /* Get min/max info */
526 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
527 GetWindowRect(hwnd
, &sizingRect
);
528 if (Style
& WS_CHILD
)
530 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
531 GetClientRect(hWndParent
, &mouseRect
);
532 clipRect
= mouseRect
;
533 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
537 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
),
538 GetSystemMetrics(SM_CYSCREEN
));
539 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
541 ClipCursor(&clipRect
);
543 origRect
= sizingRect
;
544 if (ON_LEFT_BORDER(hittest
))
546 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
547 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
549 else if (ON_RIGHT_BORDER(hittest
))
551 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
552 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
554 if (ON_TOP_BORDER(hittest
))
556 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
557 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
559 else if (ON_BOTTOM_BORDER(hittest
))
561 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
562 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
564 if (Style
& WS_CHILD
)
566 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
568 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
570 if (GetCapture() != hwnd
) SetCapture( hwnd
);
572 if (Style
& WS_CHILD
)
574 /* Retrieve a default cache DC (without using the window style) */
575 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
582 if( iconic
) /* create a cursor for dragging */
584 HICON hIcon
= (HICON
)GetClassLongW(hwnd
, GCL_HICON
);
585 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
586 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
587 if( !hDragCursor
) iconic
= FALSE
;
590 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
591 if( !iconic
&& !DragFullWindows
)
593 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
600 GetMessageW(&msg
, 0, 0, 0);
602 /* Exit on button-up, Return, or Esc */
603 if ((msg
.message
== WM_LBUTTONUP
) ||
604 ((msg
.message
== WM_KEYDOWN
) &&
605 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
607 if (msg
.message
== WM_PAINT
)
609 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
610 UpdateWindow( msg
.hwnd
);
611 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
615 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
616 continue; /* We are not interested in other messages */
620 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
622 case VK_UP
: pt
.y
-= 8; break;
623 case VK_DOWN
: pt
.y
+= 8; break;
624 case VK_LEFT
: pt
.x
-= 8; break;
625 case VK_RIGHT
: pt
.x
+= 8; break;
628 pt
.x
= max( pt
.x
, mouseRect
.left
);
629 pt
.x
= min( pt
.x
, mouseRect
.right
);
630 pt
.y
= max( pt
.y
, mouseRect
.top
);
631 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
633 dx
= pt
.x
- capturePoint
.x
;
634 dy
= pt
.y
- capturePoint
.y
;
642 if( iconic
) /* ok, no system popup tracking */
644 hOldCursor
= SetCursor(hDragCursor
);
646 WinPosShowIconTitle( hwnd
, FALSE
);
650 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
653 RECT newRect
= sizingRect
;
654 WPARAM wpSizingHit
= 0;
656 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
657 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
658 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
659 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
660 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
661 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
664 /* determine the hit location */
665 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
666 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
667 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
672 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
674 /* To avoid any deadlocks, all the locks on the windows
675 structures must be suspended before the SetWindowPos */
676 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
677 newRect
.right
- newRect
.left
,
678 newRect
.bottom
- newRect
.top
,
679 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
682 sizingRect
= newRect
;
691 if( moved
) /* restore cursors, show icon title later on */
694 SetCursor( hOldCursor
);
696 DestroyCursor( hDragCursor
);
698 else if(!DragFullWindows
)
699 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
701 if (Style
& WS_CHILD
)
702 ReleaseDC( hWndParent
, hdc
);
706 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
707 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
709 /* window moved or resized */
712 /* if the moving/resizing isn't canceled call SetWindowPos
713 * with the new position or the new size of the window
715 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
717 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
719 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
720 sizingRect
.right
- sizingRect
.left
,
721 sizingRect
.bottom
- sizingRect
.top
,
722 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
724 else { /* restore previous size/position */
726 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
727 origRect
.right
- origRect
.left
,
728 origRect
.bottom
- origRect
.top
,
729 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
734 if( Style
& WS_MINIMIZE
)
736 /* Single click brings up the system menu when iconized */
740 if( Style
& WS_SYSMENU
)
741 SendMessageA( hwnd
, WM_SYSCOMMAND
,
742 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
744 else WinPosShowIconTitle( hwnd
, TRUE
);
750 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, POINT Pt
)
752 switch (wParam
& 0xfff0)
756 DefWndDoSizeMove(hWnd
, wParam
);
759 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
762 MenuTrackMouseMenuBar(hWnd
, wParam
, Pt
);
765 MenuTrackKbdMenuBar(hWnd
, wParam
, Pt
.x
);
768 /* FIXME: Implement */
777 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
779 POINT maxSize
, minTrack
;
780 LONG style
= GetWindowLongA(hWnd
, GWL_STYLE
);
782 if (Pos
->flags
& SWP_NOSIZE
) return 0;
783 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
785 WinPosGetMinMaxInfo(hWnd
, &maxSize
, NULL
, &minTrack
, NULL
);
786 Pos
->cx
= min(Pos
->cx
, maxSize
.x
);
787 Pos
->cy
= min(Pos
->cy
, maxSize
.y
);
788 if (!(style
& WS_MINIMIZE
))
790 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
791 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
797 /* Undocumented flags. */
798 #define SWP_NOCLIENTMOVE 0x0800
799 #define SWP_NOCLIENTSIZE 0x1000
802 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
806 GetClientRect(hWnd
, &Rect
);
807 MapWindowPoints(hWnd
, (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
?
808 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
810 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
812 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
815 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
817 WPARAM wp
= SIZE_RESTORED
;
822 else if (IsIconic(hWnd
))
826 SendMessageW(hWnd
, WM_SIZE
, wp
,
827 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
833 /***********************************************************************
836 * Default colors for control painting.
839 DefWndControlColor(HDC hDC
, UINT ctlType
)
841 if (CTLCOLOR_SCROLLBAR
== ctlType
)
843 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
844 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
845 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
848 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
849 * we better use 0x55aa bitmap brush to make scrollbar's background
850 * look different from the window background.
852 if (bk
== GetSysColor(COLOR_WINDOW
))
855 return CACHE_GetPattern55AABrush();
864 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
866 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
868 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
872 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
873 return GetSysColorBrush(COLOR_3DFACE
);
876 return GetSysColorBrush(COLOR_WINDOW
);
881 User32DefWindowProc(HWND hWnd
,
891 return DefWndNCPaint(hWnd
, (HRGN
)wParam
);
896 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
901 return DefWndNCActivate(hWnd
, wParam
);
907 Point
.x
= SLOWORD(lParam
);
908 Point
.y
= SHIWORD(lParam
);
909 return (DefWndNCHitTest(hWnd
, Point
));
912 case WM_NCLBUTTONDOWN
:
914 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
919 return (DefWndNCLButtonUp(hWnd
, wParam
, lParam
));
922 case WM_LBUTTONDBLCLK
:
923 case WM_NCLBUTTONDBLCLK
:
925 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
928 case WM_NCRBUTTONDOWN
:
930 if (wParam
== HTCAPTION
)
937 case WM_WINDOWPOSCHANGING
:
939 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
942 case WM_WINDOWPOSCHANGED
:
944 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
950 if (hWnd
== GetCapture())
954 Pt
.x
= SLOWORD(lParam
);
955 Pt
.y
= SHIWORD(lParam
);
956 ClientToScreen(hWnd
, &Pt
);
957 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
960 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
964 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
971 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
975 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
979 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
987 Pt
.x
= SLOWORD(lParam
);
988 Pt
.y
= SHIWORD(lParam
);
989 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
991 ScreenToClient(GetParent(hWnd
), &Pt
);
994 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
996 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
998 TrackPopupMenu(GetSystemMenu(hWnd
, FALSE
),
999 TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1000 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1008 /* FIXME: Implement. */
1016 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1020 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1021 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1025 GetClientRect(hWnd
, &ClientRect
);
1026 x
= (ClientRect
.right
- ClientRect
.left
-
1027 GetSystemMetrics(SM_CXICON
)) / 2;
1028 y
= (ClientRect
.bottom
- ClientRect
.top
-
1029 GetSystemMetrics(SM_CYICON
)) / 2;
1030 DrawIcon(hDC
, x
, y
, hIcon
);
1032 EndPaint(hWnd
, &Ps
);
1040 hRgn
= CreateRectRgn(0, 0, 0, 0);
1041 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1043 RedrawWindow(hWnd
, NULL
, hRgn
,
1044 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1053 DefWndSetRedraw(hWnd
, wParam
);
1059 DestroyWindow(hWnd
);
1063 case WM_MOUSEACTIVATE
:
1065 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1070 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1075 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1083 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1088 /* Check if the window is minimized. */
1089 if (LOWORD(lParam
) != WA_INACTIVE
&&
1090 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1099 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1103 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1108 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1116 case WM_ICONERASEBKGND
:
1119 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1125 if (GetClassLongW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1127 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1128 GetClientRect(hWnd
, &Rect
);
1129 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1133 GetClipBox((HDC
)wParam
, &Rect
);
1135 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1139 case WM_CTLCOLORMSGBOX
:
1140 case WM_CTLCOLOREDIT
:
1141 case WM_CTLCOLORLISTBOX
:
1142 case WM_CTLCOLORBTN
:
1143 case WM_CTLCOLORDLG
:
1144 case WM_CTLCOLORSTATIC
:
1145 case WM_CTLCOLORSCROLLBAR
:
1146 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1150 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1152 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1157 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1162 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1171 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
));
1177 Pt
.x
= SLOWORD(lParam
);
1178 Pt
.y
= SHIWORD(lParam
);
1179 return (DefWndHandleSysCommand(hWnd
, wParam
, Pt
));
1182 /* FIXME: Handle key messages. */
1190 /* FIXME: This is also incomplete. */
1193 if (HIWORD(lParam
) & KEYDATA_ALT
)
1195 if (wParam
== VK_F4
) /* Try to close the window */
1197 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1198 if (!(GetClassLongW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1201 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1203 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1216 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1217 if (!(Style
& WS_POPUP
))
1219 if ((Style
& WS_VISIBLE
) && wParam
)
1221 if (!(Style
& WS_VISIBLE
) && !wParam
)
1223 if (!GetWindow(hWnd
, GW_OWNER
))
1225 ShowWindow(hWnd
, wParam
? SW_SHOWNA
: SW_HIDE
);
1231 /* FIXME: Check for a desktop. */
1232 if (GetCapture() == hWnd
)
1244 /* FIXME: Implement this. */
1247 case WM_QUERYDROPOBJECT
:
1249 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1256 case WM_QUERYDRAGICON
:
1261 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1264 return ((LRESULT
)hIcon
);
1266 for (Len
= 1; Len
< 64; Len
++)
1268 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1270 return((LRESULT
)hIcon
);
1273 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1276 /* FIXME: WM_ISACTIVEICON */
1278 case WM_NOTIFYFORMAT
:
1280 if (IsWindowUnicode(hWnd
))
1282 return(NFR_UNICODE
);
1292 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1293 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1294 SetClassLongW(hWnd
, Index
, lParam
);
1295 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1296 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1297 SWP_NOACTIVATE
| SWP_NOZORDER
);
1298 return ((LRESULT
)hOldIcon
);
1303 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1304 return (GetClassLongW(hWnd
, Index
));
1311 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1315 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1322 THRDCARETINFO CaretInfo
;
1325 case 0xffff: /* Caret timer */
1326 /* switch showing byte in win32k and get information about the caret */
1327 if(NtUserCallOneParam((DWORD
)&CaretInfo
, ONEPARAM_ROUTINE_SWITCHCARETSHOWING
) && (CaretInfo
.hWnd
== hWnd
))
1329 DrawCaret(hWnd
, &CaretInfo
);
1337 case WM_QUERYENDSESSION
:
1347 DefWindowProcA(HWND hWnd
,
1352 static LPSTR WindowTextAtom
= 0;
1359 CREATESTRUCTA
*Cs
= (CREATESTRUCTA
*)lParam
;
1360 if (HIWORD(Cs
->lpszName
))
1362 if (0 == WindowTextAtom
)
1365 (LPSTR
)(ULONG
)GlobalAddAtomA("USER32!WindowTextAtomA");
1367 WindowText
= RtlAllocateHeap(RtlGetProcessHeap(), 0,
1368 (strlen(Cs
->lpszName
) + 1) * sizeof(CHAR
));
1369 strcpy(WindowText
, Cs
->lpszName
);
1370 SetPropA(hWnd
, WindowTextAtom
, WindowText
);
1375 case WM_GETTEXTLENGTH
:
1377 if (WindowTextAtom
== 0 ||
1378 (WindowText
= GetPropA(hWnd
, WindowTextAtom
)) == NULL
)
1382 return (strlen(WindowText
));
1387 if (WindowTextAtom
== 0 ||
1388 (WindowText
= GetPropA(hWnd
, WindowTextAtom
)) == NULL
)
1392 *((PSTR
)lParam
) = '\0';
1396 strncpy((LPSTR
)lParam
, WindowText
, wParam
);
1397 return (min(wParam
, strlen(WindowText
)));
1402 if (0 == WindowTextAtom
)
1405 (LPSTR
)(DWORD
)GlobalAddAtomA("USER32!WindowTextAtomA");
1407 if (WindowTextAtom
!= 0 &&
1408 (WindowText
= GetPropA(hWnd
, WindowTextAtom
)) == NULL
)
1410 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText
);
1412 WindowText
= RtlAllocateHeap(RtlGetProcessHeap(), 0,
1413 (strlen((PSTR
)lParam
) + 1) * sizeof(CHAR
));
1414 strcpy(WindowText
, (PSTR
)lParam
);
1415 SetPropA(hWnd
, WindowTextAtom
, WindowText
);
1416 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1418 DefWndNCPaint(hWnd
, (HRGN
)1);
1424 FIXME: Implement these.
1426 case WM_IME_KEYDOWN:
1428 case WM_IME_STARTCOMPOSITION:
1429 case WM_IME_COMPOSITION:
1430 case WM_IME_ENDCOMPOSITION:
1432 case WM_IME_SETCONTEXT:
1437 if (WindowTextAtom
!= 0 &&
1438 (WindowText
= RemovePropA(hWnd
, WindowTextAtom
)) == NULL
)
1440 RtlFreeHeap(GetProcessHeap(), 0, WindowText
);
1446 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
1451 DefWindowProcW(HWND hWnd
,
1456 static LPWSTR WindowTextAtom
= 0;
1463 CREATESTRUCTW
* CreateStruct
= (CREATESTRUCTW
*)lParam
;
1464 if (HIWORD(CreateStruct
->lpszName
))
1466 if (0 == WindowTextAtom
)
1469 (LPWSTR
)(DWORD
)GlobalAddAtomW(L
"USER32!WindowTextAtomW");
1471 WindowText
= RtlAllocateHeap(RtlGetProcessHeap(), 0,
1472 (wcslen(CreateStruct
->lpszName
) + 1) * sizeof(WCHAR
));
1473 wcscpy(WindowText
, CreateStruct
->lpszName
);
1474 SetPropW(hWnd
, WindowTextAtom
, WindowText
);
1479 case WM_GETTEXTLENGTH
:
1481 if (WindowTextAtom
== 0 ||
1482 (WindowText
= GetPropW(hWnd
, WindowTextAtom
)) == NULL
)
1486 return (wcslen(WindowText
));
1491 if (WindowTextAtom
== 0 ||
1492 (WindowText
= GetPropW(hWnd
, WindowTextAtom
)) == NULL
)
1496 ((PWSTR
)lParam
) = '\0';
1500 wcsncpy((PWSTR
)lParam
, WindowText
, wParam
);
1501 return (min(wParam
, wcslen(WindowText
)));
1506 if (WindowTextAtom
== 0)
1509 (LPWSTR
)(DWORD
)GlobalAddAtomW(L
"USER32!WindowTextAtomW");
1511 if (WindowTextAtom
!= 0 &&
1512 (WindowText
= GetPropW(hWnd
, WindowTextAtom
)) == NULL
)
1514 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText
);
1516 WindowText
= RtlAllocateHeap(RtlGetProcessHeap(), 0,
1517 (wcslen((PWSTR
)lParam
) + 1) * sizeof(WCHAR
));
1518 wcscpy(WindowText
, (PWSTR
)lParam
);
1519 SetPropW(hWnd
, WindowTextAtom
, WindowText
);
1520 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1522 DefWndNCPaint(hWnd
, (HRGN
)1);
1529 SendMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
1533 case WM_IME_SETCONTEXT
:
1541 if (WindowTextAtom
!= 0 &&
1542 (WindowText
= RemovePropW(hWnd
, WindowTextAtom
)) == NULL
)
1544 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText
);
1550 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);