1 /* $Id: defwnd.c,v 1.130 2004/04/05 22:12:53 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 ******************************************************************/
17 #include <user32/wininternal.h>
27 LRESULT
DefWndNCPaint(HWND hWnd
, HRGN hRgn
);
28 LRESULT
DefWndNCCalcSize(HWND hWnd
, BOOL CalcSizeStruct
, RECT
*Rect
);
29 LRESULT
DefWndNCActivate(HWND hWnd
, WPARAM wParam
);
30 LRESULT
DefWndNCHitTest(HWND hWnd
, POINT Point
);
31 LRESULT
DefWndNCLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
32 LRESULT
DefWndNCLButtonDblClk(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
33 void FASTCALL
MenuInitSysMenuPopup(HMENU Menu
, DWORD Style
, DWORD ClsStyle
, LONG HitTest
);
35 /* GLOBALS *******************************************************************/
37 /* TODO: widgets will be cached here.
38 static HBITMAP hbClose;
39 static HBITMAP hbCloseD;
40 static HBITMAP hbMinimize;
41 static HBITMAP hbMinimizeD;
42 static HBITMAP hbRestore;
43 static HBITMAP hbRestoreD;
44 static HBITMAP hbMaximize;
45 static HBITMAP hbScrUp;
46 static HBITMAP hbScrDwn;
47 static HBITMAP hbScrLeft;
48 static HBITMAP hbScrRight;
52 static COLORREF SysColors
[] =
54 RGB(192, 192, 192) /* COLOR_SCROLLBAR */,
55 RGB(58, 110, 165) /* COLOR_BACKGROUND */,
56 RGB(10, 36, 106) /* COLOR_ACTIVECAPTION */,
57 RGB(128, 128, 128) /* COLOR_INACTIVECAPTION */,
58 RGB(192, 192, 192) /* COLOR_MENU */,
59 RGB(255, 255, 255) /* COLOR_WINDOW */,
60 RGB(0, 0, 0) /* COLOR_WINDOWFRAME */,
61 RGB(0, 0, 0) /* COLOR_MENUTEXT */,
62 RGB(0, 0, 0) /* COLOR_WINDOWTEXT */,
63 RGB(255, 255, 255) /* COLOR_CAPTIONTEXT */,
64 RGB(192, 192, 192) /* COLOR_ACTIVEBORDER */,
65 RGB(192, 192, 192) /* COLOR_INACTIVEBORDER */,
66 RGB(128, 128, 128) /* COLOR_APPWORKSPACE */,
67 RGB(0, 0, 128) /* COLOR_HILIGHT */,
68 RGB(255, 255, 255) /* COLOR_HILIGHTTEXT */,
69 RGB(192, 192, 192) /* COLOR_BTNFACE */,
70 RGB(128, 128, 128) /* COLOR_BTNSHADOW */,
71 RGB(128, 128, 128) /* COLOR_GRAYTEXT */,
72 RGB(0, 0, 0) /* COLOR_BTNTEXT */,
73 RGB(192, 192, 192) /* COLOR_INACTIVECAPTIONTEXT */,
74 RGB(255, 255, 255) /* COLOR_BTNHILIGHT */,
75 RGB(32, 32, 32) /* COLOR_3DDKSHADOW */,
76 RGB(192, 192, 192) /* COLOR_3DLIGHT */,
77 RGB(0, 0, 0) /* COLOR_INFOTEXT */,
78 RGB(255, 255, 192) /* COLOR_INFOBK */,
79 RGB(180, 180, 180) /* COLOR_ALTERNATEBTNFACE */,
80 RGB(0, 0, 255) /* COLOR_HOTLIGHT */,
81 RGB(166, 202, 240) /* COLOR_GRADIENTACTIVECAPTION */,
82 RGB(192, 192, 192) /* COLOR_GRADIENTINACTIVECAPTION */,
85 #define NUM_SYSCOLORS (sizeof(SysColors) / sizeof(SysColors[0]))
87 /* Bits in the dwKeyData */
88 #define KEYDATA_ALT 0x2000
90 /* FUNCTIONS *****************************************************************/
96 GetSysColor(int nIndex
)
98 return SysColors
[nIndex
];
105 GetSysColorPen(int nIndex
)
107 static HPEN SysPens
[NUM_SYSCOLORS
];
109 if (nIndex
< 0 || NUM_SYSCOLORS
< nIndex
)
111 SetLastError(ERROR_INVALID_PARAMETER
);
115 /* FIXME should register this object with DeleteObject() so it
117 if (NULL
== SysPens
[nIndex
])
119 SysPens
[nIndex
] = CreatePen(PS_SOLID
, 1, SysColors
[nIndex
]);
122 return SysPens
[nIndex
];
129 GetSysColorBrush(int nIndex
)
131 static HBRUSH SysBrushes
[NUM_SYSCOLORS
];
133 if (nIndex
< 0 || NUM_SYSCOLORS
< nIndex
)
135 SetLastError(ERROR_INVALID_PARAMETER
);
139 /* FIXME should register this object with DeleteObject() so it
141 if (NULL
== SysBrushes
[nIndex
])
143 SysBrushes
[nIndex
] = (HBRUSH
) ((DWORD
) CreateSolidBrush(SysColors
[nIndex
]) | 0x00800000);
146 return SysBrushes
[nIndex
];
154 DefFrameProcA( HWND hWnd,
170 DefFrameProcW(HWND hWnd,
182 UserHasAnyFrameStyle(ULONG Style
, ULONG ExStyle
)
184 return ((Style
& (WS_THICKFRAME
| WS_DLGFRAME
| WS_BORDER
)) ||
185 (ExStyle
& WS_EX_DLGMODALFRAME
) ||
186 (!(Style
& (WS_CHILD
| WS_POPUP
))));
190 UserHasDlgFrameStyle(ULONG Style
, ULONG ExStyle
)
192 return ((ExStyle
& WS_EX_DLGMODALFRAME
) ||
193 ((Style
& WS_DLGFRAME
) && (!(Style
& WS_THICKFRAME
))));
197 UserHasThickFrameStyle(ULONG Style
, ULONG ExStyle
)
199 return ((Style
& WS_THICKFRAME
) &&
200 (!((Style
& (WS_DLGFRAME
| WS_BORDER
)) == WS_DLGFRAME
)));
204 UserHasThinFrameStyle(ULONG Style
, ULONG ExStyle
)
206 return ((Style
& WS_BORDER
) || (!(Style
& (WS_CHILD
| WS_POPUP
))));
210 UserHasBigFrameStyle(ULONG Style
, ULONG ExStyle
)
212 return ((Style
& (WS_THICKFRAME
| WS_DLGFRAME
)) ||
213 (ExStyle
& WS_EX_DLGMODALFRAME
));
217 UserGetInsideRectNC(HWND hWnd
, RECT
*rect
)
223 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
224 ExStyle
= GetWindowLongW(hWnd
, GWL_EXSTYLE
);
225 GetWindowRect(hWnd
, &WindowRect
);
226 rect
->top
= rect
->left
= 0;
227 rect
->right
= WindowRect
.right
- WindowRect
.left
;
228 rect
->bottom
= WindowRect
.bottom
- WindowRect
.top
;
230 if (Style
& WS_ICONIC
)
235 /* Remove frame from rectangle */
236 if (UserHasThickFrameStyle(Style
, ExStyle
))
238 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
239 -GetSystemMetrics(SM_CYFRAME
));
243 if (UserHasDlgFrameStyle(Style
, ExStyle
))
245 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
246 -GetSystemMetrics(SM_CYDLGFRAME
));
247 /* FIXME: this isn't in NC_AdjustRect? why not? */
248 if (ExStyle
& WS_EX_DLGMODALFRAME
)
249 InflateRect( rect
, -1, 0 );
253 if (UserHasThinFrameStyle(Style
, ExStyle
))
255 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
256 -GetSystemMetrics(SM_CYBORDER
));
264 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
271 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
273 /* Not for child windows. */
274 if (hWnd
!= (HWND
)wParam
)
279 switch(LOWORD(lParam
))
283 WORD Msg
= HIWORD(lParam
);
284 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
285 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
294 HICON hCursor
= (HICON
)GetClassLongW(hWnd
, GCL_HCURSOR
);
306 if (Style
& WS_MAXIMIZE
)
310 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
316 if (Style
& WS_MAXIMIZE
)
320 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
326 if (Style
& WS_MAXIMIZE
)
330 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
336 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
340 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
343 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
347 DefWndStartSizeMove(HWND hWnd
, WPARAM wParam
, POINT
*capturePoint
)
353 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
355 GetWindowRect(hWnd
, &rectWindow
);
357 if ((wParam
& 0xfff0) == SC_MOVE
)
359 /* Move pointer at the center of the caption */
361 UserGetInsideRectNC(hWnd
, &rect
);
362 if (Style
& WS_SYSMENU
)
363 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
364 if (Style
& WS_MINIMIZEBOX
)
365 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
366 if (Style
& WS_MAXIMIZEBOX
)
367 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
368 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
369 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
377 GetMessageW(&msg
, NULL
, 0, 0);
381 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
382 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
394 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
395 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
399 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
400 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
404 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
405 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
409 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
410 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
413 case VK_ESCAPE
: return 0;
419 SetCursorPos( pt
.x
, pt
.y
);
420 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
424 #define ON_LEFT_BORDER(hit) \
425 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
426 #define ON_RIGHT_BORDER(hit) \
427 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
428 #define ON_TOP_BORDER(hit) \
429 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
430 #define ON_BOTTOM_BORDER(hit) \
431 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
434 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
435 ULONG width
, ULONG height
)
437 static HBRUSH hDraggingRectBrush
= NULL
;
439 if(!hDraggingRectBrush
)
441 static HBITMAP hDraggingPattern
= NULL
;
442 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
444 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
445 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
448 HBRUSH hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
449 PatBlt( hdc
, rect
->left
, rect
->top
,
450 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
451 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
452 rect
->bottom
- rect
->top
- height
, PATINVERT
);
453 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
454 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
455 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
456 rect
->bottom
- rect
->top
- height
, PATINVERT
);
457 SelectObject( hdc
, hbrush
);
461 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
465 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
),
466 GetSystemMetrics(SM_CYFRAME
));
468 else DrawFocusRect( hdc
, rect
);
472 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
475 RECT sizingRect
, mouseRect
, origRect
, clipRect
;
477 LONG hittest
= (LONG
)(wParam
& 0x0f);
478 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
479 POINT minTrack
, maxTrack
;
480 POINT capturePoint
, pt
;
481 ULONG Style
= GetWindowLongW(hwnd
, GWL_STYLE
);
482 ULONG ExStyle
= GetWindowLongW(hwnd
, GWL_EXSTYLE
);
484 BOOL iconic
= Style
& WS_MINIMIZE
;
486 DWORD dwPoint
= GetMessagePos();
487 BOOL DragFullWindows
= FALSE
;
490 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
492 pt
.x
= SLOWORD(dwPoint
);
493 pt
.y
= SHIWORD(dwPoint
);
496 if (IsZoomed(hwnd
) || !IsWindowVisible(hwnd
))
501 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
502 if ((wParam
& 0xfff0) == SC_MOVE
)
506 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
519 if (hittest
&& hittest
!= HTSYSMENU
)
526 hittest
= DefWndStartSizeMove(hwnd
, wParam
, &capturePoint
);
535 if (Style
& WS_CHILD
)
537 hWndParent
= GetParent(hwnd
);
540 /* Get min/max info */
542 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
543 GetWindowRect(hwnd
, &sizingRect
);
544 if (Style
& WS_CHILD
)
546 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
547 GetClientRect(hWndParent
, &mouseRect
);
548 clipRect
= mouseRect
;
549 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
553 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
),
554 GetSystemMetrics(SM_CYSCREEN
));
555 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
557 ClipCursor(&clipRect
);
559 origRect
= sizingRect
;
560 if (ON_LEFT_BORDER(hittest
))
562 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
563 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
565 else if (ON_RIGHT_BORDER(hittest
))
567 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
568 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
570 if (ON_TOP_BORDER(hittest
))
572 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
573 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
575 else if (ON_BOTTOM_BORDER(hittest
))
577 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
578 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
580 if (Style
& WS_CHILD
)
582 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
584 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
586 if (GetCapture() != hwnd
) SetCapture( hwnd
);
588 if (Style
& WS_CHILD
)
590 /* Retrieve a default cache DC (without using the window style) */
591 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
598 if( iconic
) /* create a cursor for dragging */
600 HICON hIcon
= (HICON
)GetClassLongW(hwnd
, GCL_HICON
);
601 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
602 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
603 if( !hDragCursor
) iconic
= FALSE
;
606 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
607 if( !iconic
&& !DragFullWindows
)
609 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
616 GetMessageW(&msg
, 0, 0, 0);
618 /* Exit on button-up, Return, or Esc */
619 if ((msg
.message
== WM_LBUTTONUP
) ||
620 ((msg
.message
== WM_KEYDOWN
) &&
621 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
623 if (msg
.message
== WM_PAINT
)
625 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
626 UpdateWindow( msg
.hwnd
);
627 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
631 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
632 continue; /* We are not interested in other messages */
636 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
638 case VK_UP
: pt
.y
-= 8; break;
639 case VK_DOWN
: pt
.y
+= 8; break;
640 case VK_LEFT
: pt
.x
-= 8; break;
641 case VK_RIGHT
: pt
.x
+= 8; break;
644 pt
.x
= max( pt
.x
, mouseRect
.left
);
645 pt
.x
= min( pt
.x
, mouseRect
.right
);
646 pt
.y
= max( pt
.y
, mouseRect
.top
);
647 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
649 dx
= pt
.x
- capturePoint
.x
;
650 dy
= pt
.y
- capturePoint
.y
;
658 if( iconic
) /* ok, no system popup tracking */
660 hOldCursor
= SetCursor(hDragCursor
);
665 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
668 RECT newRect
= sizingRect
;
669 WPARAM wpSizingHit
= 0;
671 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
672 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
673 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
674 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
675 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
676 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
679 /* determine the hit location */
680 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
681 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
682 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
687 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
689 /* To avoid any deadlocks, all the locks on the windows
690 structures must be suspended before the SetWindowPos */
691 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
692 newRect
.right
- newRect
.left
,
693 newRect
.bottom
- newRect
.top
,
694 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
697 sizingRect
= newRect
;
706 if( moved
) /* restore cursors, show icon title later on */
709 SetCursor( hOldCursor
);
711 DestroyCursor( hDragCursor
);
713 else if(!DragFullWindows
)
714 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
716 if (Style
& WS_CHILD
)
717 ReleaseDC( hWndParent
, hdc
);
721 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
722 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
724 /* window moved or resized */
727 /* if the moving/resizing isn't canceled call SetWindowPos
728 * with the new position or the new size of the window
730 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
732 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
734 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
735 sizingRect
.right
- sizingRect
.left
,
736 sizingRect
.bottom
- sizingRect
.top
,
737 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
739 else { /* restore previous size/position */
741 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
742 origRect
.right
- origRect
.left
,
743 origRect
.bottom
- origRect
.top
,
744 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
749 if( Style
& WS_MINIMIZE
)
751 /* Single click brings up the system menu when iconized */
755 if( Style
& WS_SYSMENU
)
756 SendMessageA( hwnd
, WM_SYSCOMMAND
,
757 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
763 /***********************************************************************
764 * DefWndTrackScrollBar
766 * Track a mouse button press on the horizontal or vertical scroll-bar.
769 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
773 if (SC_HSCROLL
== (wParam
& 0xfff0))
775 if (HTHSCROLL
!= (wParam
& 0x0f))
781 else /* SC_VSCROLL */
783 if (HTVSCROLL
!= (wParam
& 0x0f))
789 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
794 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, POINT Pt
)
798 switch (wParam
& 0xfff0)
802 DefWndDoSizeMove(hWnd
, wParam
);
805 wp
.length
= sizeof(WINDOWPLACEMENT
);
806 if(GetWindowPlacement(hWnd
, &wp
))
808 wp
.showCmd
= SW_MINIMIZE
;
809 SetWindowPlacement(hWnd
, &wp
);
813 wp
.length
= sizeof(WINDOWPLACEMENT
);
814 if(GetWindowPlacement(hWnd
, &wp
))
816 wp
.showCmd
= SW_MAXIMIZE
;
817 SetWindowPlacement(hWnd
, &wp
);
821 wp
.length
= sizeof(WINDOWPLACEMENT
);
822 if(GetWindowPlacement(hWnd
, &wp
))
824 wp
.showCmd
= SW_RESTORE
;
825 SetWindowPlacement(hWnd
, &wp
);
829 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
832 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
835 MenuTrackKbdMenuBar(hWnd
, wParam
, Pt
.x
);
839 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
843 /* FIXME: Implement */
852 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
854 POINT maxSize
, minTrack
;
855 LONG style
= GetWindowLongA(hWnd
, GWL_STYLE
);
857 if (Pos
->flags
& SWP_NOSIZE
) return 0;
858 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
860 WinPosGetMinMaxInfo(hWnd
, &maxSize
, NULL
, &minTrack
, NULL
);
861 Pos
->cx
= min(Pos
->cx
, maxSize
.x
);
862 Pos
->cy
= min(Pos
->cy
, maxSize
.y
);
863 if (!(style
& WS_MINIMIZE
))
865 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
866 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
872 /* Undocumented flags. */
873 #define SWP_NOCLIENTMOVE 0x0800
874 #define SWP_NOCLIENTSIZE 0x1000
877 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
881 GetClientRect(hWnd
, &Rect
);
882 MapWindowPoints(hWnd
, (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
?
883 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
885 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
887 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
890 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
892 WPARAM wp
= SIZE_RESTORED
;
897 else if (IsIconic(hWnd
))
901 SendMessageW(hWnd
, WM_SIZE
, wp
,
902 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
908 /***********************************************************************
911 * Default colors for control painting.
914 DefWndControlColor(HDC hDC
, UINT ctlType
)
916 if (CTLCOLOR_SCROLLBAR
== ctlType
)
918 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
919 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
920 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
923 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
924 * we better use 0x55aa bitmap brush to make scrollbar's background
925 * look different from the window background.
927 if (bk
== GetSysColor(COLOR_WINDOW
))
929 static const WORD wPattern55AA
[] =
931 0x5555, 0xaaaa, 0x5555, 0xaaaa,
932 0x5555, 0xaaaa, 0x5555, 0xaaaa
934 static HBITMAP hPattern55AABitmap
= NULL
;
935 static HBRUSH hPattern55AABrush
= NULL
;
936 if (hPattern55AABrush
== NULL
)
938 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
939 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
941 return hPattern55AABrush
;
947 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
949 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
951 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
955 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
956 return GetSysColorBrush(COLOR_3DFACE
);
959 return GetSysColorBrush(COLOR_WINDOW
);
963 DefWndScreenshot(HWND hWnd
)
969 User32DefWindowProc(HWND hWnd
,
979 return DefWndNCPaint(hWnd
, (HRGN
)wParam
);
984 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
989 return DefWndNCActivate(hWnd
, wParam
);
995 Point
.x
= SLOWORD(lParam
);
996 Point
.y
= SHIWORD(lParam
);
997 return (DefWndNCHitTest(hWnd
, Point
));
1000 case WM_NCLBUTTONDOWN
:
1002 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
1005 case WM_NCLBUTTONDBLCLK
:
1007 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
1010 case WM_WINDOWPOSCHANGING
:
1012 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1015 case WM_WINDOWPOSCHANGED
:
1017 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
1023 if (hWnd
== GetCapture())
1027 Pt
.x
= SLOWORD(lParam
);
1028 Pt
.y
= SHIWORD(lParam
);
1029 ClientToScreen(hWnd
, &Pt
);
1030 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1033 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1037 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1042 case WM_CONTEXTMENU
:
1044 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1048 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1052 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1061 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1063 Pt
.x
= SLOWORD(lParam
);
1064 Pt
.y
= SHIWORD(lParam
);
1065 if (Style
& WS_CHILD
)
1067 ScreenToClient(GetParent(hWnd
), &Pt
);
1070 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1072 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1077 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1079 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongW(hWnd
, GWL_STYLE
),
1080 GetClassLongW(hWnd
, GCL_STYLE
), HitCode
);
1082 if(HitCode
== HTCAPTION
)
1083 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1085 Flags
= TPM_LEFTBUTTON
;
1087 TrackPopupMenu(SystemMenu
, Flags
,
1088 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1097 /* FIXME: Implement. */
1105 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1109 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1110 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1114 GetClientRect(hWnd
, &ClientRect
);
1115 x
= (ClientRect
.right
- ClientRect
.left
-
1116 GetSystemMetrics(SM_CXICON
)) / 2;
1117 y
= (ClientRect
.bottom
- ClientRect
.top
-
1118 GetSystemMetrics(SM_CYICON
)) / 2;
1119 DrawIcon(hDC
, x
, y
, hIcon
);
1121 EndPaint(hWnd
, &Ps
);
1129 hRgn
= CreateRectRgn(0, 0, 0, 0);
1130 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1132 RedrawWindow(hWnd
, NULL
, hRgn
,
1133 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1142 DefWndSetRedraw(hWnd
, wParam
);
1148 DestroyWindow(hWnd
);
1152 case WM_MOUSEACTIVATE
:
1154 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1159 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1164 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1172 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1177 /* Check if the window is minimized. */
1178 if (LOWORD(wParam
) != WA_INACTIVE
&&
1179 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1188 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1192 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1197 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1205 case WM_ICONERASEBKGND
:
1208 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1214 if (GetClassLongW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1216 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1217 GetClientRect(hWnd
, &Rect
);
1218 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1222 GetClipBox((HDC
)wParam
, &Rect
);
1224 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1228 case WM_CTLCOLORMSGBOX
:
1229 case WM_CTLCOLOREDIT
:
1230 case WM_CTLCOLORLISTBOX
:
1231 case WM_CTLCOLORBTN
:
1232 case WM_CTLCOLORDLG
:
1233 case WM_CTLCOLORSTATIC
:
1234 case WM_CTLCOLORSCROLLBAR
:
1235 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1239 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1241 if (Style
& WS_CHILD
)
1243 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1248 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1253 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1262 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1268 Pt
.x
= SLOWORD(lParam
);
1269 Pt
.y
= SHIWORD(lParam
);
1270 return (DefWndHandleSysCommand(hWnd
, wParam
, Pt
));
1273 /* FIXME: Handle key messages. */
1281 /* FIXME: This is also incomplete. */
1284 if (HIWORD(lParam
) & KEYDATA_ALT
)
1286 if (wParam
== VK_F4
) /* Try to close the window */
1288 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1289 if (!(GetClassLongW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1292 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1294 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1297 else if (wParam
== VK_SNAPSHOT
)
1299 DefWndScreenshot(hWnd
);
1311 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1312 if (!(Style
& WS_POPUP
))
1314 if ((Style
& WS_VISIBLE
) && wParam
)
1316 if (!(Style
& WS_VISIBLE
) && !wParam
)
1318 if (!GetWindow(hWnd
, GW_OWNER
))
1320 ShowWindow(hWnd
, wParam
? SW_SHOWNA
: SW_HIDE
);
1326 /* FIXME: Check for a desktop. */
1327 if (GetCapture() == hWnd
)
1342 case WM_QUERYDROPOBJECT
:
1344 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1351 case WM_QUERYDRAGICON
:
1356 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1359 return ((LRESULT
)hIcon
);
1361 for (Len
= 1; Len
< 64; Len
++)
1363 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1365 return((LRESULT
)hIcon
);
1368 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1371 /* FIXME: WM_ISACTIVEICON */
1373 case WM_NOTIFYFORMAT
:
1375 if (IsWindowUnicode(hWnd
))
1377 return(NFR_UNICODE
);
1387 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1388 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1389 SetClassLongW(hWnd
, Index
, lParam
);
1390 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1391 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1392 SWP_NOACTIVATE
| SWP_NOZORDER
);
1393 return ((LRESULT
)hOldIcon
);
1398 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1399 return (GetClassLongW(hWnd
, Index
));
1406 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1410 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1417 THRDCARETINFO CaretInfo
;
1420 case 0xffff: /* Caret timer */
1421 /* switch showing byte in win32k and get information about the caret */
1422 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1424 DrawCaret(hWnd
, &CaretInfo
);
1432 case WM_QUERYENDSESSION
:
1442 DefWindowProcA(HWND hWnd
,
1454 case WM_GETTEXTLENGTH
:
1456 return InternalGetWindowText(hWnd
, NULL
, 0);
1461 UNICODE_STRING UnicodeString
;
1462 LPSTR AnsiBuffer
= (LPSTR
)lParam
;
1467 *((PWSTR
)lParam
) = '\0';
1469 UnicodeString
.Length
= UnicodeString
.MaximumLength
=
1470 wParam
* sizeof(WCHAR
);
1471 UnicodeString
.Buffer
= HeapAlloc(GetProcessHeap(), 0,
1472 UnicodeString
.Length
);
1473 if (!UnicodeString
.Buffer
)
1475 Result
= InternalGetWindowText(hWnd
, UnicodeString
.Buffer
, wParam
);
1477 !WideCharToMultiByte(CP_ACP
, 0, UnicodeString
.Buffer
, -1,
1478 AnsiBuffer
, wParam
, NULL
, NULL
))
1480 AnsiBuffer
[wParam
- 1] = 0;
1482 HeapFree(GetProcessHeap(), 0, UnicodeString
.Buffer
);
1489 ANSI_STRING AnsiString
;
1490 RtlInitAnsiString(&AnsiString
, (LPSTR
)lParam
);
1491 NtUserDefSetText(hWnd
, &AnsiString
);
1492 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1494 DefWndNCPaint(hWnd
, (HRGN
)1);
1500 FIXME: Implement these.
1502 case WM_IME_KEYDOWN:
1504 case WM_IME_STARTCOMPOSITION:
1505 case WM_IME_COMPOSITION:
1506 case WM_IME_ENDCOMPOSITION:
1508 case WM_IME_SETCONTEXT:
1512 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
1517 DefWindowProcW(HWND hWnd
,
1529 case WM_GETTEXTLENGTH
:
1531 return InternalGetWindowText(hWnd
, NULL
, 0);
1539 *((PWSTR
)lParam
) = '\0';
1541 Result
= InternalGetWindowText(hWnd
, (PWSTR
)lParam
, wParam
);
1547 UNICODE_STRING UnicodeString
;
1548 ANSI_STRING AnsiString
;
1550 RtlInitUnicodeString(&UnicodeString
, (LPWSTR
)lParam
);
1551 RtlUnicodeStringToAnsiString(&AnsiString
, &UnicodeString
, TRUE
);
1552 NtUserDefSetText(hWnd
, &AnsiString
);
1553 RtlFreeAnsiString(&AnsiString
);
1554 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1556 DefWndNCPaint(hWnd
, (HRGN
)1);
1563 SendMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
1567 case WM_IME_SETCONTEXT
:
1574 return User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);