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>
28 #define WM_SETVISIBLE 9
30 #ifndef WM_QUERYDROPOBJECT
31 #define WM_QUERYDROPOBJECT 0x022B
34 LRESULT
DefWndNCPaint(HWND hWnd
, HRGN hRgn
, BOOL Active
);
35 LRESULT
DefWndNCCalcSize(HWND hWnd
, BOOL CalcSizeStruct
, RECT
*Rect
);
36 LRESULT
DefWndNCActivate(HWND hWnd
, WPARAM wParam
);
37 LRESULT
DefWndNCHitTest(HWND hWnd
, POINT Point
);
38 LRESULT
DefWndNCLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
39 LRESULT
DefWndNCLButtonDblClk(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
40 void FASTCALL
MenuInitSysMenuPopup(HMENU Menu
, DWORD Style
, DWORD ClsStyle
, LONG HitTest
);
42 /* GLOBALS *******************************************************************/
44 COLORREF SysColors
[NUM_SYSCOLORS
] = {0};
45 HPEN SysPens
[NUM_SYSCOLORS
] = {0};
46 HBRUSH SysBrushes
[NUM_SYSCOLORS
] = {0};
48 /* Bits in the dwKeyData */
49 #define KEYDATA_ALT 0x2000
51 /* FUNCTIONS *****************************************************************/
54 InitStockObjects(void)
56 /* FIXME - Instead of copying the stuff to usermode we should map the tables to
57 userland. The current implementation has one big flaw: the system color
58 table doesn't get updated when another process changes them. That's why
59 we should rather map the table into usermode. But it only affects the
60 SysColors table - the pens, brushes and stock objects are not affected
61 as their handles never change. But it'd be faster to map them, too. */
62 if(SysBrushes
[0] == NULL
)
64 /* only initialize once */
65 NtUserGetSysColors(SysColors
, NUM_SYSCOLORS
);
66 NtUserGetSysColorPens(SysPens
, NUM_SYSCOLORS
);
67 NtUserGetSysColorBrushes(SysBrushes
, NUM_SYSCOLORS
);
75 GetSysColor(int nIndex
)
77 if(nIndex
>= 0 && nIndex
<= NUM_SYSCOLORS
)
79 return SysColors
[nIndex
];
82 SetLastError(ERROR_INVALID_PARAMETER
);
90 GetSysColorPen(int nIndex
)
92 if(nIndex
>= 0 && nIndex
<= NUM_SYSCOLORS
)
94 return SysPens
[nIndex
];
97 SetLastError(ERROR_INVALID_PARAMETER
);
105 GetSysColorBrush(int nIndex
)
107 if(nIndex
>= 0 && nIndex
<= NUM_SYSCOLORS
)
109 return SysBrushes
[nIndex
];
112 SetLastError(ERROR_INVALID_PARAMETER
);
123 CONST INT
*lpaElements
,
124 CONST COLORREF
*lpaRgbValues
)
133 ChangeSysColors
.Elements
= (INT
*)lpaElements
;
134 ChangeSysColors
.Colors
= (COLORREF
*)lpaRgbValues
;
138 Ret
= NtUserSetSysColors(&ChangeSysColors
, cElements
);
141 /* FIXME - just change it in the usermode structure, too, instead of asking win32k again */
142 NtUserGetSysColors(SysColors
, NUM_SYSCOLORS
);
147 SetLastError(ERROR_INVALID_PARAMETER
);
155 UserGetInsideRectNC(HWND hWnd
, RECT
*rect
)
161 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
162 ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
163 GetWindowRect(hWnd
, &WindowRect
);
164 rect
->top
= rect
->left
= 0;
165 rect
->right
= WindowRect
.right
- WindowRect
.left
;
166 rect
->bottom
= WindowRect
.bottom
- WindowRect
.top
;
168 if (Style
& WS_ICONIC
)
173 /* Remove frame from rectangle */
174 if (UserHasThickFrameStyle(Style
, ExStyle
))
176 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
177 -GetSystemMetrics(SM_CYFRAME
));
181 if (UserHasDlgFrameStyle(Style
, ExStyle
))
183 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
184 -GetSystemMetrics(SM_CYDLGFRAME
));
185 /* FIXME: this isn't in NC_AdjustRect? why not? */
186 if (ExStyle
& WS_EX_DLGMODALFRAME
)
187 InflateRect( rect
, -1, 0 );
191 if (UserHasThinFrameStyle(Style
, ExStyle
))
193 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
194 -GetSystemMetrics(SM_CYBORDER
));
202 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
204 if ((BOOL
) wParam
&& 0 == (GetWindowLong(hWnd
, GWL_STYLE
) & WS_VISIBLE
))
206 ShowWindow(hWnd
, SW_NORMAL
);
214 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
216 /* Not for child windows. */
217 if (hWnd
!= (HWND
)wParam
)
222 switch((INT_PTR
) LOWORD(lParam
))
226 WORD Msg
= HIWORD(lParam
);
227 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
228 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
237 HICON hCursor
= (HICON
)GetClassLongW(hWnd
, GCL_HCURSOR
);
249 if (Style
& WS_MAXIMIZE
)
253 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
259 if (Style
& WS_MAXIMIZE
)
263 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
269 if (Style
& WS_MAXIMIZE
)
273 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
279 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
283 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
286 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
290 DefWndStartSizeMove(HWND hWnd
, WPARAM wParam
, POINT
*capturePoint
)
296 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
298 GetWindowRect(hWnd
, &rectWindow
);
300 if ((wParam
& 0xfff0) == SC_MOVE
)
302 /* Move pointer at the center of the caption */
304 UserGetInsideRectNC(hWnd
, &rect
);
305 if (Style
& WS_SYSMENU
)
306 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
307 if (Style
& WS_MINIMIZEBOX
)
308 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
309 if (Style
& WS_MAXIMIZEBOX
)
310 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
311 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
312 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
320 if (GetMessageW(&msg
, NULL
, 0, 0) <= 0)
325 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
326 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
338 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
339 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
343 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
344 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
348 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
349 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
353 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
354 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
357 case VK_ESCAPE
: return 0;
363 SetCursorPos( pt
.x
, pt
.y
);
364 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
368 #define ON_LEFT_BORDER(hit) \
369 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
370 #define ON_RIGHT_BORDER(hit) \
371 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
372 #define ON_TOP_BORDER(hit) \
373 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
374 #define ON_BOTTOM_BORDER(hit) \
375 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
378 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
379 ULONG width
, ULONG height
)
381 static HBRUSH hDraggingRectBrush
= NULL
;
383 if(!hDraggingRectBrush
)
385 static HBITMAP hDraggingPattern
= NULL
;
386 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
388 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
389 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
392 HBRUSH hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
393 PatBlt( hdc
, rect
->left
, rect
->top
,
394 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
395 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
396 rect
->bottom
- rect
->top
- height
, PATINVERT
);
397 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
398 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
399 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
400 rect
->bottom
- rect
->top
- height
, PATINVERT
);
401 SelectObject( hdc
, hbrush
);
405 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
409 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
));
413 UserDrawWindowFrame(hdc
, rect
, 1, 1);
418 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
422 RECT sizingRect
, mouseRect
, origRect
, clipRect
, unmodRect
;
424 LONG hittest
= (LONG
)(wParam
& 0x0f);
425 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
426 POINT minTrack
, maxTrack
;
427 POINT capturePoint
, pt
;
428 ULONG Style
= GetWindowLongW(hwnd
, GWL_STYLE
);
429 ULONG ExStyle
= GetWindowLongW(hwnd
, GWL_EXSTYLE
);
431 BOOL iconic
= Style
& WS_MINIMIZE
;
433 DWORD dwPoint
= GetMessagePos();
434 BOOL DragFullWindows
= FALSE
;
435 HWND hWndParent
= NULL
;
437 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
439 pt
.x
= GET_X_LPARAM(dwPoint
);
440 pt
.y
= GET_Y_LPARAM(dwPoint
);
443 if (IsZoomed(hwnd
) || !IsWindowVisible(hwnd
))
448 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
449 if ((wParam
& 0xfff0) == SC_MOVE
)
453 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
466 if (hittest
&& ((wParam
& 0xfff0) != SC_MOUSEMENU
))
468 hittest
+= (HTLEFT
- WMSZ_LEFT
);
473 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
482 /* Get min/max info */
484 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
485 GetWindowRect(hwnd
, &sizingRect
);
486 if (Style
& WS_CHILD
)
488 hWndParent
= GetParent(hwnd
);
489 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
490 unmodRect
= sizingRect
;
491 GetClientRect(hWndParent
, &mouseRect
);
492 clipRect
= mouseRect
;
493 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
497 if(!(ExStyle
& WS_EX_TOPMOST
))
499 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
500 mouseRect
= clipRect
;
504 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
505 clipRect
= mouseRect
;
507 unmodRect
= sizingRect
;
509 ClipCursor(&clipRect
);
511 origRect
= sizingRect
;
512 if (ON_LEFT_BORDER(hittest
))
514 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
515 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
517 else if (ON_RIGHT_BORDER(hittest
))
519 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
520 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
522 if (ON_TOP_BORDER(hittest
))
524 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
525 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
527 else if (ON_BOTTOM_BORDER(hittest
))
529 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
530 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
532 if (Style
& WS_CHILD
)
534 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
537 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
538 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
539 if (GetCapture() != hwnd
) SetCapture( hwnd
);
541 if (Style
& WS_CHILD
)
543 /* Retrieve a default cache DC (without using the window style) */
544 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
550 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
553 SelectObject(hdc
, DesktopRgn
);
555 if( iconic
) /* create a cursor for dragging */
557 HICON hIcon
= (HICON
)GetClassLongW(hwnd
, GCL_HICON
);
558 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
559 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
560 if( !hDragCursor
) iconic
= FALSE
;
563 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
564 if( !iconic
&& !DragFullWindows
)
566 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
573 if (GetMessageW(&msg
, 0, 0, 0) <= 0)
576 /* Exit on button-up, Return, or Esc */
577 if ((msg
.message
== WM_LBUTTONUP
) ||
578 ((msg
.message
== WM_KEYDOWN
) &&
579 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
581 if (msg
.message
== WM_PAINT
)
583 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
584 UpdateWindow( msg
.hwnd
);
585 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
589 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
590 continue; /* We are not interested in other messages */
594 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
596 case VK_UP
: pt
.y
-= 8; break;
597 case VK_DOWN
: pt
.y
+= 8; break;
598 case VK_LEFT
: pt
.x
-= 8; break;
599 case VK_RIGHT
: pt
.x
+= 8; break;
602 pt
.x
= max( pt
.x
, mouseRect
.left
);
603 pt
.x
= min( pt
.x
, mouseRect
.right
);
604 pt
.y
= max( pt
.y
, mouseRect
.top
);
605 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
607 dx
= pt
.x
- capturePoint
.x
;
608 dy
= pt
.y
- capturePoint
.y
;
616 if( iconic
) /* ok, no system popup tracking */
618 hOldCursor
= SetCursor(hDragCursor
);
623 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
626 RECT newRect
= unmodRect
;
627 WPARAM wpSizingHit
= 0;
629 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
630 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
631 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
632 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
633 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
634 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
637 /* determine the hit location */
638 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
639 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
641 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
646 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
648 /* To avoid any deadlocks, all the locks on the windows
649 structures must be suspended before the SetWindowPos */
650 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
651 newRect
.right
- newRect
.left
,
652 newRect
.bottom
- newRect
.top
,
653 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
656 sizingRect
= newRect
;
665 if( moved
) /* restore cursors, show icon title later on */
668 SetCursor( hOldCursor
);
670 DestroyCursor( hDragCursor
);
672 else if(!DragFullWindows
)
673 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
675 if (Style
& WS_CHILD
)
676 ReleaseDC( hWndParent
, hdc
);
682 DeleteObject(DesktopRgn
);
685 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
686 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
687 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
689 /* window moved or resized */
692 /* if the moving/resizing isn't canceled call SetWindowPos
693 * with the new position or the new size of the window
695 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
697 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
699 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
700 sizingRect
.right
- sizingRect
.left
,
701 sizingRect
.bottom
- sizingRect
.top
,
702 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
704 else { /* restore previous size/position */
706 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
707 origRect
.right
- origRect
.left
,
708 origRect
.bottom
- origRect
.top
,
709 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
714 if( Style
& WS_MINIMIZE
)
716 /* Single click brings up the system menu when iconized */
720 if( Style
& WS_SYSMENU
)
721 SendMessageA( hwnd
, WM_SYSCOMMAND
,
722 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
728 /***********************************************************************
729 * DefWndTrackScrollBar
731 * Track a mouse button press on the horizontal or vertical scroll-bar.
734 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
738 if (SC_HSCROLL
== (wParam
& 0xfff0))
740 if (HTHSCROLL
!= (wParam
& 0x0f))
746 else /* SC_VSCROLL */
748 if (HTVSCROLL
!= (wParam
& 0x0f))
754 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
759 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, POINT Pt
)
763 switch (wParam
& 0xfff0)
767 DefWndDoSizeMove(hWnd
, wParam
);
770 wp
.length
= sizeof(WINDOWPLACEMENT
);
771 if(GetWindowPlacement(hWnd
, &wp
))
773 wp
.showCmd
= SW_MINIMIZE
;
774 SetWindowPlacement(hWnd
, &wp
);
778 wp
.length
= sizeof(WINDOWPLACEMENT
);
779 if(GetWindowPlacement(hWnd
, &wp
))
781 wp
.showCmd
= SW_MAXIMIZE
;
782 SetWindowPlacement(hWnd
, &wp
);
786 wp
.length
= sizeof(WINDOWPLACEMENT
);
787 if(GetWindowPlacement(hWnd
, &wp
))
789 wp
.showCmd
= SW_RESTORE
;
790 SetWindowPlacement(hWnd
, &wp
);
794 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
797 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
800 MenuTrackKbdMenuBar(hWnd
, wParam
, Pt
.x
);
804 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
808 /* FIXME: Implement */
817 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
819 POINT maxSize
, minTrack
;
820 LONG style
= GetWindowLongA(hWnd
, GWL_STYLE
);
822 if (Pos
->flags
& SWP_NOSIZE
) return 0;
823 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
825 WinPosGetMinMaxInfo(hWnd
, &maxSize
, NULL
, &minTrack
, NULL
);
826 Pos
->cx
= min(Pos
->cx
, maxSize
.x
);
827 Pos
->cy
= min(Pos
->cy
, maxSize
.y
);
828 if (!(style
& WS_MINIMIZE
))
830 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
831 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
836 Pos
->cx
= max(Pos
->cx
, 0);
837 Pos
->cy
= max(Pos
->cy
, 0);
842 /* Undocumented flags. */
843 #define SWP_NOCLIENTMOVE 0x0800
844 #define SWP_NOCLIENTSIZE 0x1000
847 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
851 GetClientRect(hWnd
, &Rect
);
852 MapWindowPoints(hWnd
, (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
?
853 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
855 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
857 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
860 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
862 WPARAM wp
= SIZE_RESTORED
;
867 else if (IsIconic(hWnd
))
871 SendMessageW(hWnd
, WM_SIZE
, wp
,
872 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
878 /***********************************************************************
881 * Default colors for control painting.
884 DefWndControlColor(HDC hDC
, UINT ctlType
)
886 if (CTLCOLOR_SCROLLBAR
== ctlType
)
888 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
889 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
890 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
893 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
894 * we better use 0x55aa bitmap brush to make scrollbar's background
895 * look different from the window background.
897 if (bk
== GetSysColor(COLOR_WINDOW
))
899 static const WORD wPattern55AA
[] =
901 0x5555, 0xaaaa, 0x5555, 0xaaaa,
902 0x5555, 0xaaaa, 0x5555, 0xaaaa
904 static HBITMAP hPattern55AABitmap
= NULL
;
905 static HBRUSH hPattern55AABrush
= NULL
;
906 if (hPattern55AABrush
== NULL
)
908 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
909 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
911 return hPattern55AABrush
;
917 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
919 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
921 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
925 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
926 return GetSysColorBrush(COLOR_3DFACE
);
929 return GetSysColorBrush(COLOR_WINDOW
);
933 DefWndScreenshot(HWND hWnd
)
939 User32DefWindowProc(HWND hWnd
,
949 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
954 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
959 return DefWndNCActivate(hWnd
, wParam
);
965 Point
.x
= GET_X_LPARAM(lParam
);
966 Point
.y
= GET_Y_LPARAM(lParam
);
967 return (DefWndNCHitTest(hWnd
, Point
));
970 case WM_NCLBUTTONDOWN
:
972 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
975 case WM_NCLBUTTONDBLCLK
:
977 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
980 case WM_WINDOWPOSCHANGING
:
982 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
985 case WM_WINDOWPOSCHANGED
:
987 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
993 if (hWnd
== GetCapture())
997 Pt
.x
= GET_X_LPARAM(lParam
);
998 Pt
.y
= GET_Y_LPARAM(lParam
);
999 ClientToScreen(hWnd
, &Pt
);
1000 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1003 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1007 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1012 case WM_CONTEXTMENU
:
1014 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1018 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1022 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1031 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1033 Pt
.x
= GET_X_LPARAM(lParam
);
1034 Pt
.y
= GET_Y_LPARAM(lParam
);
1035 if (Style
& WS_CHILD
)
1037 ScreenToClient(GetParent(hWnd
), &Pt
);
1040 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1042 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1047 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1049 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongW(hWnd
, GWL_STYLE
),
1050 GetClassLongW(hWnd
, GCL_STYLE
), HitCode
);
1052 if(HitCode
== HTCAPTION
)
1053 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1055 Flags
= TPM_LEFTBUTTON
;
1057 TrackPopupMenu(SystemMenu
, Flags
,
1058 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1067 /* FIXME: Implement. */
1075 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1079 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1080 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1084 GetClientRect(hWnd
, &ClientRect
);
1085 x
= (ClientRect
.right
- ClientRect
.left
-
1086 GetSystemMetrics(SM_CXICON
)) / 2;
1087 y
= (ClientRect
.bottom
- ClientRect
.top
-
1088 GetSystemMetrics(SM_CYICON
)) / 2;
1089 DrawIcon(hDC
, x
, y
, hIcon
);
1091 EndPaint(hWnd
, &Ps
);
1099 hRgn
= CreateRectRgn(0, 0, 0, 0);
1100 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1102 RedrawWindow(hWnd
, NULL
, hRgn
,
1103 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1112 DefWndSetRedraw(hWnd
, wParam
);
1118 DestroyWindow(hWnd
);
1122 case WM_MOUSEACTIVATE
:
1124 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1129 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1134 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1142 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1147 /* Check if the window is minimized. */
1148 if (LOWORD(wParam
) != WA_INACTIVE
&&
1149 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1158 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1162 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1167 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1175 case WM_ICONERASEBKGND
:
1178 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1184 if (GetClassLongW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1186 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1187 GetClientRect(hWnd
, &Rect
);
1188 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1192 GetClipBox((HDC
)wParam
, &Rect
);
1194 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1198 case WM_CTLCOLORMSGBOX
:
1199 case WM_CTLCOLOREDIT
:
1200 case WM_CTLCOLORLISTBOX
:
1201 case WM_CTLCOLORBTN
:
1202 case WM_CTLCOLORDLG
:
1203 case WM_CTLCOLORSTATIC
:
1204 case WM_CTLCOLORSCROLLBAR
:
1205 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1209 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1211 if (Style
& WS_CHILD
)
1213 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1218 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1223 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1232 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1238 Pt
.x
= GET_X_LPARAM(lParam
);
1239 Pt
.y
= GET_Y_LPARAM(lParam
);
1240 return (DefWndHandleSysCommand(hWnd
, wParam
, Pt
));
1243 /* FIXME: Handle key messages. */
1251 /* FIXME: This is also incomplete. */
1254 if (HIWORD(lParam
) & KEYDATA_ALT
)
1256 if (wParam
== VK_F4
) /* Try to close the window */
1258 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1259 if (!(GetClassLongW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1262 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1264 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1267 else if (wParam
== VK_SNAPSHOT
)
1269 DefWndScreenshot(hWnd
);
1281 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1282 if (!(Style
& WS_POPUP
))
1284 if ((Style
& WS_VISIBLE
) && wParam
)
1286 if (!(Style
& WS_VISIBLE
) && !wParam
)
1288 if (!GetWindow(hWnd
, GW_OWNER
))
1290 ShowWindow(hWnd
, wParam
? SW_SHOWNA
: SW_HIDE
);
1296 /* FIXME: Check for a desktop. */
1297 if (GetCapture() == hWnd
)
1312 case WM_QUERYDROPOBJECT
:
1314 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1321 case WM_QUERYDRAGICON
:
1326 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1329 return ((LRESULT
)hIcon
);
1331 for (Len
= 1; Len
< 64; Len
++)
1333 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1335 return((LRESULT
)hIcon
);
1338 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1341 /* FIXME: WM_ISACTIVEICON */
1343 case WM_NOTIFYFORMAT
:
1345 if (IsWindowUnicode(hWnd
))
1347 return(NFR_UNICODE
);
1357 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1358 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1359 SetClassLongW(hWnd
, Index
, lParam
);
1360 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1361 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1362 SWP_NOACTIVATE
| SWP_NOZORDER
);
1363 return ((LRESULT
)hOldIcon
);
1368 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1369 return (GetClassLongW(hWnd
, Index
));
1376 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1380 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1387 THRDCARETINFO CaretInfo
;
1390 case 0xffff: /* Caret timer */
1391 /* switch showing byte in win32k and get information about the caret */
1392 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1394 DrawCaret(hWnd
, &CaretInfo
);
1402 case WM_QUERYENDSESSION
:
1412 DefWindowProcA(HWND hWnd
,
1424 case WM_GETTEXTLENGTH
:
1426 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1432 LPSTR AnsiBuffer
= (LPSTR
)lParam
;
1437 *((PWSTR
)lParam
) = '\0';
1439 Buffer
= HeapAlloc(GetProcessHeap(), 0, wParam
* sizeof(WCHAR
));
1442 Length
= NtUserInternalGetWindowText(hWnd
, Buffer
, wParam
);
1443 if (Length
> 0 && wParam
> 0 &&
1444 !WideCharToMultiByte(CP_ACP
, 0, Buffer
, -1,
1445 AnsiBuffer
, wParam
, NULL
, NULL
))
1447 AnsiBuffer
[0] = '\0';
1450 HeapFree(GetProcessHeap(), 0, Buffer
);
1452 return (LRESULT
)Length
;
1457 ANSI_STRING AnsiString
;
1458 UNICODE_STRING UnicodeString
;
1462 RtlInitAnsiString(&AnsiString
, (LPSTR
)lParam
);
1463 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
1464 NtUserDefSetText(hWnd
, &UnicodeString
);
1465 RtlFreeUnicodeString(&UnicodeString
);
1468 NtUserDefSetText(hWnd
, NULL
);
1470 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1472 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1478 FIXME: Implement these.
1480 case WM_IME_KEYDOWN:
1482 case WM_IME_STARTCOMPOSITION:
1483 case WM_IME_COMPOSITION:
1484 case WM_IME_ENDCOMPOSITION:
1486 case WM_IME_SETCONTEXT:
1490 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
1495 DefWindowProcW(HWND hWnd
,
1507 case WM_GETTEXTLENGTH
:
1509 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1516 *((PWSTR
)lParam
) = L
'\0';
1518 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, (PWSTR
)lParam
, wParam
);
1523 UNICODE_STRING UnicodeString
;
1526 RtlInitUnicodeString(&UnicodeString
, (LPWSTR
)lParam
);
1528 NtUserDefSetText(hWnd
, (lParam
? &UnicodeString
: NULL
));
1530 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1532 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1539 SendMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
1543 case WM_IME_SETCONTEXT
:
1550 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);