1 /* $Id: defwnd.c,v 1.149 2004/12/13 15:39:52 navaraf Exp $
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
;
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 if (Style
& WS_CHILD
)
492 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
493 GetClientRect(hWndParent
, &mouseRect
);
494 clipRect
= mouseRect
;
495 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
499 if(!(ExStyle
& WS_EX_TOPMOST
))
501 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
502 mouseRect
= clipRect
;
506 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
507 clipRect
= mouseRect
;
510 ClipCursor(&clipRect
);
512 origRect
= sizingRect
;
513 if (ON_LEFT_BORDER(hittest
))
515 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
516 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
518 else if (ON_RIGHT_BORDER(hittest
))
520 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
521 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
523 if (ON_TOP_BORDER(hittest
))
525 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
526 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
528 else if (ON_BOTTOM_BORDER(hittest
))
530 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
531 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
533 if (Style
& WS_CHILD
)
535 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
538 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
539 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
540 if (GetCapture() != hwnd
) SetCapture( hwnd
);
542 if (Style
& WS_CHILD
)
544 /* Retrieve a default cache DC (without using the window style) */
545 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
551 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
554 SelectObject(hdc
, DesktopRgn
);
556 if( iconic
) /* create a cursor for dragging */
558 HICON hIcon
= (HICON
)GetClassLongW(hwnd
, GCL_HICON
);
559 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
560 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
561 if( !hDragCursor
) iconic
= FALSE
;
564 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
565 if( !iconic
&& !DragFullWindows
)
567 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
574 GetMessageW(&msg
, 0, 0, 0);
576 /* Exit on button-up, Return, or Esc */
577 if ((msg
.message
== WM_LBUTTONUP
) ||
578 ((msg
.message
== WM_KEYDOWN
) &&
579 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
581 if (msg
.message
== WM_PAINT
)
583 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
584 UpdateWindow( msg
.hwnd
);
585 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
589 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
590 continue; /* We are not interested in other messages */
594 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
596 case VK_UP
: pt
.y
-= 8; break;
597 case VK_DOWN
: pt
.y
+= 8; break;
598 case VK_LEFT
: pt
.x
-= 8; break;
599 case VK_RIGHT
: pt
.x
+= 8; break;
602 pt
.x
= max( pt
.x
, mouseRect
.left
);
603 pt
.x
= min( pt
.x
, mouseRect
.right
);
604 pt
.y
= max( pt
.y
, mouseRect
.top
);
605 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
607 dx
= pt
.x
- capturePoint
.x
;
608 dy
= pt
.y
- capturePoint
.y
;
616 if( iconic
) /* ok, no system popup tracking */
618 hOldCursor
= SetCursor(hDragCursor
);
623 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
626 RECT newRect
= sizingRect
;
627 WPARAM wpSizingHit
= 0;
629 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
630 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
631 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
632 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
633 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
634 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
637 /* determine the hit location */
638 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
639 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
640 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
645 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
647 /* To avoid any deadlocks, all the locks on the windows
648 structures must be suspended before the SetWindowPos */
649 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
650 newRect
.right
- newRect
.left
,
651 newRect
.bottom
- newRect
.top
,
652 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
655 sizingRect
= newRect
;
664 if( moved
) /* restore cursors, show icon title later on */
667 SetCursor( hOldCursor
);
669 DestroyCursor( hDragCursor
);
671 else if(!DragFullWindows
)
672 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
674 if (Style
& WS_CHILD
)
675 ReleaseDC( hWndParent
, hdc
);
681 DeleteObject(DesktopRgn
);
684 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
685 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
686 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
688 /* window moved or resized */
691 /* if the moving/resizing isn't canceled call SetWindowPos
692 * with the new position or the new size of the window
694 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
696 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
698 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
699 sizingRect
.right
- sizingRect
.left
,
700 sizingRect
.bottom
- sizingRect
.top
,
701 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
703 else { /* restore previous size/position */
705 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
706 origRect
.right
- origRect
.left
,
707 origRect
.bottom
- origRect
.top
,
708 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
713 if( Style
& WS_MINIMIZE
)
715 /* Single click brings up the system menu when iconized */
719 if( Style
& WS_SYSMENU
)
720 SendMessageA( hwnd
, WM_SYSCOMMAND
,
721 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
727 /***********************************************************************
728 * DefWndTrackScrollBar
730 * Track a mouse button press on the horizontal or vertical scroll-bar.
733 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
737 if (SC_HSCROLL
== (wParam
& 0xfff0))
739 if (HTHSCROLL
!= (wParam
& 0x0f))
745 else /* SC_VSCROLL */
747 if (HTVSCROLL
!= (wParam
& 0x0f))
753 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
758 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, POINT Pt
)
762 switch (wParam
& 0xfff0)
766 DefWndDoSizeMove(hWnd
, wParam
);
769 wp
.length
= sizeof(WINDOWPLACEMENT
);
770 if(GetWindowPlacement(hWnd
, &wp
))
772 wp
.showCmd
= SW_MINIMIZE
;
773 SetWindowPlacement(hWnd
, &wp
);
777 wp
.length
= sizeof(WINDOWPLACEMENT
);
778 if(GetWindowPlacement(hWnd
, &wp
))
780 wp
.showCmd
= SW_MAXIMIZE
;
781 SetWindowPlacement(hWnd
, &wp
);
785 wp
.length
= sizeof(WINDOWPLACEMENT
);
786 if(GetWindowPlacement(hWnd
, &wp
))
788 wp
.showCmd
= SW_RESTORE
;
789 SetWindowPlacement(hWnd
, &wp
);
793 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
796 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
799 MenuTrackKbdMenuBar(hWnd
, wParam
, Pt
.x
);
803 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
807 /* FIXME: Implement */
816 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
818 POINT maxSize
, minTrack
;
819 LONG style
= GetWindowLongA(hWnd
, GWL_STYLE
);
821 if (Pos
->flags
& SWP_NOSIZE
) return 0;
822 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
824 WinPosGetMinMaxInfo(hWnd
, &maxSize
, NULL
, &minTrack
, NULL
);
825 Pos
->cx
= min(Pos
->cx
, maxSize
.x
);
826 Pos
->cy
= min(Pos
->cy
, maxSize
.y
);
827 if (!(style
& WS_MINIMIZE
))
829 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
830 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
835 Pos
->cx
= max(Pos
->cx
, 0);
836 Pos
->cy
= max(Pos
->cy
, 0);
841 /* Undocumented flags. */
842 #define SWP_NOCLIENTMOVE 0x0800
843 #define SWP_NOCLIENTSIZE 0x1000
846 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
850 GetClientRect(hWnd
, &Rect
);
851 MapWindowPoints(hWnd
, (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
?
852 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
854 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
856 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
859 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
861 WPARAM wp
= SIZE_RESTORED
;
866 else if (IsIconic(hWnd
))
870 SendMessageW(hWnd
, WM_SIZE
, wp
,
871 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
877 /***********************************************************************
880 * Default colors for control painting.
883 DefWndControlColor(HDC hDC
, UINT ctlType
)
885 if (CTLCOLOR_SCROLLBAR
== ctlType
)
887 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
888 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
889 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
892 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
893 * we better use 0x55aa bitmap brush to make scrollbar's background
894 * look different from the window background.
896 if (bk
== GetSysColor(COLOR_WINDOW
))
898 static const WORD wPattern55AA
[] =
900 0x5555, 0xaaaa, 0x5555, 0xaaaa,
901 0x5555, 0xaaaa, 0x5555, 0xaaaa
903 static HBITMAP hPattern55AABitmap
= NULL
;
904 static HBRUSH hPattern55AABrush
= NULL
;
905 if (hPattern55AABrush
== NULL
)
907 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
908 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
910 return hPattern55AABrush
;
916 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
918 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
920 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
924 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
925 return GetSysColorBrush(COLOR_3DFACE
);
928 return GetSysColorBrush(COLOR_WINDOW
);
932 DefWndScreenshot(HWND hWnd
)
938 User32DefWindowProc(HWND hWnd
,
948 return DefWndNCPaint(hWnd
, (HRGN
)wParam
);
953 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
958 return DefWndNCActivate(hWnd
, wParam
);
964 Point
.x
= GET_X_LPARAM(lParam
);
965 Point
.y
= GET_Y_LPARAM(lParam
);
966 return (DefWndNCHitTest(hWnd
, Point
));
969 case WM_NCLBUTTONDOWN
:
971 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
974 case WM_NCLBUTTONDBLCLK
:
976 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
979 case WM_WINDOWPOSCHANGING
:
981 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
984 case WM_WINDOWPOSCHANGED
:
986 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
992 if (hWnd
== GetCapture())
996 Pt
.x
= GET_X_LPARAM(lParam
);
997 Pt
.y
= GET_Y_LPARAM(lParam
);
998 ClientToScreen(hWnd
, &Pt
);
999 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1002 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1006 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1011 case WM_CONTEXTMENU
:
1013 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1017 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1021 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1030 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1032 Pt
.x
= GET_X_LPARAM(lParam
);
1033 Pt
.y
= GET_Y_LPARAM(lParam
);
1034 if (Style
& WS_CHILD
)
1036 ScreenToClient(GetParent(hWnd
), &Pt
);
1039 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1041 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1046 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1048 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongW(hWnd
, GWL_STYLE
),
1049 GetClassLongW(hWnd
, GCL_STYLE
), HitCode
);
1051 if(HitCode
== HTCAPTION
)
1052 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1054 Flags
= TPM_LEFTBUTTON
;
1056 TrackPopupMenu(SystemMenu
, Flags
,
1057 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1066 /* FIXME: Implement. */
1074 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1078 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1079 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1083 GetClientRect(hWnd
, &ClientRect
);
1084 x
= (ClientRect
.right
- ClientRect
.left
-
1085 GetSystemMetrics(SM_CXICON
)) / 2;
1086 y
= (ClientRect
.bottom
- ClientRect
.top
-
1087 GetSystemMetrics(SM_CYICON
)) / 2;
1088 DrawIcon(hDC
, x
, y
, hIcon
);
1090 EndPaint(hWnd
, &Ps
);
1098 hRgn
= CreateRectRgn(0, 0, 0, 0);
1099 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1101 RedrawWindow(hWnd
, NULL
, hRgn
,
1102 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1111 DefWndSetRedraw(hWnd
, wParam
);
1117 DestroyWindow(hWnd
);
1121 case WM_MOUSEACTIVATE
:
1123 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1128 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1133 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1141 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1146 /* Check if the window is minimized. */
1147 if (LOWORD(wParam
) != WA_INACTIVE
&&
1148 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1157 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1161 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1166 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1174 case WM_ICONERASEBKGND
:
1177 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1183 if (GetClassLongW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1185 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1186 GetClientRect(hWnd
, &Rect
);
1187 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1191 GetClipBox((HDC
)wParam
, &Rect
);
1193 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1197 case WM_CTLCOLORMSGBOX
:
1198 case WM_CTLCOLOREDIT
:
1199 case WM_CTLCOLORLISTBOX
:
1200 case WM_CTLCOLORBTN
:
1201 case WM_CTLCOLORDLG
:
1202 case WM_CTLCOLORSTATIC
:
1203 case WM_CTLCOLORSCROLLBAR
:
1204 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1208 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1210 if (Style
& WS_CHILD
)
1212 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1217 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1222 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1231 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1237 Pt
.x
= GET_X_LPARAM(lParam
);
1238 Pt
.y
= GET_Y_LPARAM(lParam
);
1239 return (DefWndHandleSysCommand(hWnd
, wParam
, Pt
));
1242 /* FIXME: Handle key messages. */
1250 /* FIXME: This is also incomplete. */
1253 if (HIWORD(lParam
) & KEYDATA_ALT
)
1255 if (wParam
== VK_F4
) /* Try to close the window */
1257 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1258 if (!(GetClassLongW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1261 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1263 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1266 else if (wParam
== VK_SNAPSHOT
)
1268 DefWndScreenshot(hWnd
);
1280 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1281 if (!(Style
& WS_POPUP
))
1283 if ((Style
& WS_VISIBLE
) && wParam
)
1285 if (!(Style
& WS_VISIBLE
) && !wParam
)
1287 if (!GetWindow(hWnd
, GW_OWNER
))
1289 ShowWindow(hWnd
, wParam
? SW_SHOWNA
: SW_HIDE
);
1295 /* FIXME: Check for a desktop. */
1296 if (GetCapture() == hWnd
)
1311 case WM_QUERYDROPOBJECT
:
1313 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1320 case WM_QUERYDRAGICON
:
1325 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1328 return ((LRESULT
)hIcon
);
1330 for (Len
= 1; Len
< 64; Len
++)
1332 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1334 return((LRESULT
)hIcon
);
1337 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1340 /* FIXME: WM_ISACTIVEICON */
1342 case WM_NOTIFYFORMAT
:
1344 if (IsWindowUnicode(hWnd
))
1346 return(NFR_UNICODE
);
1356 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1357 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1358 SetClassLongW(hWnd
, Index
, lParam
);
1359 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1360 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1361 SWP_NOACTIVATE
| SWP_NOZORDER
);
1362 return ((LRESULT
)hOldIcon
);
1367 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1368 return (GetClassLongW(hWnd
, Index
));
1375 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1379 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1386 THRDCARETINFO CaretInfo
;
1389 case 0xffff: /* Caret timer */
1390 /* switch showing byte in win32k and get information about the caret */
1391 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1393 DrawCaret(hWnd
, &CaretInfo
);
1401 case WM_QUERYENDSESSION
:
1411 DefWindowProcA(HWND hWnd
,
1423 case WM_GETTEXTLENGTH
:
1425 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1431 LPSTR AnsiBuffer
= (LPSTR
)lParam
;
1436 *((PWSTR
)lParam
) = '\0';
1438 Buffer
= HeapAlloc(GetProcessHeap(), 0, wParam
* sizeof(WCHAR
));
1441 Length
= NtUserInternalGetWindowText(hWnd
, Buffer
, wParam
);
1442 if (Length
> 0 && wParam
> 0 &&
1443 !WideCharToMultiByte(CP_ACP
, 0, Buffer
, -1,
1444 AnsiBuffer
, wParam
, NULL
, NULL
))
1446 AnsiBuffer
[0] = '\0';
1449 HeapFree(GetProcessHeap(), 0, Buffer
);
1451 return (LRESULT
)Length
;
1456 ANSI_STRING AnsiString
;
1457 UNICODE_STRING UnicodeString
;
1461 RtlInitAnsiString(&AnsiString
, (LPSTR
)lParam
);
1462 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
1463 NtUserDefSetText(hWnd
, &UnicodeString
);
1464 RtlFreeUnicodeString(&UnicodeString
);
1467 NtUserDefSetText(hWnd
, NULL
);
1469 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1471 DefWndNCPaint(hWnd
, (HRGN
)1);
1477 FIXME: Implement these.
1479 case WM_IME_KEYDOWN:
1481 case WM_IME_STARTCOMPOSITION:
1482 case WM_IME_COMPOSITION:
1483 case WM_IME_ENDCOMPOSITION:
1485 case WM_IME_SETCONTEXT:
1489 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
1494 DefWindowProcW(HWND hWnd
,
1506 case WM_GETTEXTLENGTH
:
1508 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1515 *((PWSTR
)lParam
) = L
'\0';
1517 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, (PWSTR
)lParam
, wParam
);
1522 UNICODE_STRING UnicodeString
;
1525 RtlInitUnicodeString(&UnicodeString
, (LPWSTR
)lParam
);
1527 NtUserDefSetText(hWnd
, (lParam
? &UnicodeString
: NULL
));
1529 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1531 DefWndNCPaint(hWnd
, (HRGN
)1);
1538 SendMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
1542 case WM_IME_SETCONTEXT
:
1549 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);