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 ******************************************************************/
19 #define WM_SETVISIBLE 9
21 #ifndef WM_QUERYDROPOBJECT
22 #define WM_QUERYDROPOBJECT 0x022B
25 LRESULT
DefWndNCPaint(HWND hWnd
, HRGN hRgn
, BOOL Active
);
26 LRESULT
DefWndNCCalcSize(HWND hWnd
, BOOL CalcSizeStruct
, RECT
*Rect
);
27 LRESULT
DefWndNCActivate(HWND hWnd
, WPARAM wParam
);
28 LRESULT
DefWndNCHitTest(HWND hWnd
, POINT Point
);
29 LRESULT
DefWndNCLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
30 LRESULT
DefWndNCLButtonDblClk(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
31 void FASTCALL
MenuInitSysMenuPopup(HMENU Menu
, DWORD Style
, DWORD ClsStyle
, LONG HitTest
);
33 /* GLOBALS *******************************************************************/
35 COLORREF SysColors
[NUM_SYSCOLORS
] = {0};
36 HPEN SysPens
[NUM_SYSCOLORS
] = {0};
37 HBRUSH SysBrushes
[NUM_SYSCOLORS
] = {0};
39 /* Bits in the dwKeyData */
40 #define KEYDATA_ALT 0x2000
42 /* FUNCTIONS *****************************************************************/
45 InitStockObjects(void)
47 /* FIXME - Instead of copying the stuff to usermode we should map the tables to
48 userland. The current implementation has one big flaw: the system color
49 table doesn't get updated when another process changes them. That's why
50 we should rather map the table into usermode. But it only affects the
51 SysColors table - the pens, brushes and stock objects are not affected
52 as their handles never change. But it'd be faster to map them, too. */
53 if(SysBrushes
[0] == NULL
)
55 /* only initialize once */
56 NtUserGetSysColors(SysColors
, NUM_SYSCOLORS
);
57 NtUserGetSysColorPens(SysPens
, NUM_SYSCOLORS
);
58 NtUserGetSysColorBrushes(SysBrushes
, NUM_SYSCOLORS
);
66 GetSysColor(int nIndex
)
68 if(nIndex
>= 0 && nIndex
<= NUM_SYSCOLORS
)
70 return SysColors
[nIndex
];
73 SetLastError(ERROR_INVALID_PARAMETER
);
81 GetSysColorPen(int nIndex
)
83 if(nIndex
>= 0 && nIndex
<= NUM_SYSCOLORS
)
85 return SysPens
[nIndex
];
88 SetLastError(ERROR_INVALID_PARAMETER
);
96 GetSysColorBrush(int nIndex
)
98 if(nIndex
>= 0 && nIndex
<= NUM_SYSCOLORS
)
100 return SysBrushes
[nIndex
];
103 SetLastError(ERROR_INVALID_PARAMETER
);
114 CONST INT
*lpaElements
,
115 CONST COLORREF
*lpaRgbValues
)
124 ChangeSysColors
.Elements
= (INT
*)lpaElements
;
125 ChangeSysColors
.Colors
= (COLORREF
*)lpaRgbValues
;
129 Ret
= NtUserSetSysColors(&ChangeSysColors
, cElements
);
132 /* FIXME - just change it in the usermode structure, too, instead of asking win32k again */
133 NtUserGetSysColors(SysColors
, NUM_SYSCOLORS
);
138 SetLastError(ERROR_INVALID_PARAMETER
);
146 UserGetInsideRectNC(HWND hWnd
, RECT
*rect
)
152 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
153 ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
154 GetWindowRect(hWnd
, &WindowRect
);
155 rect
->top
= rect
->left
= 0;
156 rect
->right
= WindowRect
.right
- WindowRect
.left
;
157 rect
->bottom
= WindowRect
.bottom
- WindowRect
.top
;
159 if (Style
& WS_ICONIC
)
164 /* Remove frame from rectangle */
165 if (UserHasThickFrameStyle(Style
, ExStyle
))
167 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
168 -GetSystemMetrics(SM_CYFRAME
));
172 if (UserHasDlgFrameStyle(Style
, ExStyle
))
174 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
175 -GetSystemMetrics(SM_CYDLGFRAME
));
176 /* FIXME: this isn't in NC_AdjustRect? why not? */
177 if (ExStyle
& WS_EX_DLGMODALFRAME
)
178 InflateRect( rect
, -1, 0 );
182 if (UserHasThinFrameStyle(Style
, ExStyle
))
184 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
185 -GetSystemMetrics(SM_CYBORDER
));
193 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
195 if ((BOOL
) wParam
&& 0 == (GetWindowLong(hWnd
, GWL_STYLE
) & WS_VISIBLE
))
197 ShowWindow(hWnd
, SW_NORMAL
);
205 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
207 /* Not for child windows. */
208 if (hWnd
!= (HWND
)wParam
)
213 switch((INT_PTR
) LOWORD(lParam
))
217 WORD Msg
= HIWORD(lParam
);
218 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
219 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
228 HICON hCursor
= (HICON
)GetClassLongW(hWnd
, GCL_HCURSOR
);
240 if (Style
& WS_MAXIMIZE
)
244 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
250 if (Style
& WS_MAXIMIZE
)
254 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
260 if (Style
& WS_MAXIMIZE
)
264 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
270 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
274 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
277 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
281 DefWndStartSizeMove(HWND hWnd
, WPARAM wParam
, POINT
*capturePoint
)
287 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
289 GetWindowRect(hWnd
, &rectWindow
);
291 if ((wParam
& 0xfff0) == SC_MOVE
)
293 /* Move pointer at the center of the caption */
295 UserGetInsideRectNC(hWnd
, &rect
);
296 if (Style
& WS_SYSMENU
)
297 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
298 if (Style
& WS_MINIMIZEBOX
)
299 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
300 if (Style
& WS_MAXIMIZEBOX
)
301 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
302 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
303 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
312 if (GetMessageW(&msg
, NULL
, 0, 0) <= 0)
317 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
318 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
330 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
331 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
335 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
336 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
340 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
341 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
345 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
346 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
349 case VK_ESCAPE
: return 0;
355 SetCursorPos( pt
.x
, pt
.y
);
356 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
360 #define ON_LEFT_BORDER(hit) \
361 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
362 #define ON_RIGHT_BORDER(hit) \
363 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
364 #define ON_TOP_BORDER(hit) \
365 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
366 #define ON_BOTTOM_BORDER(hit) \
367 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
370 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
371 ULONG width
, ULONG height
)
373 static HBRUSH hDraggingRectBrush
= NULL
;
376 if(!hDraggingRectBrush
)
378 static HBITMAP hDraggingPattern
= NULL
;
379 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
381 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
382 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
385 hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
386 PatBlt( hdc
, rect
->left
, rect
->top
,
387 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
388 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
389 rect
->bottom
- rect
->top
- height
, PATINVERT
);
390 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
391 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
392 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
393 rect
->bottom
- rect
->top
- height
, PATINVERT
);
394 SelectObject( hdc
, hbrush
);
398 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
402 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
));
406 UserDrawWindowFrame(hdc
, rect
, 1, 1);
411 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
415 RECT sizingRect
, mouseRect
, origRect
, clipRect
, unmodRect
;
417 LONG hittest
= (LONG
)(wParam
& 0x0f);
418 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
419 POINT minTrack
, maxTrack
;
420 POINT capturePoint
, pt
;
421 ULONG Style
= GetWindowLongW(hwnd
, GWL_STYLE
);
422 ULONG ExStyle
= GetWindowLongW(hwnd
, GWL_EXSTYLE
);
424 BOOL iconic
= Style
& WS_MINIMIZE
;
426 DWORD dwPoint
= GetMessagePos();
427 BOOL DragFullWindows
= FALSE
;
428 HWND hWndParent
= NULL
;
430 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
432 pt
.x
= GET_X_LPARAM(dwPoint
);
433 pt
.y
= GET_Y_LPARAM(dwPoint
);
436 if (IsZoomed(hwnd
) || !IsWindowVisible(hwnd
))
441 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
442 if ((wParam
& 0xfff0) == SC_MOVE
)
446 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
459 if (hittest
&& ((wParam
& 0xfff0) != SC_MOUSEMENU
))
461 hittest
+= (HTLEFT
- WMSZ_LEFT
);
466 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
475 /* Get min/max info */
477 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
478 GetWindowRect(hwnd
, &sizingRect
);
479 if (Style
& WS_CHILD
)
481 hWndParent
= GetParent(hwnd
);
482 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
483 unmodRect
= sizingRect
;
484 GetClientRect(hWndParent
, &mouseRect
);
485 clipRect
= mouseRect
;
486 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
490 if(!(ExStyle
& WS_EX_TOPMOST
))
492 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
493 mouseRect
= clipRect
;
497 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
498 clipRect
= mouseRect
;
500 unmodRect
= sizingRect
;
502 ClipCursor(&clipRect
);
504 origRect
= sizingRect
;
505 if (ON_LEFT_BORDER(hittest
))
507 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
508 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
510 else if (ON_RIGHT_BORDER(hittest
))
512 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
513 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
515 if (ON_TOP_BORDER(hittest
))
517 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
518 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
520 else if (ON_BOTTOM_BORDER(hittest
))
522 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
523 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
525 if (Style
& WS_CHILD
)
527 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
530 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
531 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
532 if (GetCapture() != hwnd
) SetCapture( hwnd
);
534 if (Style
& WS_CHILD
)
536 /* Retrieve a default cache DC (without using the window style) */
537 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
543 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
546 SelectObject(hdc
, DesktopRgn
);
548 if( iconic
) /* create a cursor for dragging */
550 HICON hIcon
= (HICON
)GetClassLongW(hwnd
, GCL_HICON
);
551 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
552 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
553 if( !hDragCursor
) iconic
= FALSE
;
556 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
557 if( !iconic
&& !DragFullWindows
)
559 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
566 if (GetMessageW(&msg
, 0, 0, 0) <= 0)
569 /* Exit on button-up, Return, or Esc */
570 if ((msg
.message
== WM_LBUTTONUP
) ||
571 ((msg
.message
== WM_KEYDOWN
) &&
572 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
574 if (msg
.message
== WM_PAINT
)
576 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
577 UpdateWindow( msg
.hwnd
);
578 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
582 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
583 continue; /* We are not interested in other messages */
587 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
589 case VK_UP
: pt
.y
-= 8; break;
590 case VK_DOWN
: pt
.y
+= 8; break;
591 case VK_LEFT
: pt
.x
-= 8; break;
592 case VK_RIGHT
: pt
.x
+= 8; break;
595 pt
.x
= max( pt
.x
, mouseRect
.left
);
596 pt
.x
= min( pt
.x
, mouseRect
.right
);
597 pt
.y
= max( pt
.y
, mouseRect
.top
);
598 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
600 dx
= pt
.x
- capturePoint
.x
;
601 dy
= pt
.y
- capturePoint
.y
;
609 if( iconic
) /* ok, no system popup tracking */
611 hOldCursor
= SetCursor(hDragCursor
);
616 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
619 RECT newRect
= unmodRect
;
620 WPARAM wpSizingHit
= 0;
622 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
623 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
624 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
625 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
626 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
627 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
630 /* determine the hit location */
631 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
632 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
634 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
639 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
641 /* To avoid any deadlocks, all the locks on the windows
642 structures must be suspended before the SetWindowPos */
643 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
644 newRect
.right
- newRect
.left
,
645 newRect
.bottom
- newRect
.top
,
646 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
649 sizingRect
= newRect
;
658 if( moved
) /* restore cursors, show icon title later on */
661 SetCursor( hOldCursor
);
663 DestroyCursor( hDragCursor
);
665 else if(!DragFullWindows
)
666 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
668 if (Style
& WS_CHILD
)
669 ReleaseDC( hWndParent
, hdc
);
675 DeleteObject(DesktopRgn
);
678 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
679 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
680 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
682 /* window moved or resized */
685 /* if the moving/resizing isn't canceled call SetWindowPos
686 * with the new position or the new size of the window
688 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
690 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
692 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
693 sizingRect
.right
- sizingRect
.left
,
694 sizingRect
.bottom
- sizingRect
.top
,
695 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
697 else { /* restore previous size/position */
699 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
700 origRect
.right
- origRect
.left
,
701 origRect
.bottom
- origRect
.top
,
702 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
707 if( Style
& WS_MINIMIZE
)
709 /* Single click brings up the system menu when iconized */
713 if( Style
& WS_SYSMENU
)
714 SendMessageA( hwnd
, WM_SYSCOMMAND
,
715 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
721 /***********************************************************************
722 * DefWndTrackScrollBar
724 * Track a mouse button press on the horizontal or vertical scroll-bar.
727 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
731 if (SC_HSCROLL
== (wParam
& 0xfff0))
733 if (HTHSCROLL
!= (wParam
& 0x0f))
739 else /* SC_VSCROLL */
741 if (HTVSCROLL
!= (wParam
& 0x0f))
747 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
752 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, POINT Pt
)
756 switch (wParam
& 0xfff0)
760 DefWndDoSizeMove(hWnd
, wParam
);
763 wp
.length
= sizeof(WINDOWPLACEMENT
);
764 if(GetWindowPlacement(hWnd
, &wp
))
766 wp
.showCmd
= SW_MINIMIZE
;
767 SetWindowPlacement(hWnd
, &wp
);
771 wp
.length
= sizeof(WINDOWPLACEMENT
);
772 if(GetWindowPlacement(hWnd
, &wp
))
774 wp
.showCmd
= SW_MAXIMIZE
;
775 SetWindowPlacement(hWnd
, &wp
);
779 wp
.length
= sizeof(WINDOWPLACEMENT
);
780 if(GetWindowPlacement(hWnd
, &wp
))
782 wp
.showCmd
= SW_RESTORE
;
783 SetWindowPlacement(hWnd
, &wp
);
787 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
790 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
793 MenuTrackKbdMenuBar(hWnd
, wParam
, Pt
.x
);
797 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
801 /* FIXME: Implement */
810 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
812 POINT maxTrack
, minTrack
;
813 LONG style
= GetWindowLongA(hWnd
, GWL_STYLE
);
815 if (Pos
->flags
& SWP_NOSIZE
) return 0;
816 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
818 WinPosGetMinMaxInfo(hWnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
819 Pos
->cx
= min(Pos
->cx
, maxTrack
.x
);
820 Pos
->cy
= min(Pos
->cy
, maxTrack
.y
);
821 if (!(style
& WS_MINIMIZE
))
823 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
824 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
829 Pos
->cx
= max(Pos
->cx
, 0);
830 Pos
->cy
= max(Pos
->cy
, 0);
835 /* Undocumented flags. */
836 #define SWP_NOCLIENTMOVE 0x0800
837 #define SWP_NOCLIENTSIZE 0x1000
840 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
844 GetClientRect(hWnd
, &Rect
);
845 MapWindowPoints(hWnd
, (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
?
846 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
848 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
850 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
853 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
855 WPARAM wp
= SIZE_RESTORED
;
860 else if (IsIconic(hWnd
))
864 SendMessageW(hWnd
, WM_SIZE
, wp
,
865 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
871 /***********************************************************************
874 * Default colors for control painting.
877 DefWndControlColor(HDC hDC
, UINT ctlType
)
879 if (CTLCOLOR_SCROLLBAR
== ctlType
)
881 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
882 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
883 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
886 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
887 * we better use 0x55aa bitmap brush to make scrollbar's background
888 * look different from the window background.
890 if (bk
== GetSysColor(COLOR_WINDOW
))
892 static const WORD wPattern55AA
[] =
894 0x5555, 0xaaaa, 0x5555, 0xaaaa,
895 0x5555, 0xaaaa, 0x5555, 0xaaaa
897 static HBITMAP hPattern55AABitmap
= NULL
;
898 static HBRUSH hPattern55AABrush
= NULL
;
899 if (hPattern55AABrush
== NULL
)
901 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
902 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
904 return hPattern55AABrush
;
910 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
912 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
914 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
918 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
919 return GetSysColorBrush(COLOR_3DFACE
);
922 return GetSysColorBrush(COLOR_WINDOW
);
926 DefWndScreenshot(HWND hWnd
)
932 User32DefWindowProc(HWND hWnd
,
942 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
947 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
952 return DefWndNCActivate(hWnd
, wParam
);
958 Point
.x
= GET_X_LPARAM(lParam
);
959 Point
.y
= GET_Y_LPARAM(lParam
);
960 return (DefWndNCHitTest(hWnd
, Point
));
963 case WM_NCLBUTTONDOWN
:
965 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
968 case WM_NCLBUTTONDBLCLK
:
970 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
973 case WM_WINDOWPOSCHANGING
:
975 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
978 case WM_WINDOWPOSCHANGED
:
980 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
986 if (hWnd
== GetCapture())
990 Pt
.x
= GET_X_LPARAM(lParam
);
991 Pt
.y
= GET_Y_LPARAM(lParam
);
992 ClientToScreen(hWnd
, &Pt
);
993 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
996 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1000 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1005 case WM_CONTEXTMENU
:
1007 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1011 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1015 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1024 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1026 Pt
.x
= GET_X_LPARAM(lParam
);
1027 Pt
.y
= GET_Y_LPARAM(lParam
);
1028 if (Style
& WS_CHILD
)
1030 ScreenToClient(GetParent(hWnd
), &Pt
);
1033 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1035 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1040 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1042 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongW(hWnd
, GWL_STYLE
),
1043 GetClassLongW(hWnd
, GCL_STYLE
), HitCode
);
1045 if(HitCode
== HTCAPTION
)
1046 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1048 Flags
= TPM_LEFTBUTTON
;
1050 TrackPopupMenu(SystemMenu
, Flags
,
1051 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1060 /* FIXME: Implement. */
1068 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1072 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1073 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1077 GetClientRect(hWnd
, &ClientRect
);
1078 x
= (ClientRect
.right
- ClientRect
.left
-
1079 GetSystemMetrics(SM_CXICON
)) / 2;
1080 y
= (ClientRect
.bottom
- ClientRect
.top
-
1081 GetSystemMetrics(SM_CYICON
)) / 2;
1082 DrawIcon(hDC
, x
, y
, hIcon
);
1084 EndPaint(hWnd
, &Ps
);
1092 hRgn
= CreateRectRgn(0, 0, 0, 0);
1093 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1095 RedrawWindow(hWnd
, NULL
, hRgn
,
1096 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1105 DefWndSetRedraw(hWnd
, wParam
);
1111 DestroyWindow(hWnd
);
1115 case WM_MOUSEACTIVATE
:
1117 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1122 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1127 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1135 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1140 /* Check if the window is minimized. */
1141 if (LOWORD(wParam
) != WA_INACTIVE
&&
1142 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1151 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1155 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1160 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1168 case WM_ICONERASEBKGND
:
1171 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1177 if (GetClassLongW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1179 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1180 GetClientRect(hWnd
, &Rect
);
1181 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1185 GetClipBox((HDC
)wParam
, &Rect
);
1187 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1191 case WM_CTLCOLORMSGBOX
:
1192 case WM_CTLCOLOREDIT
:
1193 case WM_CTLCOLORLISTBOX
:
1194 case WM_CTLCOLORBTN
:
1195 case WM_CTLCOLORDLG
:
1196 case WM_CTLCOLORSTATIC
:
1197 case WM_CTLCOLORSCROLLBAR
:
1198 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1202 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1204 if (Style
& WS_CHILD
)
1206 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1211 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1216 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1225 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1231 Pt
.x
= GET_X_LPARAM(lParam
);
1232 Pt
.y
= GET_Y_LPARAM(lParam
);
1233 return (DefWndHandleSysCommand(hWnd
, wParam
, Pt
));
1236 /* FIXME: Handle key messages. */
1244 /* FIXME: This is also incomplete. */
1247 if (HIWORD(lParam
) & KEYDATA_ALT
)
1249 if (wParam
== VK_F4
) /* Try to close the window */
1251 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1252 if (!(GetClassLongW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1255 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1257 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1260 else if (wParam
== VK_SNAPSHOT
)
1262 DefWndScreenshot(hWnd
);
1274 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1275 // if (!(Style & WS_POPUP))
1277 if ((Style
& WS_VISIBLE
) && wParam
)
1279 if (!(Style
& WS_VISIBLE
) && !wParam
)
1281 if (!GetWindow(hWnd
, GW_OWNER
))
1283 NtUserCallTwoParam((DWORD
) hWnd
, (DWORD
) wParam
, TWOPARAM_ROUTINE_ROS_SHOWWINDOW
);
1284 ShowWindow(hWnd
, wParam
? SW_SHOWNA
: SW_HIDE
);
1290 /* FIXME: Check for a desktop. */
1291 if (GetCapture() == hWnd
)
1306 case WM_QUERYDROPOBJECT
:
1308 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1315 case WM_QUERYDRAGICON
:
1320 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1323 return ((LRESULT
)hIcon
);
1325 for (Len
= 1; Len
< 64; Len
++)
1327 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1329 return((LRESULT
)hIcon
);
1332 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1335 /* FIXME: WM_ISACTIVEICON */
1337 case WM_NOTIFYFORMAT
:
1339 if (IsWindowUnicode(hWnd
))
1341 return(NFR_UNICODE
);
1351 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1352 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1353 SetClassLongW(hWnd
, Index
, lParam
);
1354 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1355 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1356 SWP_NOACTIVATE
| SWP_NOZORDER
);
1357 return ((LRESULT
)hOldIcon
);
1362 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1363 return (GetClassLongW(hWnd
, Index
));
1370 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1374 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1381 THRDCARETINFO CaretInfo
;
1384 case 0xffff: /* Caret timer */
1385 /* switch showing byte in win32k and get information about the caret */
1386 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1388 DrawCaret(hWnd
, &CaretInfo
);
1396 case WM_QUERYENDSESSION
:
1406 DefWindowProcA(HWND hWnd
,
1418 case WM_GETTEXTLENGTH
:
1420 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1426 LPSTR AnsiBuffer
= (LPSTR
)lParam
;
1429 Buffer
= HeapAlloc(GetProcessHeap(), 0, wParam
* sizeof(WCHAR
));
1432 Length
= NtUserInternalGetWindowText(hWnd
, Buffer
, wParam
);
1433 if (Length
> 0 && wParam
> 0 &&
1434 !WideCharToMultiByte(CP_ACP
, 0, Buffer
, -1,
1435 AnsiBuffer
, wParam
, NULL
, NULL
))
1437 AnsiBuffer
[0] = '\0';
1440 HeapFree(GetProcessHeap(), 0, Buffer
);
1442 return (LRESULT
)Length
;
1447 ANSI_STRING AnsiString
;
1448 UNICODE_STRING UnicodeString
;
1452 RtlInitAnsiString(&AnsiString
, (LPSTR
)lParam
);
1453 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
1454 NtUserDefSetText(hWnd
, &UnicodeString
);
1455 RtlFreeUnicodeString(&UnicodeString
);
1458 NtUserDefSetText(hWnd
, NULL
);
1460 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1462 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1468 FIXME: Implement these.
1470 case WM_IME_KEYDOWN:
1472 case WM_IME_STARTCOMPOSITION:
1473 case WM_IME_COMPOSITION:
1474 case WM_IME_ENDCOMPOSITION:
1476 case WM_IME_SETCONTEXT:
1480 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
1485 DefWindowProcW(HWND hWnd
,
1497 case WM_GETTEXTLENGTH
:
1499 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1504 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, (PWSTR
)lParam
, wParam
);
1509 UNICODE_STRING UnicodeString
;
1512 RtlInitUnicodeString(&UnicodeString
, (LPWSTR
)lParam
);
1514 NtUserDefSetText(hWnd
, (lParam
? &UnicodeString
: NULL
));
1516 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1518 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1525 SendMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
1529 case WM_IME_SETCONTEXT
:
1536 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);