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 #define WM_SETVISIBLE 9
19 #ifndef WM_QUERYDROPOBJECT
20 #define WM_QUERYDROPOBJECT 0x022B
23 LRESULT
DefWndNCPaint(HWND hWnd
, HRGN hRgn
, BOOL Active
);
24 LRESULT
DefWndNCCalcSize(HWND hWnd
, BOOL CalcSizeStruct
, RECT
*Rect
);
25 LRESULT
DefWndNCActivate(HWND hWnd
, WPARAM wParam
);
26 LRESULT
DefWndNCHitTest(HWND hWnd
, POINT Point
);
27 LRESULT
DefWndNCLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
28 LRESULT
DefWndNCLButtonDblClk(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
29 void FASTCALL
MenuInitSysMenuPopup(HMENU Menu
, DWORD Style
, DWORD ClsStyle
, LONG HitTest
);
31 /* GLOBALS *******************************************************************/
33 COLORREF SysColors
[NUM_SYSCOLORS
] = {0};
34 HPEN SysPens
[NUM_SYSCOLORS
] = {0};
35 HBRUSH SysBrushes
[NUM_SYSCOLORS
] = {0};
37 /* Bits in the dwKeyData */
38 #define KEYDATA_ALT 0x2000
40 /* FUNCTIONS *****************************************************************/
43 InitStockObjects(void)
45 /* FIXME - Instead of copying the stuff to usermode we should map the tables to
46 userland. The current implementation has one big flaw: the system color
47 table doesn't get updated when another process changes them. That's why
48 we should rather map the table into usermode. But it only affects the
49 SysColors table - the pens, brushes and stock objects are not affected
50 as their handles never change. But it'd be faster to map them, too. */
51 if(SysBrushes
[0] == NULL
)
53 /* only initialize once */
54 NtUserGetSysColors(SysColors
, NUM_SYSCOLORS
);
55 NtUserGetSysColorPens(SysPens
, NUM_SYSCOLORS
);
56 NtUserGetSysColorBrushes(SysBrushes
, NUM_SYSCOLORS
);
64 GetSysColor(int nIndex
)
66 if(nIndex
>= 0 && nIndex
<= NUM_SYSCOLORS
)
68 return SysColors
[nIndex
];
71 SetLastError(ERROR_INVALID_PARAMETER
);
79 GetSysColorPen(int nIndex
)
81 if(nIndex
>= 0 && nIndex
<= NUM_SYSCOLORS
)
83 return SysPens
[nIndex
];
86 SetLastError(ERROR_INVALID_PARAMETER
);
94 GetSysColorBrush(int nIndex
)
96 if(nIndex
>= 0 && nIndex
<= NUM_SYSCOLORS
)
98 return SysBrushes
[nIndex
];
101 SetLastError(ERROR_INVALID_PARAMETER
);
112 CONST INT
*lpaElements
,
113 CONST COLORREF
*lpaRgbValues
)
122 ChangeSysColors
.Elements
= (INT
*)lpaElements
;
123 ChangeSysColors
.Colors
= (COLORREF
*)lpaRgbValues
;
127 Ret
= NtUserSetSysColors(&ChangeSysColors
, cElements
);
130 /* FIXME - just change it in the usermode structure, too, instead of asking win32k again */
131 NtUserGetSysColors(SysColors
, NUM_SYSCOLORS
);
136 SetLastError(ERROR_INVALID_PARAMETER
);
144 UserGetInsideRectNC(HWND hWnd
, RECT
*rect
)
150 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
151 ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
152 GetWindowRect(hWnd
, &WindowRect
);
153 rect
->top
= rect
->left
= 0;
154 rect
->right
= WindowRect
.right
- WindowRect
.left
;
155 rect
->bottom
= WindowRect
.bottom
- WindowRect
.top
;
157 if (Style
& WS_ICONIC
)
162 /* Remove frame from rectangle */
163 if (UserHasThickFrameStyle(Style
, ExStyle
))
165 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
166 -GetSystemMetrics(SM_CYFRAME
));
170 if (UserHasDlgFrameStyle(Style
, ExStyle
))
172 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
173 -GetSystemMetrics(SM_CYDLGFRAME
));
174 /* FIXME: this isn't in NC_AdjustRect? why not? */
175 if (ExStyle
& WS_EX_DLGMODALFRAME
)
176 InflateRect( rect
, -1, 0 );
180 if (UserHasThinFrameStyle(Style
, ExStyle
))
182 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
183 -GetSystemMetrics(SM_CYBORDER
));
191 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
193 if ((BOOL
) wParam
&& 0 == (GetWindowLong(hWnd
, GWL_STYLE
) & WS_VISIBLE
))
195 ShowWindow(hWnd
, SW_NORMAL
);
203 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
205 /* Not for child windows. */
206 if (hWnd
!= (HWND
)wParam
)
211 switch((INT_PTR
) LOWORD(lParam
))
215 WORD Msg
= HIWORD(lParam
);
216 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
217 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
226 HICON hCursor
= (HICON
)GetClassLongW(hWnd
, GCL_HCURSOR
);
238 if (Style
& WS_MAXIMIZE
)
242 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
248 if (Style
& WS_MAXIMIZE
)
252 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
258 if (Style
& WS_MAXIMIZE
)
262 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
268 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
272 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
275 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
279 DefWndStartSizeMove(HWND hWnd
, WPARAM wParam
, POINT
*capturePoint
)
285 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
287 GetWindowRect(hWnd
, &rectWindow
);
289 if ((wParam
& 0xfff0) == SC_MOVE
)
291 /* Move pointer at the center of the caption */
293 UserGetInsideRectNC(hWnd
, &rect
);
294 if (Style
& WS_SYSMENU
)
295 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
296 if (Style
& WS_MINIMIZEBOX
)
297 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
298 if (Style
& WS_MAXIMIZEBOX
)
299 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
300 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
301 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
310 if (GetMessageW(&msg
, NULL
, 0, 0) <= 0)
315 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
316 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
328 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
329 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
333 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
334 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
338 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
339 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
343 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
344 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
347 case VK_ESCAPE
: return 0;
353 SetCursorPos( pt
.x
, pt
.y
);
354 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
358 #define ON_LEFT_BORDER(hit) \
359 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
360 #define ON_RIGHT_BORDER(hit) \
361 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
362 #define ON_TOP_BORDER(hit) \
363 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
364 #define ON_BOTTOM_BORDER(hit) \
365 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
368 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
369 ULONG width
, ULONG height
)
371 static HBRUSH hDraggingRectBrush
= NULL
;
373 if(!hDraggingRectBrush
)
375 static HBITMAP hDraggingPattern
= NULL
;
376 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
378 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
379 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
382 HBRUSH hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
383 PatBlt( hdc
, rect
->left
, rect
->top
,
384 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
385 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
386 rect
->bottom
- rect
->top
- height
, PATINVERT
);
387 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
388 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
389 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
390 rect
->bottom
- rect
->top
- height
, PATINVERT
);
391 SelectObject( hdc
, hbrush
);
395 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
399 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
));
403 UserDrawWindowFrame(hdc
, rect
, 1, 1);
408 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
412 RECT sizingRect
, mouseRect
, origRect
, clipRect
, unmodRect
;
414 LONG hittest
= (LONG
)(wParam
& 0x0f);
415 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
416 POINT minTrack
, maxTrack
;
417 POINT capturePoint
, pt
;
418 ULONG Style
= GetWindowLongW(hwnd
, GWL_STYLE
);
419 ULONG ExStyle
= GetWindowLongW(hwnd
, GWL_EXSTYLE
);
421 BOOL iconic
= Style
& WS_MINIMIZE
;
423 DWORD dwPoint
= GetMessagePos();
424 BOOL DragFullWindows
= FALSE
;
425 HWND hWndParent
= NULL
;
427 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
429 pt
.x
= GET_X_LPARAM(dwPoint
);
430 pt
.y
= GET_Y_LPARAM(dwPoint
);
433 if (IsZoomed(hwnd
) || !IsWindowVisible(hwnd
))
438 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
439 if ((wParam
& 0xfff0) == SC_MOVE
)
443 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
456 if (hittest
&& ((wParam
& 0xfff0) != SC_MOUSEMENU
))
458 hittest
+= (HTLEFT
- WMSZ_LEFT
);
463 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
472 /* Get min/max info */
474 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
475 GetWindowRect(hwnd
, &sizingRect
);
476 if (Style
& WS_CHILD
)
478 hWndParent
= GetParent(hwnd
);
479 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
480 unmodRect
= sizingRect
;
481 GetClientRect(hWndParent
, &mouseRect
);
482 clipRect
= mouseRect
;
483 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
487 if(!(ExStyle
& WS_EX_TOPMOST
))
489 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
490 mouseRect
= clipRect
;
494 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
495 clipRect
= mouseRect
;
497 unmodRect
= sizingRect
;
499 ClipCursor(&clipRect
);
501 origRect
= sizingRect
;
502 if (ON_LEFT_BORDER(hittest
))
504 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
505 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
507 else if (ON_RIGHT_BORDER(hittest
))
509 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
510 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
512 if (ON_TOP_BORDER(hittest
))
514 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
515 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
517 else if (ON_BOTTOM_BORDER(hittest
))
519 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
520 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
522 if (Style
& WS_CHILD
)
524 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
527 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
528 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
529 if (GetCapture() != hwnd
) SetCapture( hwnd
);
531 if (Style
& WS_CHILD
)
533 /* Retrieve a default cache DC (without using the window style) */
534 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
540 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
543 SelectObject(hdc
, DesktopRgn
);
545 if( iconic
) /* create a cursor for dragging */
547 HICON hIcon
= (HICON
)GetClassLongW(hwnd
, GCL_HICON
);
548 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
549 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
550 if( !hDragCursor
) iconic
= FALSE
;
553 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
554 if( !iconic
&& !DragFullWindows
)
556 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
563 if (GetMessageW(&msg
, 0, 0, 0) <= 0)
566 /* Exit on button-up, Return, or Esc */
567 if ((msg
.message
== WM_LBUTTONUP
) ||
568 ((msg
.message
== WM_KEYDOWN
) &&
569 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
571 if (msg
.message
== WM_PAINT
)
573 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
574 UpdateWindow( msg
.hwnd
);
575 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
579 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
580 continue; /* We are not interested in other messages */
584 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
586 case VK_UP
: pt
.y
-= 8; break;
587 case VK_DOWN
: pt
.y
+= 8; break;
588 case VK_LEFT
: pt
.x
-= 8; break;
589 case VK_RIGHT
: pt
.x
+= 8; break;
592 pt
.x
= max( pt
.x
, mouseRect
.left
);
593 pt
.x
= min( pt
.x
, mouseRect
.right
);
594 pt
.y
= max( pt
.y
, mouseRect
.top
);
595 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
597 dx
= pt
.x
- capturePoint
.x
;
598 dy
= pt
.y
- capturePoint
.y
;
606 if( iconic
) /* ok, no system popup tracking */
608 hOldCursor
= SetCursor(hDragCursor
);
613 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
616 RECT newRect
= unmodRect
;
617 WPARAM wpSizingHit
= 0;
619 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
620 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
621 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
622 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
623 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
624 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
627 /* determine the hit location */
628 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
629 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
631 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
636 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
638 /* To avoid any deadlocks, all the locks on the windows
639 structures must be suspended before the SetWindowPos */
640 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
641 newRect
.right
- newRect
.left
,
642 newRect
.bottom
- newRect
.top
,
643 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
646 sizingRect
= newRect
;
655 if( moved
) /* restore cursors, show icon title later on */
658 SetCursor( hOldCursor
);
660 DestroyCursor( hDragCursor
);
662 else if(!DragFullWindows
)
663 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
665 if (Style
& WS_CHILD
)
666 ReleaseDC( hWndParent
, hdc
);
672 DeleteObject(DesktopRgn
);
675 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
676 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
677 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
679 /* window moved or resized */
682 /* if the moving/resizing isn't canceled call SetWindowPos
683 * with the new position or the new size of the window
685 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
687 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
689 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
690 sizingRect
.right
- sizingRect
.left
,
691 sizingRect
.bottom
- sizingRect
.top
,
692 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
694 else { /* restore previous size/position */
696 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
697 origRect
.right
- origRect
.left
,
698 origRect
.bottom
- origRect
.top
,
699 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
704 if( Style
& WS_MINIMIZE
)
706 /* Single click brings up the system menu when iconized */
710 if( Style
& WS_SYSMENU
)
711 SendMessageA( hwnd
, WM_SYSCOMMAND
,
712 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
718 /***********************************************************************
719 * DefWndTrackScrollBar
721 * Track a mouse button press on the horizontal or vertical scroll-bar.
724 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
728 if (SC_HSCROLL
== (wParam
& 0xfff0))
730 if (HTHSCROLL
!= (wParam
& 0x0f))
736 else /* SC_VSCROLL */
738 if (HTVSCROLL
!= (wParam
& 0x0f))
744 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
749 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, POINT Pt
)
753 switch (wParam
& 0xfff0)
757 DefWndDoSizeMove(hWnd
, wParam
);
760 wp
.length
= sizeof(WINDOWPLACEMENT
);
761 if(GetWindowPlacement(hWnd
, &wp
))
763 wp
.showCmd
= SW_MINIMIZE
;
764 SetWindowPlacement(hWnd
, &wp
);
768 wp
.length
= sizeof(WINDOWPLACEMENT
);
769 if(GetWindowPlacement(hWnd
, &wp
))
771 wp
.showCmd
= SW_MAXIMIZE
;
772 SetWindowPlacement(hWnd
, &wp
);
776 wp
.length
= sizeof(WINDOWPLACEMENT
);
777 if(GetWindowPlacement(hWnd
, &wp
))
779 wp
.showCmd
= SW_RESTORE
;
780 SetWindowPlacement(hWnd
, &wp
);
784 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
787 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
790 MenuTrackKbdMenuBar(hWnd
, wParam
, Pt
.x
);
794 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
798 /* FIXME: Implement */
807 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
809 POINT maxSize
, minTrack
;
810 LONG style
= GetWindowLongA(hWnd
, GWL_STYLE
);
812 if (Pos
->flags
& SWP_NOSIZE
) return 0;
813 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
815 WinPosGetMinMaxInfo(hWnd
, &maxSize
, NULL
, &minTrack
, NULL
);
816 Pos
->cx
= min(Pos
->cx
, maxSize
.x
);
817 Pos
->cy
= min(Pos
->cy
, maxSize
.y
);
818 if (!(style
& WS_MINIMIZE
))
820 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
821 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
826 Pos
->cx
= max(Pos
->cx
, 0);
827 Pos
->cy
= max(Pos
->cy
, 0);
832 /* Undocumented flags. */
833 #define SWP_NOCLIENTMOVE 0x0800
834 #define SWP_NOCLIENTSIZE 0x1000
837 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
841 GetClientRect(hWnd
, &Rect
);
842 MapWindowPoints(hWnd
, (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
?
843 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
845 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
847 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
850 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
852 WPARAM wp
= SIZE_RESTORED
;
857 else if (IsIconic(hWnd
))
861 SendMessageW(hWnd
, WM_SIZE
, wp
,
862 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
868 /***********************************************************************
871 * Default colors for control painting.
874 DefWndControlColor(HDC hDC
, UINT ctlType
)
876 if (CTLCOLOR_SCROLLBAR
== ctlType
)
878 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
879 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
880 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
883 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
884 * we better use 0x55aa bitmap brush to make scrollbar's background
885 * look different from the window background.
887 if (bk
== GetSysColor(COLOR_WINDOW
))
889 static const WORD wPattern55AA
[] =
891 0x5555, 0xaaaa, 0x5555, 0xaaaa,
892 0x5555, 0xaaaa, 0x5555, 0xaaaa
894 static HBITMAP hPattern55AABitmap
= NULL
;
895 static HBRUSH hPattern55AABrush
= NULL
;
896 if (hPattern55AABrush
== NULL
)
898 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
899 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
901 return hPattern55AABrush
;
907 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
909 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
911 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
915 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
916 return GetSysColorBrush(COLOR_3DFACE
);
919 return GetSysColorBrush(COLOR_WINDOW
);
923 DefWndScreenshot(HWND hWnd
)
929 User32DefWindowProc(HWND hWnd
,
939 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
944 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
949 return DefWndNCActivate(hWnd
, wParam
);
955 Point
.x
= GET_X_LPARAM(lParam
);
956 Point
.y
= GET_Y_LPARAM(lParam
);
957 return (DefWndNCHitTest(hWnd
, Point
));
960 case WM_NCLBUTTONDOWN
:
962 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
965 case WM_NCLBUTTONDBLCLK
:
967 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
970 case WM_WINDOWPOSCHANGING
:
972 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
975 case WM_WINDOWPOSCHANGED
:
977 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
983 if (hWnd
== GetCapture())
987 Pt
.x
= GET_X_LPARAM(lParam
);
988 Pt
.y
= GET_Y_LPARAM(lParam
);
989 ClientToScreen(hWnd
, &Pt
);
990 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
993 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
997 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1002 case WM_CONTEXTMENU
:
1004 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1008 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1012 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1021 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1023 Pt
.x
= GET_X_LPARAM(lParam
);
1024 Pt
.y
= GET_Y_LPARAM(lParam
);
1025 if (Style
& WS_CHILD
)
1027 ScreenToClient(GetParent(hWnd
), &Pt
);
1030 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1032 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1037 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1039 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongW(hWnd
, GWL_STYLE
),
1040 GetClassLongW(hWnd
, GCL_STYLE
), HitCode
);
1042 if(HitCode
== HTCAPTION
)
1043 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1045 Flags
= TPM_LEFTBUTTON
;
1047 TrackPopupMenu(SystemMenu
, Flags
,
1048 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1057 /* FIXME: Implement. */
1065 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1069 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1070 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1074 GetClientRect(hWnd
, &ClientRect
);
1075 x
= (ClientRect
.right
- ClientRect
.left
-
1076 GetSystemMetrics(SM_CXICON
)) / 2;
1077 y
= (ClientRect
.bottom
- ClientRect
.top
-
1078 GetSystemMetrics(SM_CYICON
)) / 2;
1079 DrawIcon(hDC
, x
, y
, hIcon
);
1081 EndPaint(hWnd
, &Ps
);
1089 hRgn
= CreateRectRgn(0, 0, 0, 0);
1090 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1092 RedrawWindow(hWnd
, NULL
, hRgn
,
1093 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1102 DefWndSetRedraw(hWnd
, wParam
);
1108 DestroyWindow(hWnd
);
1112 case WM_MOUSEACTIVATE
:
1114 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1119 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1124 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1132 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1137 /* Check if the window is minimized. */
1138 if (LOWORD(wParam
) != WA_INACTIVE
&&
1139 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1148 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1152 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1157 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1165 case WM_ICONERASEBKGND
:
1168 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1174 if (GetClassLongW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1176 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1177 GetClientRect(hWnd
, &Rect
);
1178 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1182 GetClipBox((HDC
)wParam
, &Rect
);
1184 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1188 case WM_CTLCOLORMSGBOX
:
1189 case WM_CTLCOLOREDIT
:
1190 case WM_CTLCOLORLISTBOX
:
1191 case WM_CTLCOLORBTN
:
1192 case WM_CTLCOLORDLG
:
1193 case WM_CTLCOLORSTATIC
:
1194 case WM_CTLCOLORSCROLLBAR
:
1195 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1199 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1201 if (Style
& WS_CHILD
)
1203 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1208 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1213 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1222 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1228 Pt
.x
= GET_X_LPARAM(lParam
);
1229 Pt
.y
= GET_Y_LPARAM(lParam
);
1230 return (DefWndHandleSysCommand(hWnd
, wParam
, Pt
));
1233 /* FIXME: Handle key messages. */
1241 /* FIXME: This is also incomplete. */
1244 if (HIWORD(lParam
) & KEYDATA_ALT
)
1246 if (wParam
== VK_F4
) /* Try to close the window */
1248 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1249 if (!(GetClassLongW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1252 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1254 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1257 else if (wParam
== VK_SNAPSHOT
)
1259 DefWndScreenshot(hWnd
);
1271 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1272 // if (!(Style & WS_POPUP))
1274 if ((Style
& WS_VISIBLE
) && wParam
)
1276 if (!(Style
& WS_VISIBLE
) && !wParam
)
1278 if (!GetWindow(hWnd
, GW_OWNER
))
1280 NtUserCallTwoParam((DWORD
) hWnd
, (DWORD
) wParam
, TWOPARAM_ROUTINE_ROS_SHOWWINDOW
);
1281 ShowWindow(hWnd
, wParam
? SW_SHOWNA
: SW_HIDE
);
1287 /* FIXME: Check for a desktop. */
1288 if (GetCapture() == hWnd
)
1303 case WM_QUERYDROPOBJECT
:
1305 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1312 case WM_QUERYDRAGICON
:
1317 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1320 return ((LRESULT
)hIcon
);
1322 for (Len
= 1; Len
< 64; Len
++)
1324 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1326 return((LRESULT
)hIcon
);
1329 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1332 /* FIXME: WM_ISACTIVEICON */
1334 case WM_NOTIFYFORMAT
:
1336 if (IsWindowUnicode(hWnd
))
1338 return(NFR_UNICODE
);
1348 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1349 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1350 SetClassLongW(hWnd
, Index
, lParam
);
1351 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1352 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1353 SWP_NOACTIVATE
| SWP_NOZORDER
);
1354 return ((LRESULT
)hOldIcon
);
1359 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1360 return (GetClassLongW(hWnd
, Index
));
1367 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1371 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1378 THRDCARETINFO CaretInfo
;
1381 case 0xffff: /* Caret timer */
1382 /* switch showing byte in win32k and get information about the caret */
1383 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1385 DrawCaret(hWnd
, &CaretInfo
);
1393 case WM_QUERYENDSESSION
:
1403 DefWindowProcA(HWND hWnd
,
1415 case WM_GETTEXTLENGTH
:
1417 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1423 LPSTR AnsiBuffer
= (LPSTR
)lParam
;
1428 *((PWSTR
)lParam
) = '\0';
1430 Buffer
= HeapAlloc(GetProcessHeap(), 0, wParam
* sizeof(WCHAR
));
1433 Length
= NtUserInternalGetWindowText(hWnd
, Buffer
, wParam
);
1434 if (Length
> 0 && wParam
> 0 &&
1435 !WideCharToMultiByte(CP_ACP
, 0, Buffer
, -1,
1436 AnsiBuffer
, wParam
, NULL
, NULL
))
1438 AnsiBuffer
[0] = '\0';
1441 HeapFree(GetProcessHeap(), 0, Buffer
);
1443 return (LRESULT
)Length
;
1448 ANSI_STRING AnsiString
;
1449 UNICODE_STRING UnicodeString
;
1453 RtlInitAnsiString(&AnsiString
, (LPSTR
)lParam
);
1454 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
1455 NtUserDefSetText(hWnd
, &UnicodeString
);
1456 RtlFreeUnicodeString(&UnicodeString
);
1459 NtUserDefSetText(hWnd
, NULL
);
1461 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1463 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1469 FIXME: Implement these.
1471 case WM_IME_KEYDOWN:
1473 case WM_IME_STARTCOMPOSITION:
1474 case WM_IME_COMPOSITION:
1475 case WM_IME_ENDCOMPOSITION:
1477 case WM_IME_SETCONTEXT:
1481 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
1486 DefWindowProcW(HWND hWnd
,
1498 case WM_GETTEXTLENGTH
:
1500 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1507 *((PWSTR
)lParam
) = L
'\0';
1509 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, (PWSTR
)lParam
, wParam
);
1514 UNICODE_STRING UnicodeString
;
1517 RtlInitUnicodeString(&UnicodeString
, (LPWSTR
)lParam
);
1519 NtUserDefSetText(hWnd
, (lParam
? &UnicodeString
: NULL
));
1521 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1523 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1530 SendMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
1534 case WM_IME_SETCONTEXT
:
1541 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);