1 /* $Id: defwnd.c,v 1.143 2004/07/19 12:13:45 weiden 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 ******************************************************************/
18 #include <user32/wininternal.h>
29 #define WM_SETVISIBLE 9
31 #ifndef WM_QUERYDROPOBJECT
32 #define WM_QUERYDROPOBJECT 0x022B
35 LRESULT
DefWndNCPaint(HWND hWnd
, HRGN hRgn
);
36 LRESULT
DefWndNCCalcSize(HWND hWnd
, BOOL CalcSizeStruct
, RECT
*Rect
);
37 LRESULT
DefWndNCActivate(HWND hWnd
, WPARAM wParam
);
38 LRESULT
DefWndNCHitTest(HWND hWnd
, POINT Point
);
39 LRESULT
DefWndNCLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
40 LRESULT
DefWndNCLButtonDblClk(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
41 void FASTCALL
MenuInitSysMenuPopup(HMENU Menu
, DWORD Style
, DWORD ClsStyle
, LONG HitTest
);
43 /* GLOBALS *******************************************************************/
45 /* TODO: widgets will be cached here.
46 static HBITMAP hbClose;
47 static HBITMAP hbCloseD;
48 static HBITMAP hbMinimize;
49 static HBITMAP hbMinimizeD;
50 static HBITMAP hbRestore;
51 static HBITMAP hbRestoreD;
52 static HBITMAP hbMaximize;
53 static HBITMAP hbScrUp;
54 static HBITMAP hbScrDwn;
55 static HBITMAP hbScrLeft;
56 static HBITMAP hbScrRight;
60 static COLORREF SysColors
[] =
62 RGB(212, 208, 200), /* COLOR_SCROLLBAR */
63 RGB(58, 110, 165), /* COLOR_BACKGROUND */
64 RGB(10, 36, 106), /* COLOR_ACTIVECAPTION */
65 RGB(128, 128, 128), /* COLOR_INACTIVECAPTION */
66 RGB(212, 208, 200), /* COLOR_MENU */
67 RGB(255, 255, 255), /* COLOR_WINDOW */
68 RGB(0, 0, 0), /* COLOR_WINDOWFRAME */
69 RGB(0, 0, 0), /* COLOR_MENUTEXT */
70 RGB(0, 0, 0), /* COLOR_WINDOWTEXT */
71 RGB(255, 255, 255), /* COLOR_CAPTIONTEXT */
72 RGB(212, 208, 200), /* COLOR_ACTIVEBORDER */
73 RGB(212, 208, 200), /* COLOR_INACTIVEBORDER */
74 RGB(128, 128, 128), /* COLOR_APPWORKSPACE */
75 RGB(10, 36, 106), /* COLOR_HIGHLIGHT */
76 RGB(255, 255, 255), /* COLOR_HIGHLIGHTTEXT */
77 RGB(212, 208, 200), /* COLOR_BTNFACE */
78 RGB(128, 128, 128), /* COLOR_BTNSHADOW */
79 RGB(128, 128, 128), /* COLOR_GRAYTEXT */
80 RGB(0, 0, 0), /* COLOR_BTNTEXT */
81 RGB(212, 208, 200), /* COLOR_INACTIVECAPTIONTEXT */
82 RGB(255, 255, 255), /* COLOR_BTNHIGHLIGHT */
83 RGB(64, 64, 64), /* COLOR_3DDKSHADOW */
84 RGB(212, 208, 200), /* COLOR_3DLIGHT */
85 RGB(0, 0, 0), /* COLOR_INFOTEXT */
86 RGB(255, 255, 225), /* COLOR_INFOBK */
87 RGB(181, 181, 181), /* COLOR_UNKNOWN */
88 RGB(0, 0, 128), /* COLOR_HOTLIGHT */
89 RGB(166, 202, 240), /* COLOR_GRADIENTACTIVECAPTION */
90 RGB(192, 192, 192), /* COLOR_GRADIENTINACTIVECAPTION */
91 RGB(49, 106, 197), /* COLOR_MENUHILIGHT */
92 RGB(236, 233, 216) /* COLOR_MENUBAR */
95 #define NUM_SYSCOLORS (sizeof(SysColors) / sizeof(SysColors[0]))
97 /* Bits in the dwKeyData */
98 #define KEYDATA_ALT 0x2000
100 /* FUNCTIONS *****************************************************************/
106 GetSysColor(int nIndex
)
108 return SysColors
[nIndex
];
115 GetSysColorPen(int nIndex
)
117 static HPEN SysPens
[NUM_SYSCOLORS
];
119 if (nIndex
< 0 || NUM_SYSCOLORS
< nIndex
)
121 SetLastError(ERROR_INVALID_PARAMETER
);
125 /* FIXME should register this object with DeleteObject() so it
127 if (NULL
== SysPens
[nIndex
])
129 SysPens
[nIndex
] = CreatePen(PS_SOLID
, 1, SysColors
[nIndex
]);
132 return SysPens
[nIndex
];
139 GetSysColorBrush(int nIndex
)
141 static HBRUSH SysBrushes
[NUM_SYSCOLORS
];
143 if (nIndex
< 0 || NUM_SYSCOLORS
< nIndex
)
145 SetLastError(ERROR_INVALID_PARAMETER
);
149 /* FIXME should register this object with DeleteObject() so it
151 if (NULL
== SysBrushes
[nIndex
])
153 SysBrushes
[nIndex
] = (HBRUSH
) ((DWORD
) CreateSolidBrush(SysColors
[nIndex
]) | 0x00800000);
156 return SysBrushes
[nIndex
];
164 DefFrameProcA( HWND hWnd,
180 DefFrameProcW(HWND hWnd,
192 UserHasAnyFrameStyle(ULONG Style
, ULONG ExStyle
)
194 return ((Style
& (WS_THICKFRAME
| WS_DLGFRAME
| WS_BORDER
)) ||
195 (ExStyle
& WS_EX_DLGMODALFRAME
) ||
196 (!(Style
& (WS_CHILD
| WS_POPUP
))));
200 UserHasDlgFrameStyle(ULONG Style
, ULONG ExStyle
)
202 return ((ExStyle
& WS_EX_DLGMODALFRAME
) ||
203 ((Style
& WS_DLGFRAME
) && (!(Style
& WS_THICKFRAME
))));
207 UserHasThickFrameStyle(ULONG Style
, ULONG ExStyle
)
209 return ((Style
& WS_THICKFRAME
) &&
210 (!((Style
& (WS_DLGFRAME
| WS_BORDER
)) == WS_DLGFRAME
)));
214 UserHasThinFrameStyle(ULONG Style
, ULONG ExStyle
)
216 return ((Style
& WS_BORDER
) || (!(Style
& (WS_CHILD
| WS_POPUP
))));
220 UserHasBigFrameStyle(ULONG Style
, ULONG ExStyle
)
222 return ((Style
& (WS_THICKFRAME
| WS_DLGFRAME
)) ||
223 (ExStyle
& WS_EX_DLGMODALFRAME
));
227 UserGetInsideRectNC(HWND hWnd
, RECT
*rect
)
233 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
234 ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
235 GetWindowRect(hWnd
, &WindowRect
);
236 rect
->top
= rect
->left
= 0;
237 rect
->right
= WindowRect
.right
- WindowRect
.left
;
238 rect
->bottom
= WindowRect
.bottom
- WindowRect
.top
;
240 if (Style
& WS_ICONIC
)
245 /* Remove frame from rectangle */
246 if (UserHasThickFrameStyle(Style
, ExStyle
))
248 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
249 -GetSystemMetrics(SM_CYFRAME
));
253 if (UserHasDlgFrameStyle(Style
, ExStyle
))
255 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
256 -GetSystemMetrics(SM_CYDLGFRAME
));
257 /* FIXME: this isn't in NC_AdjustRect? why not? */
258 if (ExStyle
& WS_EX_DLGMODALFRAME
)
259 InflateRect( rect
, -1, 0 );
263 if (UserHasThinFrameStyle(Style
, ExStyle
))
265 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
266 -GetSystemMetrics(SM_CYBORDER
));
274 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
281 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
283 /* Not for child windows. */
284 if (hWnd
!= (HWND
)wParam
)
289 switch(LOWORD(lParam
))
293 WORD Msg
= HIWORD(lParam
);
294 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
295 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
304 HICON hCursor
= (HICON
)GetClassLongW(hWnd
, GCL_HCURSOR
);
316 if (Style
& WS_MAXIMIZE
)
320 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
326 if (Style
& WS_MAXIMIZE
)
330 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
336 if (Style
& WS_MAXIMIZE
)
340 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
346 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
350 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
353 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
357 DefWndStartSizeMove(HWND hWnd
, WPARAM wParam
, POINT
*capturePoint
)
363 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
365 GetWindowRect(hWnd
, &rectWindow
);
367 if ((wParam
& 0xfff0) == SC_MOVE
)
369 /* Move pointer at the center of the caption */
371 UserGetInsideRectNC(hWnd
, &rect
);
372 if (Style
& WS_SYSMENU
)
373 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
374 if (Style
& WS_MINIMIZEBOX
)
375 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
376 if (Style
& WS_MAXIMIZEBOX
)
377 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
378 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
379 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
387 GetMessageW(&msg
, NULL
, 0, 0);
391 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
392 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
404 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
405 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
409 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
410 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
414 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
415 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
419 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
420 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
423 case VK_ESCAPE
: return 0;
429 SetCursorPos( pt
.x
, pt
.y
);
430 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
434 #define ON_LEFT_BORDER(hit) \
435 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
436 #define ON_RIGHT_BORDER(hit) \
437 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
438 #define ON_TOP_BORDER(hit) \
439 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
440 #define ON_BOTTOM_BORDER(hit) \
441 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
444 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
445 ULONG width
, ULONG height
)
447 static HBRUSH hDraggingRectBrush
= NULL
;
449 if(!hDraggingRectBrush
)
451 static HBITMAP hDraggingPattern
= NULL
;
452 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
454 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
455 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
458 HBRUSH hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
459 PatBlt( hdc
, rect
->left
, rect
->top
,
460 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
461 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
462 rect
->bottom
- rect
->top
- height
, PATINVERT
);
463 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
464 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
465 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
466 rect
->bottom
- rect
->top
- height
, PATINVERT
);
467 SelectObject( hdc
, hbrush
);
471 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
475 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
));
479 UserDrawWindowFrame(hdc
, rect
, 1, 1);
484 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
488 RECT sizingRect
, mouseRect
, origRect
, clipRect
;
490 LONG hittest
= (LONG
)(wParam
& 0x0f);
491 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
492 POINT minTrack
, maxTrack
;
493 POINT capturePoint
, pt
;
494 ULONG Style
= GetWindowLongW(hwnd
, GWL_STYLE
);
495 ULONG ExStyle
= GetWindowLongW(hwnd
, GWL_EXSTYLE
);
497 BOOL iconic
= Style
& WS_MINIMIZE
;
499 DWORD dwPoint
= GetMessagePos();
500 BOOL DragFullWindows
= FALSE
;
501 HWND hWndParent
= NULL
;
503 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
505 pt
.x
= GET_X_LPARAM(dwPoint
);
506 pt
.y
= GET_Y_LPARAM(dwPoint
);
509 if (IsZoomed(hwnd
) || !IsWindowVisible(hwnd
))
514 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
515 if ((wParam
& 0xfff0) == SC_MOVE
)
519 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
532 if (hittest
&& ((wParam
& 0xfff0) != SC_MOUSEMENU
))
534 hittest
+= (HTLEFT
- WMSZ_LEFT
);
539 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
548 if (Style
& WS_CHILD
)
550 hWndParent
= GetParent(hwnd
);
553 /* Get min/max info */
555 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
556 GetWindowRect(hwnd
, &sizingRect
);
557 if (Style
& WS_CHILD
)
559 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
560 GetClientRect(hWndParent
, &mouseRect
);
561 clipRect
= mouseRect
;
562 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
566 if(!(ExStyle
& WS_EX_TOPMOST
))
568 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
569 mouseRect
= clipRect
;
573 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
574 clipRect
= mouseRect
;
577 ClipCursor(&clipRect
);
579 origRect
= sizingRect
;
580 if (ON_LEFT_BORDER(hittest
))
582 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
583 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
585 else if (ON_RIGHT_BORDER(hittest
))
587 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
588 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
590 if (ON_TOP_BORDER(hittest
))
592 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
593 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
595 else if (ON_BOTTOM_BORDER(hittest
))
597 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
598 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
600 if (Style
& WS_CHILD
)
602 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
605 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
606 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
607 if (GetCapture() != hwnd
) SetCapture( hwnd
);
609 if (Style
& WS_CHILD
)
611 /* Retrieve a default cache DC (without using the window style) */
612 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
618 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
621 SelectObject(hdc
, DesktopRgn
);
623 if( iconic
) /* create a cursor for dragging */
625 HICON hIcon
= (HICON
)GetClassLongW(hwnd
, GCL_HICON
);
626 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
627 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
628 if( !hDragCursor
) iconic
= FALSE
;
631 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
632 if( !iconic
&& !DragFullWindows
)
634 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
641 GetMessageW(&msg
, 0, 0, 0);
643 /* Exit on button-up, Return, or Esc */
644 if ((msg
.message
== WM_LBUTTONUP
) ||
645 ((msg
.message
== WM_KEYDOWN
) &&
646 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
648 if (msg
.message
== WM_PAINT
)
650 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
651 UpdateWindow( msg
.hwnd
);
652 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
656 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
657 continue; /* We are not interested in other messages */
661 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
663 case VK_UP
: pt
.y
-= 8; break;
664 case VK_DOWN
: pt
.y
+= 8; break;
665 case VK_LEFT
: pt
.x
-= 8; break;
666 case VK_RIGHT
: pt
.x
+= 8; break;
669 pt
.x
= max( pt
.x
, mouseRect
.left
);
670 pt
.x
= min( pt
.x
, mouseRect
.right
);
671 pt
.y
= max( pt
.y
, mouseRect
.top
);
672 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
674 dx
= pt
.x
- capturePoint
.x
;
675 dy
= pt
.y
- capturePoint
.y
;
683 if( iconic
) /* ok, no system popup tracking */
685 hOldCursor
= SetCursor(hDragCursor
);
690 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
693 RECT newRect
= sizingRect
;
694 WPARAM wpSizingHit
= 0;
696 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
697 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
698 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
699 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
700 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
701 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
704 /* determine the hit location */
705 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
706 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
707 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
712 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
714 /* To avoid any deadlocks, all the locks on the windows
715 structures must be suspended before the SetWindowPos */
716 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
717 newRect
.right
- newRect
.left
,
718 newRect
.bottom
- newRect
.top
,
719 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
722 sizingRect
= newRect
;
731 if( moved
) /* restore cursors, show icon title later on */
734 SetCursor( hOldCursor
);
736 DestroyCursor( hDragCursor
);
738 else if(!DragFullWindows
)
739 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
741 if (Style
& WS_CHILD
)
742 ReleaseDC( hWndParent
, hdc
);
748 DeleteObject(DesktopRgn
);
751 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
752 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
753 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
755 /* window moved or resized */
758 /* if the moving/resizing isn't canceled call SetWindowPos
759 * with the new position or the new size of the window
761 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
763 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
765 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
766 sizingRect
.right
- sizingRect
.left
,
767 sizingRect
.bottom
- sizingRect
.top
,
768 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
770 else { /* restore previous size/position */
772 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
773 origRect
.right
- origRect
.left
,
774 origRect
.bottom
- origRect
.top
,
775 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
780 if( Style
& WS_MINIMIZE
)
782 /* Single click brings up the system menu when iconized */
786 if( Style
& WS_SYSMENU
)
787 SendMessageA( hwnd
, WM_SYSCOMMAND
,
788 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
794 /***********************************************************************
795 * DefWndTrackScrollBar
797 * Track a mouse button press on the horizontal or vertical scroll-bar.
800 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
804 if (SC_HSCROLL
== (wParam
& 0xfff0))
806 if (HTHSCROLL
!= (wParam
& 0x0f))
812 else /* SC_VSCROLL */
814 if (HTVSCROLL
!= (wParam
& 0x0f))
820 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
825 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, POINT Pt
)
829 switch (wParam
& 0xfff0)
833 DefWndDoSizeMove(hWnd
, wParam
);
836 wp
.length
= sizeof(WINDOWPLACEMENT
);
837 if(GetWindowPlacement(hWnd
, &wp
))
839 wp
.showCmd
= SW_MINIMIZE
;
840 SetWindowPlacement(hWnd
, &wp
);
844 wp
.length
= sizeof(WINDOWPLACEMENT
);
845 if(GetWindowPlacement(hWnd
, &wp
))
847 wp
.showCmd
= SW_MAXIMIZE
;
848 SetWindowPlacement(hWnd
, &wp
);
852 wp
.length
= sizeof(WINDOWPLACEMENT
);
853 if(GetWindowPlacement(hWnd
, &wp
))
855 wp
.showCmd
= SW_RESTORE
;
856 SetWindowPlacement(hWnd
, &wp
);
860 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
863 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
866 MenuTrackKbdMenuBar(hWnd
, wParam
, Pt
.x
);
870 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
874 /* FIXME: Implement */
883 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
885 POINT maxSize
, minTrack
;
886 LONG style
= GetWindowLongA(hWnd
, GWL_STYLE
);
888 if (Pos
->flags
& SWP_NOSIZE
) return 0;
889 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
891 WinPosGetMinMaxInfo(hWnd
, &maxSize
, NULL
, &minTrack
, NULL
);
892 Pos
->cx
= min(Pos
->cx
, maxSize
.x
);
893 Pos
->cy
= min(Pos
->cy
, maxSize
.y
);
894 if (!(style
& WS_MINIMIZE
))
896 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
897 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
902 Pos
->cx
= max(Pos
->cx
, 0);
903 Pos
->cy
= max(Pos
->cy
, 0);
908 /* Undocumented flags. */
909 #define SWP_NOCLIENTMOVE 0x0800
910 #define SWP_NOCLIENTSIZE 0x1000
913 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
917 GetClientRect(hWnd
, &Rect
);
918 MapWindowPoints(hWnd
, (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
?
919 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
921 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
923 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
926 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
928 WPARAM wp
= SIZE_RESTORED
;
933 else if (IsIconic(hWnd
))
937 SendMessageW(hWnd
, WM_SIZE
, wp
,
938 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
944 /***********************************************************************
947 * Default colors for control painting.
950 DefWndControlColor(HDC hDC
, UINT ctlType
)
952 if (CTLCOLOR_SCROLLBAR
== ctlType
)
954 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
955 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
956 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
959 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
960 * we better use 0x55aa bitmap brush to make scrollbar's background
961 * look different from the window background.
963 if (bk
== GetSysColor(COLOR_WINDOW
))
965 static const WORD wPattern55AA
[] =
967 0x5555, 0xaaaa, 0x5555, 0xaaaa,
968 0x5555, 0xaaaa, 0x5555, 0xaaaa
970 static HBITMAP hPattern55AABitmap
= NULL
;
971 static HBRUSH hPattern55AABrush
= NULL
;
972 if (hPattern55AABrush
== NULL
)
974 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
975 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
977 return hPattern55AABrush
;
983 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
985 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
987 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
991 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
992 return GetSysColorBrush(COLOR_3DFACE
);
995 return GetSysColorBrush(COLOR_WINDOW
);
999 DefWndScreenshot(HWND hWnd
)
1005 User32DefWindowProc(HWND hWnd
,
1015 return DefWndNCPaint(hWnd
, (HRGN
)wParam
);
1020 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
1025 return DefWndNCActivate(hWnd
, wParam
);
1031 Point
.x
= GET_X_LPARAM(lParam
);
1032 Point
.y
= GET_Y_LPARAM(lParam
);
1033 return (DefWndNCHitTest(hWnd
, Point
));
1036 case WM_NCLBUTTONDOWN
:
1038 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
1041 case WM_NCLBUTTONDBLCLK
:
1043 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
1046 case WM_WINDOWPOSCHANGING
:
1048 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1051 case WM_WINDOWPOSCHANGED
:
1053 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
1059 if (hWnd
== GetCapture())
1063 Pt
.x
= GET_X_LPARAM(lParam
);
1064 Pt
.y
= GET_Y_LPARAM(lParam
);
1065 ClientToScreen(hWnd
, &Pt
);
1066 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1069 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1073 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1078 case WM_CONTEXTMENU
:
1080 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1084 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1088 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1097 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1099 Pt
.x
= GET_X_LPARAM(lParam
);
1100 Pt
.y
= GET_Y_LPARAM(lParam
);
1101 if (Style
& WS_CHILD
)
1103 ScreenToClient(GetParent(hWnd
), &Pt
);
1106 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1108 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1113 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1115 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongW(hWnd
, GWL_STYLE
),
1116 GetClassLongW(hWnd
, GCL_STYLE
), HitCode
);
1118 if(HitCode
== HTCAPTION
)
1119 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1121 Flags
= TPM_LEFTBUTTON
;
1123 TrackPopupMenu(SystemMenu
, Flags
,
1124 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1133 /* FIXME: Implement. */
1141 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1145 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1146 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1150 GetClientRect(hWnd
, &ClientRect
);
1151 x
= (ClientRect
.right
- ClientRect
.left
-
1152 GetSystemMetrics(SM_CXICON
)) / 2;
1153 y
= (ClientRect
.bottom
- ClientRect
.top
-
1154 GetSystemMetrics(SM_CYICON
)) / 2;
1155 DrawIcon(hDC
, x
, y
, hIcon
);
1157 EndPaint(hWnd
, &Ps
);
1165 hRgn
= CreateRectRgn(0, 0, 0, 0);
1166 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1168 RedrawWindow(hWnd
, NULL
, hRgn
,
1169 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1178 DefWndSetRedraw(hWnd
, wParam
);
1184 DestroyWindow(hWnd
);
1188 case WM_MOUSEACTIVATE
:
1190 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1195 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1200 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1208 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1213 /* Check if the window is minimized. */
1214 if (LOWORD(wParam
) != WA_INACTIVE
&&
1215 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1224 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1228 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1233 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1241 case WM_ICONERASEBKGND
:
1244 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1250 if (GetClassLongW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1252 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1253 GetClientRect(hWnd
, &Rect
);
1254 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1258 GetClipBox((HDC
)wParam
, &Rect
);
1260 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1264 case WM_CTLCOLORMSGBOX
:
1265 case WM_CTLCOLOREDIT
:
1266 case WM_CTLCOLORLISTBOX
:
1267 case WM_CTLCOLORBTN
:
1268 case WM_CTLCOLORDLG
:
1269 case WM_CTLCOLORSTATIC
:
1270 case WM_CTLCOLORSCROLLBAR
:
1271 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1275 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1277 if (Style
& WS_CHILD
)
1279 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1284 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1289 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1298 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1304 Pt
.x
= GET_X_LPARAM(lParam
);
1305 Pt
.y
= GET_Y_LPARAM(lParam
);
1306 return (DefWndHandleSysCommand(hWnd
, wParam
, Pt
));
1309 /* FIXME: Handle key messages. */
1317 /* FIXME: This is also incomplete. */
1320 if (HIWORD(lParam
) & KEYDATA_ALT
)
1322 if (wParam
== VK_F4
) /* Try to close the window */
1324 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1325 if (!(GetClassLongW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1328 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1330 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1333 else if (wParam
== VK_SNAPSHOT
)
1335 DefWndScreenshot(hWnd
);
1347 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1348 if (!(Style
& WS_POPUP
))
1350 if ((Style
& WS_VISIBLE
) && wParam
)
1352 if (!(Style
& WS_VISIBLE
) && !wParam
)
1354 if (!GetWindow(hWnd
, GW_OWNER
))
1356 ShowWindow(hWnd
, wParam
? SW_SHOWNA
: SW_HIDE
);
1362 /* FIXME: Check for a desktop. */
1363 if (GetCapture() == hWnd
)
1378 case WM_QUERYDROPOBJECT
:
1380 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1387 case WM_QUERYDRAGICON
:
1392 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1395 return ((LRESULT
)hIcon
);
1397 for (Len
= 1; Len
< 64; Len
++)
1399 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1401 return((LRESULT
)hIcon
);
1404 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1407 /* FIXME: WM_ISACTIVEICON */
1409 case WM_NOTIFYFORMAT
:
1411 if (IsWindowUnicode(hWnd
))
1413 return(NFR_UNICODE
);
1423 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1424 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1425 SetClassLongW(hWnd
, Index
, lParam
);
1426 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1427 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1428 SWP_NOACTIVATE
| SWP_NOZORDER
);
1429 return ((LRESULT
)hOldIcon
);
1434 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1435 return (GetClassLongW(hWnd
, Index
));
1442 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1446 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1453 THRDCARETINFO CaretInfo
;
1456 case 0xffff: /* Caret timer */
1457 /* switch showing byte in win32k and get information about the caret */
1458 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1460 DrawCaret(hWnd
, &CaretInfo
);
1468 case WM_QUERYENDSESSION
:
1478 DefWindowProcA(HWND hWnd
,
1490 case WM_GETTEXTLENGTH
:
1492 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1498 LPSTR AnsiBuffer
= (LPSTR
)lParam
;
1503 *((PWSTR
)lParam
) = '\0';
1505 Buffer
= HeapAlloc(GetProcessHeap(), 0, wParam
* sizeof(WCHAR
));
1508 Length
= NtUserInternalGetWindowText(hWnd
, Buffer
, wParam
);
1509 if (Length
> 0 && wParam
> 0 &&
1510 !WideCharToMultiByte(CP_ACP
, 0, Buffer
, -1,
1511 AnsiBuffer
, wParam
, NULL
, NULL
))
1513 AnsiBuffer
[0] = '\0';
1516 HeapFree(GetProcessHeap(), 0, Buffer
);
1518 return (LRESULT
)Length
;
1523 ANSI_STRING AnsiString
;
1524 UNICODE_STRING UnicodeString
;
1528 RtlInitAnsiString(&AnsiString
, (LPSTR
)lParam
);
1529 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
1530 NtUserDefSetText(hWnd
, &UnicodeString
);
1531 RtlFreeUnicodeString(&UnicodeString
);
1534 NtUserDefSetText(hWnd
, NULL
);
1536 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1538 DefWndNCPaint(hWnd
, (HRGN
)1);
1544 FIXME: Implement these.
1546 case WM_IME_KEYDOWN:
1548 case WM_IME_STARTCOMPOSITION:
1549 case WM_IME_COMPOSITION:
1550 case WM_IME_ENDCOMPOSITION:
1552 case WM_IME_SETCONTEXT:
1556 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
1561 DefWindowProcW(HWND hWnd
,
1573 case WM_GETTEXTLENGTH
:
1575 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, NULL
, 0);
1582 *((PWSTR
)lParam
) = L
'\0';
1584 return (LRESULT
)NtUserInternalGetWindowText(hWnd
, (PWSTR
)lParam
, wParam
);
1589 UNICODE_STRING UnicodeString
;
1592 RtlInitUnicodeString(&UnicodeString
, (LPWSTR
)lParam
);
1594 NtUserDefSetText(hWnd
, (lParam
? &UnicodeString
: NULL
));
1596 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1598 DefWndNCPaint(hWnd
, (HRGN
)1);
1605 SendMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
1609 case WM_IME_SETCONTEXT
:
1616 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);