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 if (Style
& WS_CHILD
)
484 hWndParent
= GetParent(hwnd
);
487 /* Get min/max info */
489 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
490 GetWindowRect(hwnd
, &sizingRect
);
491 unmodRect
= sizingRect
;
492 if (Style
& WS_CHILD
)
494 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
495 GetClientRect(hWndParent
, &mouseRect
);
496 clipRect
= mouseRect
;
497 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
501 if(!(ExStyle
& WS_EX_TOPMOST
))
503 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
504 mouseRect
= clipRect
;
508 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
509 clipRect
= mouseRect
;
512 ClipCursor(&clipRect
);
514 origRect
= sizingRect
;
515 if (ON_LEFT_BORDER(hittest
))
517 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
518 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
520 else if (ON_RIGHT_BORDER(hittest
))
522 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
523 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
525 if (ON_TOP_BORDER(hittest
))
527 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
528 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
530 else if (ON_BOTTOM_BORDER(hittest
))
532 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
533 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
535 if (Style
& WS_CHILD
)
537 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
540 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
541 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
542 if (GetCapture() != hwnd
) SetCapture( hwnd
);
544 if (Style
& WS_CHILD
)
546 /* Retrieve a default cache DC (without using the window style) */
547 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
553 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
556 SelectObject(hdc
, DesktopRgn
);
558 if( iconic
) /* create a cursor for dragging */
560 HICON hIcon
= (HICON
)GetClassLongW(hwnd
, GCL_HICON
);
561 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
562 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
563 if( !hDragCursor
) iconic
= FALSE
;
566 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
567 if( !iconic
&& !DragFullWindows
)
569 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
576 if (GetMessageW(&msg
, 0, 0, 0) <= 0)
579 /* Exit on button-up, Return, or Esc */
580 if ((msg
.message
== WM_LBUTTONUP
) ||
581 ((msg
.message
== WM_KEYDOWN
) &&
582 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
584 if (msg
.message
== WM_PAINT
)
586 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
587 UpdateWindow( msg
.hwnd
);
588 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
592 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
593 continue; /* We are not interested in other messages */
597 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
599 case VK_UP
: pt
.y
-= 8; break;
600 case VK_DOWN
: pt
.y
+= 8; break;
601 case VK_LEFT
: pt
.x
-= 8; break;
602 case VK_RIGHT
: pt
.x
+= 8; break;
605 pt
.x
= max( pt
.x
, mouseRect
.left
);
606 pt
.x
= min( pt
.x
, mouseRect
.right
);
607 pt
.y
= max( pt
.y
, mouseRect
.top
);
608 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
610 dx
= pt
.x
- capturePoint
.x
;
611 dy
= pt
.y
- capturePoint
.y
;
619 if( iconic
) /* ok, no system popup tracking */
621 hOldCursor
= SetCursor(hDragCursor
);
626 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
629 RECT newRect
= unmodRect
;
630 WPARAM wpSizingHit
= 0;
632 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
633 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
634 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
635 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
636 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
637 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
640 /* determine the hit location */
641 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
642 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
644 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
649 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
651 /* To avoid any deadlocks, all the locks on the windows
652 structures must be suspended before the SetWindowPos */
653 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
654 newRect
.right
- newRect
.left
,
655 newRect
.bottom
- newRect
.top
,
656 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
659 sizingRect
= newRect
;
668 if( moved
) /* restore cursors, show icon title later on */
671 SetCursor( hOldCursor
);
673 DestroyCursor( hDragCursor
);
675 else if(!DragFullWindows
)
676 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
678 if (Style
& WS_CHILD
)
679 ReleaseDC( hWndParent
, hdc
);
685 DeleteObject(DesktopRgn
);
688 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
689 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
690 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
692 /* window moved or resized */
695 /* if the moving/resizing isn't canceled call SetWindowPos
696 * with the new position or the new size of the window
698 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
700 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
702 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
703 sizingRect
.right
- sizingRect
.left
,
704 sizingRect
.bottom
- sizingRect
.top
,
705 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
707 else { /* restore previous size/position */
709 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
710 origRect
.right
- origRect
.left
,
711 origRect
.bottom
- origRect
.top
,
712 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
717 if( Style
& WS_MINIMIZE
)
719 /* Single click brings up the system menu when iconized */
723 if( Style
& WS_SYSMENU
)
724 SendMessageA( hwnd
, WM_SYSCOMMAND
,
725 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
731 /***********************************************************************
732 * DefWndTrackScrollBar
734 * Track a mouse button press on the horizontal or vertical scroll-bar.
737 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
741 if (SC_HSCROLL
== (wParam
& 0xfff0))
743 if (HTHSCROLL
!= (wParam
& 0x0f))
749 else /* SC_VSCROLL */
751 if (HTVSCROLL
!= (wParam
& 0x0f))
757 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
762 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, POINT Pt
)
766 switch (wParam
& 0xfff0)
770 DefWndDoSizeMove(hWnd
, wParam
);
773 wp
.length
= sizeof(WINDOWPLACEMENT
);
774 if(GetWindowPlacement(hWnd
, &wp
))
776 wp
.showCmd
= SW_MINIMIZE
;
777 SetWindowPlacement(hWnd
, &wp
);
781 wp
.length
= sizeof(WINDOWPLACEMENT
);
782 if(GetWindowPlacement(hWnd
, &wp
))
784 wp
.showCmd
= SW_MAXIMIZE
;
785 SetWindowPlacement(hWnd
, &wp
);
789 wp
.length
= sizeof(WINDOWPLACEMENT
);
790 if(GetWindowPlacement(hWnd
, &wp
))
792 wp
.showCmd
= SW_RESTORE
;
793 SetWindowPlacement(hWnd
, &wp
);
797 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
800 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
803 MenuTrackKbdMenuBar(hWnd
, wParam
, Pt
.x
);
807 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
811 /* FIXME: Implement */
820 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
822 POINT maxSize
, minTrack
;
823 LONG style
= GetWindowLongA(hWnd
, GWL_STYLE
);
825 if (Pos
->flags
& SWP_NOSIZE
) return 0;
826 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
828 WinPosGetMinMaxInfo(hWnd
, &maxSize
, NULL
, &minTrack
, NULL
);
829 Pos
->cx
= min(Pos
->cx
, maxSize
.x
);
830 Pos
->cy
= min(Pos
->cy
, maxSize
.y
);
831 if (!(style
& WS_MINIMIZE
))
833 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
834 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
839 Pos
->cx
= max(Pos
->cx
, 0);
840 Pos
->cy
= max(Pos
->cy
, 0);
845 /* Undocumented flags. */
846 #define SWP_NOCLIENTMOVE 0x0800
847 #define SWP_NOCLIENTSIZE 0x1000
850 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
854 GetClientRect(hWnd
, &Rect
);
855 MapWindowPoints(hWnd
, (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
?
856 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
858 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
860 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
863 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
865 WPARAM wp
= SIZE_RESTORED
;
870 else if (IsIconic(hWnd
))
874 SendMessageW(hWnd
, WM_SIZE
, wp
,
875 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
881 /***********************************************************************
884 * Default colors for control painting.
887 DefWndControlColor(HDC hDC
, UINT ctlType
)
889 if (CTLCOLOR_SCROLLBAR
== ctlType
)
891 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
892 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
893 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
896 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
897 * we better use 0x55aa bitmap brush to make scrollbar's background
898 * look different from the window background.
900 if (bk
== GetSysColor(COLOR_WINDOW
))
902 static const WORD wPattern55AA
[] =
904 0x5555, 0xaaaa, 0x5555, 0xaaaa,
905 0x5555, 0xaaaa, 0x5555, 0xaaaa
907 static HBITMAP hPattern55AABitmap
= NULL
;
908 static HBRUSH hPattern55AABrush
= NULL
;
909 if (hPattern55AABrush
== NULL
)
911 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
912 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
914 return hPattern55AABrush
;
920 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
922 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
924 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
928 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
929 return GetSysColorBrush(COLOR_3DFACE
);
932 return GetSysColorBrush(COLOR_WINDOW
);
936 DefWndScreenshot(HWND hWnd
)
942 User32DefWindowProc(HWND hWnd
,
952 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
957 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
962 return DefWndNCActivate(hWnd
, wParam
);
968 Point
.x
= GET_X_LPARAM(lParam
);
969 Point
.y
= GET_Y_LPARAM(lParam
);
970 return (DefWndNCHitTest(hWnd
, Point
));
973 case WM_NCLBUTTONDOWN
:
975 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
978 case WM_NCLBUTTONDBLCLK
:
980 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
983 case WM_WINDOWPOSCHANGING
:
985 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
988 case WM_WINDOWPOSCHANGED
:
990 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
996 if (hWnd
== GetCapture())
1000 Pt
.x
= GET_X_LPARAM(lParam
);
1001 Pt
.y
= GET_Y_LPARAM(lParam
);
1002 ClientToScreen(hWnd
, &Pt
);
1003 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1006 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1010 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1015 case WM_CONTEXTMENU
:
1017 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1021 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1025 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1034 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1036 Pt
.x
= GET_X_LPARAM(lParam
);
1037 Pt
.y
= GET_Y_LPARAM(lParam
);
1038 if (Style
& WS_CHILD
)
1040 ScreenToClient(GetParent(hWnd
), &Pt
);
1043 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1045 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1050 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1052 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongW(hWnd
, GWL_STYLE
),
1053 GetClassLongW(hWnd
, GCL_STYLE
), HitCode
);
1055 if(HitCode
== HTCAPTION
)
1056 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1058 Flags
= TPM_LEFTBUTTON
;
1060 TrackPopupMenu(SystemMenu
, Flags
,
1061 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1070 /* FIXME: Implement. */
1078 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1082 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1083 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1087 GetClientRect(hWnd
, &ClientRect
);
1088 x
= (ClientRect
.right
- ClientRect
.left
-
1089 GetSystemMetrics(SM_CXICON
)) / 2;
1090 y
= (ClientRect
.bottom
- ClientRect
.top
-
1091 GetSystemMetrics(SM_CYICON
)) / 2;
1092 DrawIcon(hDC
, x
, y
, hIcon
);
1094 EndPaint(hWnd
, &Ps
);
1102 hRgn
= CreateRectRgn(0, 0, 0, 0);
1103 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1105 RedrawWindow(hWnd
, NULL
, hRgn
,
1106 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1115 DefWndSetRedraw(hWnd
, wParam
);
1121 DestroyWindow(hWnd
);
1125 case WM_MOUSEACTIVATE
:
1127 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1132 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1137 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1145 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1150 /* Check if the window is minimized. */
1151 if (LOWORD(wParam
) != WA_INACTIVE
&&
1152 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1161 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1165 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1170 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1178 case WM_ICONERASEBKGND
:
1181 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1187 if (GetClassLongW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1189 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1190 GetClientRect(hWnd
, &Rect
);
1191 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1195 GetClipBox((HDC
)wParam
, &Rect
);
1197 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1201 case WM_CTLCOLORMSGBOX
:
1202 case WM_CTLCOLOREDIT
:
1203 case WM_CTLCOLORLISTBOX
:
1204 case WM_CTLCOLORBTN
:
1205 case WM_CTLCOLORDLG
:
1206 case WM_CTLCOLORSTATIC
:
1207 case WM_CTLCOLORSCROLLBAR
:
1208 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1212 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1214 if (Style
& WS_CHILD
)
1216 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1221 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1226 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1235 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1241 Pt
.x
= GET_X_LPARAM(lParam
);
1242 Pt
.y
= GET_Y_LPARAM(lParam
);
1243 return (DefWndHandleSysCommand(hWnd
, wParam
, Pt
));
1246 /* FIXME: Handle key messages. */
1254 /* FIXME: This is also incomplete. */
1257 if (HIWORD(lParam
) & KEYDATA_ALT
)
1259 if (wParam
== VK_F4
) /* Try to close the window */
1261 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1262 if (!(GetClassLongW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1265 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1267 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1270 else if (wParam
== VK_SNAPSHOT
)
1272 DefWndScreenshot(hWnd
);
1284 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1285 if (!(Style
& WS_POPUP
))
1287 if ((Style
& WS_VISIBLE
) && wParam
)
1289 if (!(Style
& WS_VISIBLE
) && !wParam
)
1291 if (!GetWindow(hWnd
, GW_OWNER
))
1293 ShowWindow(hWnd
, wParam
? SW_SHOWNA
: SW_HIDE
);
1299 /* FIXME: Check for a desktop. */
1300 if (GetCapture() == hWnd
)
1315 case WM_QUERYDROPOBJECT
:
1317 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1324 case WM_QUERYDRAGICON
:
1329 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1332 return ((LRESULT
)hIcon
);
1334 for (Len
= 1; Len
< 64; Len
++)
1336 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1338 return((LRESULT
)hIcon
);
1341 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1344 /* FIXME: WM_ISACTIVEICON */
1346 case WM_NOTIFYFORMAT
:
1348 if (IsWindowUnicode(hWnd
))
1350 return(NFR_UNICODE
);
1360 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1361 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1362 SetClassLongW(hWnd
, Index
, lParam
);
1363 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1364 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1365 SWP_NOACTIVATE
| SWP_NOZORDER
);
1366 return ((LRESULT
)hOldIcon
);
1371 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1372 return (GetClassLongW(hWnd
, Index
));
1379 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1383 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1390 THRDCARETINFO CaretInfo
;
1393 case 0xffff: /* Caret timer */
1394 /* switch showing byte in win32k and get information about the caret */
1395 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1397 DrawCaret(hWnd
, &CaretInfo
);
1405 case WM_QUERYENDSESSION
:
1415 DefWindowProcA(HWND hWnd
,
1427 case WM_GETTEXTLENGTH
:
1429 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1435 LPSTR AnsiBuffer
= (LPSTR
)lParam
;
1440 *((PWSTR
)lParam
) = '\0';
1442 Buffer
= HeapAlloc(GetProcessHeap(), 0, wParam
* sizeof(WCHAR
));
1445 Length
= NtUserInternalGetWindowText(hWnd
, Buffer
, wParam
);
1446 if (Length
> 0 && wParam
> 0 &&
1447 !WideCharToMultiByte(CP_ACP
, 0, Buffer
, -1,
1448 AnsiBuffer
, wParam
, NULL
, NULL
))
1450 AnsiBuffer
[0] = '\0';
1453 HeapFree(GetProcessHeap(), 0, Buffer
);
1455 return (LRESULT
)Length
;
1460 ANSI_STRING AnsiString
;
1461 UNICODE_STRING UnicodeString
;
1465 RtlInitAnsiString(&AnsiString
, (LPSTR
)lParam
);
1466 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
1467 NtUserDefSetText(hWnd
, &UnicodeString
);
1468 RtlFreeUnicodeString(&UnicodeString
);
1471 NtUserDefSetText(hWnd
, NULL
);
1473 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1475 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1481 FIXME: Implement these.
1483 case WM_IME_KEYDOWN:
1485 case WM_IME_STARTCOMPOSITION:
1486 case WM_IME_COMPOSITION:
1487 case WM_IME_ENDCOMPOSITION:
1489 case WM_IME_SETCONTEXT:
1493 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
1498 DefWindowProcW(HWND hWnd
,
1510 case WM_GETTEXTLENGTH
:
1512 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1519 *((PWSTR
)lParam
) = L
'\0';
1521 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, (PWSTR
)lParam
, wParam
);
1526 UNICODE_STRING UnicodeString
;
1529 RtlInitUnicodeString(&UnicodeString
, (LPWSTR
)lParam
);
1531 NtUserDefSetText(hWnd
, (lParam
? &UnicodeString
: NULL
));
1533 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1535 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1542 SendMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
1546 case WM_IME_SETCONTEXT
:
1553 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);