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
);
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 GetMessageW(&msg
, NULL
, 0, 0);
324 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
325 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
337 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
338 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
342 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
343 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
347 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
348 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
352 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
353 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
356 case VK_ESCAPE
: return 0;
362 SetCursorPos( pt
.x
, pt
.y
);
363 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
367 #define ON_LEFT_BORDER(hit) \
368 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
369 #define ON_RIGHT_BORDER(hit) \
370 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
371 #define ON_TOP_BORDER(hit) \
372 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
373 #define ON_BOTTOM_BORDER(hit) \
374 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
377 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
378 ULONG width
, ULONG height
)
380 static HBRUSH hDraggingRectBrush
= NULL
;
382 if(!hDraggingRectBrush
)
384 static HBITMAP hDraggingPattern
= NULL
;
385 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
387 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
388 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
391 HBRUSH hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
392 PatBlt( hdc
, rect
->left
, rect
->top
,
393 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
394 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
395 rect
->bottom
- rect
->top
- height
, PATINVERT
);
396 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
397 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
398 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
399 rect
->bottom
- rect
->top
- height
, PATINVERT
);
400 SelectObject( hdc
, hbrush
);
404 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
408 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
));
412 UserDrawWindowFrame(hdc
, rect
, 1, 1);
417 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
421 RECT sizingRect
, mouseRect
, origRect
, clipRect
, unmodRect
;
423 LONG hittest
= (LONG
)(wParam
& 0x0f);
424 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
425 POINT minTrack
, maxTrack
;
426 POINT capturePoint
, pt
;
427 ULONG Style
= GetWindowLongW(hwnd
, GWL_STYLE
);
428 ULONG ExStyle
= GetWindowLongW(hwnd
, GWL_EXSTYLE
);
430 BOOL iconic
= Style
& WS_MINIMIZE
;
432 DWORD dwPoint
= GetMessagePos();
433 BOOL DragFullWindows
= FALSE
;
434 HWND hWndParent
= NULL
;
436 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
438 pt
.x
= GET_X_LPARAM(dwPoint
);
439 pt
.y
= GET_Y_LPARAM(dwPoint
);
442 if (IsZoomed(hwnd
) || !IsWindowVisible(hwnd
))
447 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
448 if ((wParam
& 0xfff0) == SC_MOVE
)
452 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
465 if (hittest
&& ((wParam
& 0xfff0) != SC_MOUSEMENU
))
467 hittest
+= (HTLEFT
- WMSZ_LEFT
);
472 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
481 if (Style
& WS_CHILD
)
483 hWndParent
= GetParent(hwnd
);
486 /* Get min/max info */
488 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
489 GetWindowRect(hwnd
, &sizingRect
);
490 GetWindowRect(hwnd
, &unmodRect
);
491 if (Style
& WS_CHILD
)
493 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
494 GetClientRect(hWndParent
, &mouseRect
);
495 clipRect
= mouseRect
;
496 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
500 if(!(ExStyle
& WS_EX_TOPMOST
))
502 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
503 mouseRect
= clipRect
;
507 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
508 clipRect
= mouseRect
;
511 ClipCursor(&clipRect
);
513 origRect
= sizingRect
;
514 if (ON_LEFT_BORDER(hittest
))
516 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
517 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
519 else if (ON_RIGHT_BORDER(hittest
))
521 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
522 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
524 if (ON_TOP_BORDER(hittest
))
526 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
527 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
529 else if (ON_BOTTOM_BORDER(hittest
))
531 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
532 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
534 if (Style
& WS_CHILD
)
536 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
539 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
540 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
541 if (GetCapture() != hwnd
) SetCapture( hwnd
);
543 if (Style
& WS_CHILD
)
545 /* Retrieve a default cache DC (without using the window style) */
546 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
552 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
555 SelectObject(hdc
, DesktopRgn
);
557 if( iconic
) /* create a cursor for dragging */
559 HICON hIcon
= (HICON
)GetClassLongW(hwnd
, GCL_HICON
);
560 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
561 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
562 if( !hDragCursor
) iconic
= FALSE
;
565 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
566 if( !iconic
&& !DragFullWindows
)
568 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
575 GetMessageW(&msg
, 0, 0, 0);
577 /* Exit on button-up, Return, or Esc */
578 if ((msg
.message
== WM_LBUTTONUP
) ||
579 ((msg
.message
== WM_KEYDOWN
) &&
580 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
582 if (msg
.message
== WM_PAINT
)
584 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
585 UpdateWindow( msg
.hwnd
);
586 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
590 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
591 continue; /* We are not interested in other messages */
595 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
597 case VK_UP
: pt
.y
-= 8; break;
598 case VK_DOWN
: pt
.y
+= 8; break;
599 case VK_LEFT
: pt
.x
-= 8; break;
600 case VK_RIGHT
: pt
.x
+= 8; break;
603 pt
.x
= max( pt
.x
, mouseRect
.left
);
604 pt
.x
= min( pt
.x
, mouseRect
.right
);
605 pt
.y
= max( pt
.y
, mouseRect
.top
);
606 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
608 dx
= pt
.x
- capturePoint
.x
;
609 dy
= pt
.y
- capturePoint
.y
;
617 if( iconic
) /* ok, no system popup tracking */
619 hOldCursor
= SetCursor(hDragCursor
);
624 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
627 RECT newRect
= unmodRect
;
628 WPARAM wpSizingHit
= 0;
630 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
631 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
632 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
633 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
634 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
635 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
638 /* determine the hit location */
639 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
640 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
642 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
647 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
649 /* To avoid any deadlocks, all the locks on the windows
650 structures must be suspended before the SetWindowPos */
651 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
652 newRect
.right
- newRect
.left
,
653 newRect
.bottom
- newRect
.top
,
654 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
657 sizingRect
= newRect
;
666 if( moved
) /* restore cursors, show icon title later on */
669 SetCursor( hOldCursor
);
671 DestroyCursor( hDragCursor
);
673 else if(!DragFullWindows
)
674 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
676 if (Style
& WS_CHILD
)
677 ReleaseDC( hWndParent
, hdc
);
683 DeleteObject(DesktopRgn
);
686 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
687 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
688 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
690 /* window moved or resized */
693 /* if the moving/resizing isn't canceled call SetWindowPos
694 * with the new position or the new size of the window
696 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
698 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
700 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
701 sizingRect
.right
- sizingRect
.left
,
702 sizingRect
.bottom
- sizingRect
.top
,
703 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
705 else { /* restore previous size/position */
707 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
708 origRect
.right
- origRect
.left
,
709 origRect
.bottom
- origRect
.top
,
710 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
715 if( Style
& WS_MINIMIZE
)
717 /* Single click brings up the system menu when iconized */
721 if( Style
& WS_SYSMENU
)
722 SendMessageA( hwnd
, WM_SYSCOMMAND
,
723 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
729 /***********************************************************************
730 * DefWndTrackScrollBar
732 * Track a mouse button press on the horizontal or vertical scroll-bar.
735 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
739 if (SC_HSCROLL
== (wParam
& 0xfff0))
741 if (HTHSCROLL
!= (wParam
& 0x0f))
747 else /* SC_VSCROLL */
749 if (HTVSCROLL
!= (wParam
& 0x0f))
755 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
760 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, POINT Pt
)
764 switch (wParam
& 0xfff0)
768 DefWndDoSizeMove(hWnd
, wParam
);
771 wp
.length
= sizeof(WINDOWPLACEMENT
);
772 if(GetWindowPlacement(hWnd
, &wp
))
774 wp
.showCmd
= SW_MINIMIZE
;
775 SetWindowPlacement(hWnd
, &wp
);
779 wp
.length
= sizeof(WINDOWPLACEMENT
);
780 if(GetWindowPlacement(hWnd
, &wp
))
782 wp
.showCmd
= SW_MAXIMIZE
;
783 SetWindowPlacement(hWnd
, &wp
);
787 wp
.length
= sizeof(WINDOWPLACEMENT
);
788 if(GetWindowPlacement(hWnd
, &wp
))
790 wp
.showCmd
= SW_RESTORE
;
791 SetWindowPlacement(hWnd
, &wp
);
795 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
798 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
801 MenuTrackKbdMenuBar(hWnd
, wParam
, Pt
.x
);
805 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
809 /* FIXME: Implement */
818 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
820 POINT maxSize
, minTrack
;
821 LONG style
= GetWindowLongA(hWnd
, GWL_STYLE
);
823 if (Pos
->flags
& SWP_NOSIZE
) return 0;
824 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
826 WinPosGetMinMaxInfo(hWnd
, &maxSize
, NULL
, &minTrack
, NULL
);
827 Pos
->cx
= min(Pos
->cx
, maxSize
.x
);
828 Pos
->cy
= min(Pos
->cy
, maxSize
.y
);
829 if (!(style
& WS_MINIMIZE
))
831 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
832 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
837 Pos
->cx
= max(Pos
->cx
, 0);
838 Pos
->cy
= max(Pos
->cy
, 0);
843 /* Undocumented flags. */
844 #define SWP_NOCLIENTMOVE 0x0800
845 #define SWP_NOCLIENTSIZE 0x1000
848 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
852 GetClientRect(hWnd
, &Rect
);
853 MapWindowPoints(hWnd
, (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
?
854 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
856 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
858 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
861 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
863 WPARAM wp
= SIZE_RESTORED
;
868 else if (IsIconic(hWnd
))
872 SendMessageW(hWnd
, WM_SIZE
, wp
,
873 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
879 /***********************************************************************
882 * Default colors for control painting.
885 DefWndControlColor(HDC hDC
, UINT ctlType
)
887 if (CTLCOLOR_SCROLLBAR
== ctlType
)
889 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
890 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
891 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
894 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
895 * we better use 0x55aa bitmap brush to make scrollbar's background
896 * look different from the window background.
898 if (bk
== GetSysColor(COLOR_WINDOW
))
900 static const WORD wPattern55AA
[] =
902 0x5555, 0xaaaa, 0x5555, 0xaaaa,
903 0x5555, 0xaaaa, 0x5555, 0xaaaa
905 static HBITMAP hPattern55AABitmap
= NULL
;
906 static HBRUSH hPattern55AABrush
= NULL
;
907 if (hPattern55AABrush
== NULL
)
909 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
910 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
912 return hPattern55AABrush
;
918 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
920 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
922 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
926 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
927 return GetSysColorBrush(COLOR_3DFACE
);
930 return GetSysColorBrush(COLOR_WINDOW
);
934 DefWndScreenshot(HWND hWnd
)
940 User32DefWindowProc(HWND hWnd
,
950 return DefWndNCPaint(hWnd
, (HRGN
)wParam
);
955 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
960 return DefWndNCActivate(hWnd
, wParam
);
966 Point
.x
= GET_X_LPARAM(lParam
);
967 Point
.y
= GET_Y_LPARAM(lParam
);
968 return (DefWndNCHitTest(hWnd
, Point
));
971 case WM_NCLBUTTONDOWN
:
973 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
976 case WM_NCLBUTTONDBLCLK
:
978 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
981 case WM_WINDOWPOSCHANGING
:
983 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
986 case WM_WINDOWPOSCHANGED
:
988 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
994 if (hWnd
== GetCapture())
998 Pt
.x
= GET_X_LPARAM(lParam
);
999 Pt
.y
= GET_Y_LPARAM(lParam
);
1000 ClientToScreen(hWnd
, &Pt
);
1001 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1004 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1008 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1013 case WM_CONTEXTMENU
:
1015 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1019 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1023 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1032 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1034 Pt
.x
= GET_X_LPARAM(lParam
);
1035 Pt
.y
= GET_Y_LPARAM(lParam
);
1036 if (Style
& WS_CHILD
)
1038 ScreenToClient(GetParent(hWnd
), &Pt
);
1041 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1043 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1048 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1050 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongW(hWnd
, GWL_STYLE
),
1051 GetClassLongW(hWnd
, GCL_STYLE
), HitCode
);
1053 if(HitCode
== HTCAPTION
)
1054 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1056 Flags
= TPM_LEFTBUTTON
;
1058 TrackPopupMenu(SystemMenu
, Flags
,
1059 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1068 /* FIXME: Implement. */
1076 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1080 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1081 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1085 GetClientRect(hWnd
, &ClientRect
);
1086 x
= (ClientRect
.right
- ClientRect
.left
-
1087 GetSystemMetrics(SM_CXICON
)) / 2;
1088 y
= (ClientRect
.bottom
- ClientRect
.top
-
1089 GetSystemMetrics(SM_CYICON
)) / 2;
1090 DrawIcon(hDC
, x
, y
, hIcon
);
1092 EndPaint(hWnd
, &Ps
);
1100 hRgn
= CreateRectRgn(0, 0, 0, 0);
1101 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1103 RedrawWindow(hWnd
, NULL
, hRgn
,
1104 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1113 DefWndSetRedraw(hWnd
, wParam
);
1119 DestroyWindow(hWnd
);
1123 case WM_MOUSEACTIVATE
:
1125 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1130 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1135 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1143 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1148 /* Check if the window is minimized. */
1149 if (LOWORD(wParam
) != WA_INACTIVE
&&
1150 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1159 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1163 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1168 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1176 case WM_ICONERASEBKGND
:
1179 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1185 if (GetClassLongW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1187 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1188 GetClientRect(hWnd
, &Rect
);
1189 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1193 GetClipBox((HDC
)wParam
, &Rect
);
1195 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1199 case WM_CTLCOLORMSGBOX
:
1200 case WM_CTLCOLOREDIT
:
1201 case WM_CTLCOLORLISTBOX
:
1202 case WM_CTLCOLORBTN
:
1203 case WM_CTLCOLORDLG
:
1204 case WM_CTLCOLORSTATIC
:
1205 case WM_CTLCOLORSCROLLBAR
:
1206 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1210 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1212 if (Style
& WS_CHILD
)
1214 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1219 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1224 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1233 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1239 Pt
.x
= GET_X_LPARAM(lParam
);
1240 Pt
.y
= GET_Y_LPARAM(lParam
);
1241 return (DefWndHandleSysCommand(hWnd
, wParam
, Pt
));
1244 /* FIXME: Handle key messages. */
1252 /* FIXME: This is also incomplete. */
1255 if (HIWORD(lParam
) & KEYDATA_ALT
)
1257 if (wParam
== VK_F4
) /* Try to close the window */
1259 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1260 if (!(GetClassLongW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1263 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1265 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1268 else if (wParam
== VK_SNAPSHOT
)
1270 DefWndScreenshot(hWnd
);
1282 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1283 if (!(Style
& WS_POPUP
))
1285 if ((Style
& WS_VISIBLE
) && wParam
)
1287 if (!(Style
& WS_VISIBLE
) && !wParam
)
1289 if (!GetWindow(hWnd
, GW_OWNER
))
1291 ShowWindow(hWnd
, wParam
? SW_SHOWNA
: SW_HIDE
);
1297 /* FIXME: Check for a desktop. */
1298 if (GetCapture() == hWnd
)
1313 case WM_QUERYDROPOBJECT
:
1315 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1322 case WM_QUERYDRAGICON
:
1327 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1330 return ((LRESULT
)hIcon
);
1332 for (Len
= 1; Len
< 64; Len
++)
1334 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1336 return((LRESULT
)hIcon
);
1339 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1342 /* FIXME: WM_ISACTIVEICON */
1344 case WM_NOTIFYFORMAT
:
1346 if (IsWindowUnicode(hWnd
))
1348 return(NFR_UNICODE
);
1358 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1359 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1360 SetClassLongW(hWnd
, Index
, lParam
);
1361 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1362 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1363 SWP_NOACTIVATE
| SWP_NOZORDER
);
1364 return ((LRESULT
)hOldIcon
);
1369 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1370 return (GetClassLongW(hWnd
, Index
));
1377 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1381 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1388 THRDCARETINFO CaretInfo
;
1391 case 0xffff: /* Caret timer */
1392 /* switch showing byte in win32k and get information about the caret */
1393 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1395 DrawCaret(hWnd
, &CaretInfo
);
1403 case WM_QUERYENDSESSION
:
1413 DefWindowProcA(HWND hWnd
,
1425 case WM_GETTEXTLENGTH
:
1427 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1433 LPSTR AnsiBuffer
= (LPSTR
)lParam
;
1438 *((PWSTR
)lParam
) = '\0';
1440 Buffer
= HeapAlloc(GetProcessHeap(), 0, wParam
* sizeof(WCHAR
));
1443 Length
= NtUserInternalGetWindowText(hWnd
, Buffer
, wParam
);
1444 if (Length
> 0 && wParam
> 0 &&
1445 !WideCharToMultiByte(CP_ACP
, 0, Buffer
, -1,
1446 AnsiBuffer
, wParam
, NULL
, NULL
))
1448 AnsiBuffer
[0] = '\0';
1451 HeapFree(GetProcessHeap(), 0, Buffer
);
1453 return (LRESULT
)Length
;
1458 ANSI_STRING AnsiString
;
1459 UNICODE_STRING UnicodeString
;
1463 RtlInitAnsiString(&AnsiString
, (LPSTR
)lParam
);
1464 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
1465 NtUserDefSetText(hWnd
, &UnicodeString
);
1466 RtlFreeUnicodeString(&UnicodeString
);
1469 NtUserDefSetText(hWnd
, NULL
);
1471 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1473 DefWndNCPaint(hWnd
, (HRGN
)1);
1479 FIXME: Implement these.
1481 case WM_IME_KEYDOWN:
1483 case WM_IME_STARTCOMPOSITION:
1484 case WM_IME_COMPOSITION:
1485 case WM_IME_ENDCOMPOSITION:
1487 case WM_IME_SETCONTEXT:
1491 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
1496 DefWindowProcW(HWND hWnd
,
1508 case WM_GETTEXTLENGTH
:
1510 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1517 *((PWSTR
)lParam
) = L
'\0';
1519 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, (PWSTR
)lParam
, wParam
);
1524 UNICODE_STRING UnicodeString
;
1527 RtlInitUnicodeString(&UnicodeString
, (LPWSTR
)lParam
);
1529 NtUserDefSetText(hWnd
, (lParam
? &UnicodeString
: NULL
));
1531 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1533 DefWndNCPaint(hWnd
, (HRGN
)1);
1540 SendMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
1544 case WM_IME_SETCONTEXT
:
1551 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);