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 ******************************************************************/
16 #include <wine/debug.h>
17 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
20 #define WM_SETVISIBLE 9
22 #ifndef WM_QUERYDROPOBJECT
23 #define WM_QUERYDROPOBJECT 0x022B
26 LRESULT
DefWndNCPaint(HWND hWnd
, HRGN hRgn
, BOOL Active
);
27 LRESULT
DefWndNCCalcSize(HWND hWnd
, BOOL CalcSizeStruct
, RECT
*Rect
);
28 LRESULT
DefWndNCActivate(HWND hWnd
, WPARAM wParam
);
29 LRESULT
DefWndNCHitTest(HWND hWnd
, POINT Point
);
30 LRESULT
DefWndNCLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
31 LRESULT
DefWndNCLButtonDblClk(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
32 void FASTCALL
MenuInitSysMenuPopup(HMENU Menu
, DWORD Style
, DWORD ClsStyle
, LONG HitTest
);
34 /* GLOBALS *******************************************************************/
36 /* Bits in the dwKeyData */
37 #define KEYDATA_ALT 0x2000
38 #define KEYDATA_PREVSTATE 0x4000
40 static short iF10Key
= 0;
41 static short iMenuSysKey
= 0;
43 /* FUNCTIONS *****************************************************************/
46 InitStockObjects(void)
48 /* FIXME - Instead of copying the stuff to usermode we should map the tables to
49 userland. The current implementation has one big flaw: the system color
50 table doesn't get updated when another process changes them. That's why
51 we should rather map the table into usermode. But it only affects the
52 SysColors table - the pens, brushes and stock objects are not affected
53 as their handles never change. But it'd be faster to map them, too. */
62 GetSysColor(int nIndex
)
64 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
66 return gpsi
->argbSystem
[nIndex
];
69 SetLastError(ERROR_INVALID_PARAMETER
);
77 GetSysColorBrush(int nIndex
)
79 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
81 return gpsi
->ahbrSystem
[nIndex
];
84 SetLastError(ERROR_INVALID_PARAMETER
);
95 CONST INT
*lpaElements
,
96 CONST COLORREF
*lpaRgbValues
)
98 return NtUserSetSysColors(cElements
, lpaElements
, lpaRgbValues
, 0);
103 DefSetText(HWND hWnd
, PCWSTR String
, BOOL Ansi
)
105 LARGE_STRING lsString
;
110 RtlInitLargeAnsiString((PLARGE_ANSI_STRING
)&lsString
, (PCSZ
)String
, 0);
112 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING
)&lsString
, String
, 0);
114 return NtUserDefSetText(hWnd
, (String
? &lsString
: NULL
));
118 UserGetInsideRectNC(PWND Wnd
, RECT
*rect
)
124 ExStyle
= Wnd
->ExStyle
;
126 rect
->top
= rect
->left
= 0;
127 rect
->right
= Wnd
->rcWindow
.right
- Wnd
->rcWindow
.left
;
128 rect
->bottom
= Wnd
->rcWindow
.bottom
- Wnd
->rcWindow
.top
;
130 if (Style
& WS_ICONIC
)
135 /* Remove frame from rectangle */
136 if (UserHasThickFrameStyle(Style
, ExStyle
))
138 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
139 -GetSystemMetrics(SM_CYFRAME
));
143 if (UserHasDlgFrameStyle(Style
, ExStyle
))
145 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
146 -GetSystemMetrics(SM_CYDLGFRAME
));
147 /* FIXME: this isn't in NC_AdjustRect? why not? */
148 if (ExStyle
& WS_EX_DLGMODALFRAME
)
149 InflateRect( rect
, -1, 0 );
153 if (UserHasThinFrameStyle(Style
, ExStyle
))
155 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
156 -GetSystemMetrics(SM_CYBORDER
));
164 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
166 LONG Style
= GetWindowLongPtr(hWnd
, GWL_STYLE
);
167 /* Content can be redrawn after a change. */
170 if (!(Style
& WS_VISIBLE
)) /* Not Visible */
172 SetWindowLongPtr(hWnd
, GWL_STYLE
, WS_VISIBLE
);
175 else /* Content cannot be redrawn after a change. */
177 if (Style
& WS_VISIBLE
) /* Visible */
179 RedrawWindow( hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
180 Style
&= ~WS_VISIBLE
;
181 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
); /* clear bits */
189 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
191 /* Not for child windows. */
192 if (hWnd
!= (HWND
)wParam
)
197 switch((INT_PTR
) LOWORD(lParam
))
201 WORD Msg
= HIWORD(lParam
);
202 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
203 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
212 HICON hCursor
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HCURSOR
);
224 if (Style
& WS_MAXIMIZE
)
228 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
234 if (Style
& WS_MAXIMIZE
)
238 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
244 if (Style
& WS_MAXIMIZE
)
248 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
254 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
258 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
261 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
265 DefWndStartSizeMove(HWND hWnd
, PWND Wnd
, WPARAM wParam
, POINT
*capturePoint
)
271 ULONG Style
= Wnd
->style
;
273 rectWindow
= Wnd
->rcWindow
;
275 if ((wParam
& 0xfff0) == SC_MOVE
)
277 /* Move pointer at the center of the caption */
279 UserGetInsideRectNC(Wnd
, &rect
);
280 if (Style
& WS_SYSMENU
)
281 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
282 if (Style
& WS_MINIMIZEBOX
)
283 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
284 if (Style
& WS_MAXIMIZEBOX
)
285 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
286 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
287 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
296 if (GetMessageW(&msg
, NULL
, 0, 0) <= 0)
301 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
302 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
314 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
315 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
319 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
320 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
324 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
325 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
329 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
330 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
333 case VK_ESCAPE
: return 0;
339 SetCursorPos( pt
.x
, pt
.y
);
340 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
344 #define ON_LEFT_BORDER(hit) \
345 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
346 #define ON_RIGHT_BORDER(hit) \
347 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
348 #define ON_TOP_BORDER(hit) \
349 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
350 #define ON_BOTTOM_BORDER(hit) \
351 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
354 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
355 ULONG width
, ULONG height
)
357 static HBRUSH hDraggingRectBrush
= NULL
;
360 if(!hDraggingRectBrush
)
362 static HBITMAP hDraggingPattern
= NULL
;
363 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
365 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
366 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
369 hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
370 PatBlt( hdc
, rect
->left
, rect
->top
,
371 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
372 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
373 rect
->bottom
- rect
->top
- height
, PATINVERT
);
374 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
375 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
376 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
377 rect
->bottom
- rect
->top
- height
, PATINVERT
);
378 SelectObject( hdc
, hbrush
);
382 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
386 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
));
390 UserDrawWindowFrame(hdc
, rect
, 1, 1);
395 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
399 RECT sizingRect
, mouseRect
, origRect
, clipRect
, unmodRect
;
401 LONG hittest
= (LONG
)(wParam
& 0x0f);
402 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
403 POINT minTrack
, maxTrack
;
404 POINT capturePoint
, pt
;
405 ULONG Style
, ExStyle
;
409 DWORD dwPoint
= GetMessagePos();
410 BOOL DragFullWindows
= FALSE
;
411 HWND hWndParent
= NULL
;
414 Wnd
= ValidateHwnd(hwnd
);
419 ExStyle
= Wnd
->ExStyle
;
420 iconic
= (Style
& WS_MINIMIZE
) != 0;
422 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
424 pt
.x
= GET_X_LPARAM(dwPoint
);
425 pt
.y
= GET_Y_LPARAM(dwPoint
);
428 if ((Style
& WS_MAXIMIZE
) || !IsWindowVisible(hwnd
))
433 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
434 if ((wParam
& 0xfff0) == SC_MOVE
)
438 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
451 if (hittest
&& ((wParam
& 0xfff0) != SC_MOUSEMENU
))
453 hittest
+= (HTLEFT
- WMSZ_LEFT
);
458 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
467 /* Get min/max info */
469 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
470 sizingRect
= Wnd
->rcWindow
;
471 if (Style
& WS_CHILD
)
473 hWndParent
= GetParent(hwnd
);
474 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
475 unmodRect
= sizingRect
;
476 GetClientRect(hWndParent
, &mouseRect
);
477 clipRect
= mouseRect
;
478 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
482 if(!(ExStyle
& WS_EX_TOPMOST
))
484 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
485 mouseRect
= clipRect
;
489 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
490 clipRect
= mouseRect
;
492 unmodRect
= sizingRect
;
494 ClipCursor(&clipRect
);
496 origRect
= sizingRect
;
497 if (ON_LEFT_BORDER(hittest
))
499 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
500 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
502 else if (ON_RIGHT_BORDER(hittest
))
504 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
505 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
507 if (ON_TOP_BORDER(hittest
))
509 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
510 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
512 else if (ON_BOTTOM_BORDER(hittest
))
514 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
515 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
517 if (Style
& WS_CHILD
)
519 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
522 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
523 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
524 if (GetCapture() != hwnd
) SetCapture( hwnd
);
526 if (Style
& WS_CHILD
)
528 /* Retrieve a default cache DC (without using the window style) */
529 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
535 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
538 SelectObject(hdc
, DesktopRgn
);
540 if( iconic
) /* create a cursor for dragging */
542 HICON hIcon
= (HICON
)GetClassLongPtrW(hwnd
, GCL_HICON
);
543 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
544 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
545 if( !hDragCursor
) iconic
= FALSE
;
548 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
549 if( !iconic
&& !DragFullWindows
)
551 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
558 if (GetMessageW(&msg
, 0, 0, 0) <= 0)
561 /* Exit on button-up, Return, or Esc */
562 if ((msg
.message
== WM_LBUTTONUP
) ||
563 ((msg
.message
== WM_KEYDOWN
) &&
564 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
566 if (msg
.message
== WM_PAINT
)
568 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
569 UpdateWindow( msg
.hwnd
);
570 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
574 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
575 continue; /* We are not interested in other messages */
579 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
581 case VK_UP
: pt
.y
-= 8; break;
582 case VK_DOWN
: pt
.y
+= 8; break;
583 case VK_LEFT
: pt
.x
-= 8; break;
584 case VK_RIGHT
: pt
.x
+= 8; break;
587 pt
.x
= max( pt
.x
, mouseRect
.left
);
588 pt
.x
= min( pt
.x
, mouseRect
.right
);
589 pt
.y
= max( pt
.y
, mouseRect
.top
);
590 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
592 dx
= pt
.x
- capturePoint
.x
;
593 dy
= pt
.y
- capturePoint
.y
;
601 if( iconic
) /* ok, no system popup tracking */
603 hOldCursor
= SetCursor(hDragCursor
);
608 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
611 RECT newRect
= unmodRect
;
612 WPARAM wpSizingHit
= 0;
614 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
615 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
616 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
617 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
618 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
619 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
622 /* determine the hit location */
623 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
624 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
626 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
631 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
633 /* To avoid any deadlocks, all the locks on the windows
634 structures must be suspended before the SetWindowPos */
635 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
636 newRect
.right
- newRect
.left
,
637 newRect
.bottom
- newRect
.top
,
638 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
641 sizingRect
= newRect
;
650 if( moved
) /* restore cursors, show icon title later on */
653 SetCursor( hOldCursor
);
655 DestroyCursor( hDragCursor
);
657 else if(!DragFullWindows
)
658 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
660 if (Style
& WS_CHILD
)
661 ReleaseDC( hWndParent
, hdc
);
667 DeleteObject(DesktopRgn
);
671 if (ISITHOOKED(WH_CBT
))
674 NtUserMessageCall( hwnd
, WM_CBT
, HCBT_MOVESIZE
, (LPARAM
)&sizingRect
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
675 if (lResult
) moved
= FALSE
;
678 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
679 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
680 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
682 /* window moved or resized */
685 /* if the moving/resizing isn't canceled call SetWindowPos
686 * with the new position or the new size of the window
688 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
690 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
692 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
693 sizingRect
.right
- sizingRect
.left
,
694 sizingRect
.bottom
- sizingRect
.top
,
695 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
697 else { /* restore previous size/position */
699 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
700 origRect
.right
- origRect
.left
,
701 origRect
.bottom
- origRect
.top
,
702 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
707 if( Style
& WS_MINIMIZE
)
709 /* Single click brings up the system menu when iconized */
713 if( Style
& WS_SYSMENU
)
714 SendMessageA( hwnd
, WM_SYSCOMMAND
,
715 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
721 /***********************************************************************
722 * DefWndTrackScrollBar
724 * Track a mouse button press on the horizontal or vertical scroll-bar.
727 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
731 if (SC_HSCROLL
== (wParam
& 0xfff0))
733 if (HTHSCROLL
!= (wParam
& 0x0f))
739 else /* SC_VSCROLL */
741 if (HTVSCROLL
!= (wParam
& 0x0f))
747 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
752 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
757 if (!IsWindowEnabled( hWnd
)) return 0;
759 if (ISITHOOKED(WH_CBT
))
762 NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
763 if (lResult
) return 0;
766 switch (wParam
& 0xfff0)
770 DefWndDoSizeMove(hWnd
, wParam
);
773 wp
.length
= sizeof(WINDOWPLACEMENT
);
774 if(GetWindowPlacement(hWnd
, &wp
))
776 wp
.showCmd
= SW_MINIMIZE
;
777 SetWindowPlacement(hWnd
, &wp
);
781 wp
.length
= sizeof(WINDOWPLACEMENT
);
782 if(GetWindowPlacement(hWnd
, &wp
))
784 wp
.showCmd
= SW_MAXIMIZE
;
785 SetWindowPlacement(hWnd
, &wp
);
789 wp
.length
= sizeof(WINDOWPLACEMENT
);
790 if(GetWindowPlacement(hWnd
, &wp
))
792 wp
.showCmd
= SW_RESTORE
;
793 SetWindowPlacement(hWnd
, &wp
);
797 return SendMessageW(hWnd
, WM_CLOSE
, 0, 0);
801 Pt
.x
= (short)LOWORD(lParam
);
802 Pt
.y
= (short)HIWORD(lParam
);
803 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
807 MenuTrackKbdMenuBar(hWnd
, wParam
, (WCHAR
)lParam
);
812 Pt
.x
= (short)LOWORD(lParam
);
813 Pt
.y
= (short)HIWORD(lParam
);
814 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
819 /* FIXME: Implement */
828 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
830 POINT maxTrack
, minTrack
;
831 LONG style
= GetWindowLongPtrA(hWnd
, GWL_STYLE
);
833 if (Pos
->flags
& SWP_NOSIZE
) return 0;
834 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
836 WinPosGetMinMaxInfo(hWnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
837 Pos
->cx
= min(Pos
->cx
, maxTrack
.x
);
838 Pos
->cy
= min(Pos
->cy
, maxTrack
.y
);
839 if (!(style
& WS_MINIMIZE
))
841 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
842 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
847 Pos
->cx
= max(Pos
->cx
, 0);
848 Pos
->cy
= max(Pos
->cy
, 0);
853 /* Undocumented flags. */
854 #define SWP_NOCLIENTMOVE 0x0800
855 #define SWP_NOCLIENTSIZE 0x1000
858 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
862 GetClientRect(hWnd
, &Rect
);
863 MapWindowPoints(hWnd
, (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
?
864 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
866 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
868 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
871 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
873 WPARAM wp
= SIZE_RESTORED
;
878 else if (IsIconic(hWnd
))
882 SendMessageW(hWnd
, WM_SIZE
, wp
,
883 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
889 /***********************************************************************
892 * Default colors for control painting.
895 DefWndControlColor(HDC hDC
, UINT ctlType
)
897 if (CTLCOLOR_SCROLLBAR
== ctlType
)
899 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
900 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
901 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
904 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
905 * we better use 0x55aa bitmap brush to make scrollbar's background
906 * look different from the window background.
908 if (bk
== GetSysColor(COLOR_WINDOW
))
910 static const WORD wPattern55AA
[] =
912 0x5555, 0xaaaa, 0x5555, 0xaaaa,
913 0x5555, 0xaaaa, 0x5555, 0xaaaa
915 static HBITMAP hPattern55AABitmap
= NULL
;
916 static HBRUSH hPattern55AABrush
= NULL
;
917 if (hPattern55AABrush
== NULL
)
919 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
920 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
922 return hPattern55AABrush
;
928 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
930 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
932 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
936 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
937 return GetSysColorBrush(COLOR_3DFACE
);
940 return GetSysColorBrush(COLOR_WINDOW
);
943 static void DefWndPrint( HWND hwnd
, HDC hdc
, ULONG uFlags
)
948 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
949 !IsWindowVisible(hwnd
) )
953 * Unimplemented flags.
955 if ( (uFlags
& PRF_CHILDREN
) ||
956 (uFlags
& PRF_OWNED
) ||
957 (uFlags
& PRF_NONCLIENT
) )
959 FIXME("WM_PRINT message with unsupported flags\n");
965 if ( uFlags
& PRF_ERASEBKGND
)
966 SendMessageW(hwnd
, WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
971 if ( uFlags
& PRF_CLIENT
)
972 SendMessageW(hwnd
, WM_PRINTCLIENT
, (WPARAM
)hdc
, uFlags
);
976 UserSendUiUpdateMsg(HWND hwnd
, LPARAM lParam
)
978 SendMessageW(hwnd
, WM_UPDATEUISTATE
, (WPARAM
)lParam
, 0);
984 DefWndScreenshot(HWND hWnd
)
996 hdc
= GetWindowDC(hWnd
);
997 GetWindowRect(hWnd
, &rect
);
998 w
= rect
.right
- rect
.left
;
999 h
= rect
.bottom
- rect
.top
;
1001 hbitmap
= CreateCompatibleBitmap(hdc
, w
, h
);
1002 hdc2
= CreateCompatibleDC(hdc
);
1003 SelectObject(hdc2
, hbitmap
);
1005 BitBlt(hdc2
, 0, 0, w
, h
,
1009 SetClipboardData(CF_BITMAP
, hbitmap
);
1011 ReleaseDC(hWnd
, hdc
);
1012 ReleaseDC(hWnd
, hdc2
);
1021 User32DefWindowProc(HWND hWnd
,
1031 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
1036 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
1039 case WM_POPUPSYSTEMMENU
:
1041 /* This is an undocumented message used by the windows taskbar to
1042 display the system menu of windows that belong to other processes. */
1043 HMENU menu
= GetSystemMenu(hWnd
, FALSE
);
1046 TrackPopupMenu(menu
, TPM_LEFTBUTTON
|TPM_RIGHTBUTTON
,
1047 LOWORD(lParam
), HIWORD(lParam
), 0, hWnd
, NULL
);
1053 return DefWndNCActivate(hWnd
, wParam
);
1059 Point
.x
= GET_X_LPARAM(lParam
);
1060 Point
.y
= GET_Y_LPARAM(lParam
);
1061 return (DefWndNCHitTest(hWnd
, Point
));
1064 case WM_LBUTTONDOWN
:
1065 case WM_RBUTTONDOWN
:
1066 case WM_MBUTTONDOWN
:
1067 iF10Key
= iMenuSysKey
= 0;
1070 case WM_NCLBUTTONDOWN
:
1072 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
1075 case WM_LBUTTONDBLCLK
:
1076 return (DefWndNCLButtonDblClk(hWnd
, HTCLIENT
, lParam
));
1078 case WM_NCLBUTTONDBLCLK
:
1080 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
1083 case WM_WINDOWPOSCHANGING
:
1085 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1088 case WM_WINDOWPOSCHANGED
:
1090 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
1093 case WM_NCRBUTTONDOWN
:
1095 /* in Windows, capture is taken when right-clicking on the caption bar */
1096 if (wParam
== HTCAPTION
)
1106 if (hWnd
== GetCapture())
1110 Pt
.x
= GET_X_LPARAM(lParam
);
1111 Pt
.y
= GET_Y_LPARAM(lParam
);
1112 ClientToScreen(hWnd
, &Pt
);
1113 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1116 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1120 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1125 case WM_NCRBUTTONUP
:
1127 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1128 * in Windows), but what _should_ we do? According to MSDN :
1129 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1130 * message to the window". When is it appropriate?
1134 case WM_CONTEXTMENU
:
1136 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1140 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1144 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1153 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1155 Pt
.x
= GET_X_LPARAM(lParam
);
1156 Pt
.y
= GET_Y_LPARAM(lParam
);
1157 if (Style
& WS_CHILD
)
1159 ScreenToClient(GetParent(hWnd
), &Pt
);
1162 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1164 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1169 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1171 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongPtrW(hWnd
, GWL_STYLE
),
1172 GetClassLongPtrW(hWnd
, GCL_STYLE
), HitCode
);
1174 if(HitCode
== HTCAPTION
)
1175 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1177 Flags
= TPM_LEFTBUTTON
;
1179 TrackPopupMenu(SystemMenu
, Flags
,
1180 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1189 DefWndPrint(hWnd
, (HDC
)wParam
, lParam
);
1193 case WM_SYSCOLORCHANGE
:
1195 /* force to redraw non-client area */
1196 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1197 /* Use InvalidateRect to redraw client area, enable
1198 * erase to redraw all subcontrols otherwise send the
1199 * WM_SYSCOLORCHANGE to child windows/controls is required
1201 InvalidateRect(hWnd
,NULL
,TRUE
);
1209 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1214 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1215 (hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
)) != NULL
)
1219 GetClientRect(hWnd
, &ClientRect
);
1220 x
= (ClientRect
.right
- ClientRect
.left
-
1221 GetSystemMetrics(SM_CXICON
)) / 2;
1222 y
= (ClientRect
.bottom
- ClientRect
.top
-
1223 GetSystemMetrics(SM_CYICON
)) / 2;
1224 DrawIcon(hDC
, x
, y
, hIcon
);
1226 EndPaint(hWnd
, &Ps
);
1234 hRgn
= CreateRectRgn(0, 0, 0, 0);
1235 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1237 RedrawWindow(hWnd
, NULL
, hRgn
,
1238 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1247 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1248 if (wParam
) SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
| WS_VISIBLE
);
1251 RedrawWindow(hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
1252 Style
&= ~WS_VISIBLE
;
1253 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
);
1260 DestroyWindow(hWnd
);
1264 case WM_MOUSEACTIVATE
:
1266 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1271 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1276 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1284 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1289 /* Check if the window is minimized. */
1290 if (LOWORD(wParam
) != WA_INACTIVE
&&
1291 !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1300 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1304 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1309 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1317 case WM_ICONERASEBKGND
:
1320 HBRUSH hBrush
= (HBRUSH
)GetClassLongPtrW(hWnd
, GCL_HBRBACKGROUND
);
1326 if (GetClassLongPtrW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1328 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1329 GetClientRect(hWnd
, &Rect
);
1330 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1334 GetClipBox((HDC
)wParam
, &Rect
);
1336 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1340 case WM_CTLCOLORMSGBOX
:
1341 case WM_CTLCOLOREDIT
:
1342 case WM_CTLCOLORLISTBOX
:
1343 case WM_CTLCOLORBTN
:
1344 case WM_CTLCOLORDLG
:
1345 case WM_CTLCOLORSTATIC
:
1346 case WM_CTLCOLORSCROLLBAR
:
1347 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1350 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
1354 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1356 if (Style
& WS_CHILD
)
1358 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1363 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1368 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1377 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1381 return (DefWndHandleSysCommand(hWnd
, wParam
, lParam
));
1384 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
1387 /* FIXME: This is also incomplete. */
1390 if (HIWORD(lParam
) & KEYDATA_ALT
)
1392 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1393 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
1394 if ( (wParam
== VK_MENU
|| wParam
== VK_LMENU
1395 || wParam
== VK_RMENU
) && !iMenuSysKey
)
1398 /* mimic behaviour of XP, sending a WM_SYSCOMMAND when pressing <alt> */
1399 SendMessageW( top
, WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1406 if (wParam
== VK_F4
) /* Try to close the window */
1408 if (!(GetClassLongPtrW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1411 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1413 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1416 else if (wParam
== VK_SNAPSHOT
)
1419 while (GetParent(hwnd
) != NULL
)
1421 hwnd
= GetParent(hwnd
);
1423 DefWndScreenshot(hwnd
);
1426 else if( wParam
== VK_F10
)
1428 else if( wParam
== VK_ESCAPE
&& (GetKeyState(VK_SHIFT
) & 0x8000))
1429 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, ' ' );
1436 /* Press and release F10 or ALT */
1437 if (((wParam
== VK_MENU
|| wParam
== VK_LMENU
|| wParam
== VK_RMENU
)
1438 && iMenuSysKey
) || ((wParam
== VK_F10
) && iF10Key
))
1439 SendMessageW( GetAncestor( hWnd
, GA_ROOT
), WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1440 iMenuSysKey
= iF10Key
= 0;
1447 if (wParam
== '\r' && IsIconic(hWnd
))
1449 PostMessageW( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0L );
1452 if ((HIWORD(lParam
) & KEYDATA_ALT
) && wParam
)
1454 if (wParam
== '\t' || wParam
== '\x1b') break;
1455 if (wParam
== ' ' && (GetWindowLongPtrW( hWnd
, GWL_STYLE
) & WS_CHILD
))
1456 SendMessageW( GetParent(hWnd
), Msg
, wParam
, lParam
);
1458 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, wParam
);
1460 else /* check for Ctrl-Esc */
1461 if (wParam
!= '\x1b') MessageBeep(0);
1467 if (lParam
) // Call when it is necessary.
1468 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, 0, FNID_DEFWINDOWPROC
, FALSE
);
1472 case WM_CLIENTSHUTDOWN
:
1475 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
1482 /* FIXME: Check for a desktop. */
1483 if (!(GetWindowLongPtrW( hWnd
, GWL_STYLE
) & WS_CHILD
)) EndMenu();
1484 if (GetCapture() == hWnd
)
1498 case WM_QUERYDROPOBJECT
:
1500 if (GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1507 case WM_QUERYDRAGICON
:
1512 hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
);
1515 return ((LRESULT
)hIcon
);
1517 for (Len
= 1; Len
< 64; Len
++)
1519 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1521 return((LRESULT
)hIcon
);
1524 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1527 case WM_ISACTIVEICON
:
1531 pWnd
= ValidateHwnd(hWnd
);
1532 if (!pWnd
) return 0;
1533 isai
= (pWnd
->state
& WNDS_ACTIVEFRAME
) != 0;
1537 case WM_NOTIFYFORMAT
:
1539 if (lParam
== NF_QUERY
)
1540 return IsWindowUnicode(hWnd
) ? NFR_UNICODE
: NFR_ANSI
;
1546 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1547 HICON hOldIcon
= (HICON
)GetClassLongPtrW(hWnd
, Index
);
1548 SetClassLongPtrW(hWnd
, Index
, lParam
);
1549 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1550 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1551 SWP_NOACTIVATE
| SWP_NOZORDER
);
1552 return ((LRESULT
)hOldIcon
);
1557 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1558 return (GetClassLongPtrW(hWnd
, Index
));
1565 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1569 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1576 THRDCARETINFO CaretInfo
;
1579 case 0xffff: /* Caret timer */
1580 /* switch showing byte in win32k and get information about the caret */
1581 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1583 DrawCaret(hWnd
, &CaretInfo
);
1591 case WM_QUERYENDSESSION
:
1596 case WM_INPUTLANGCHANGEREQUEST
:
1600 if(wParam
& INPUTLANGCHANGE_BACKWARD
1601 && wParam
& INPUTLANGCHANGE_FORWARD
)
1606 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1608 if(wParam
& INPUTLANGCHANGE_BACKWARD
) NewHkl
= (HKL
) HKL_PREV
;
1609 else if(wParam
& INPUTLANGCHANGE_FORWARD
) NewHkl
= (HKL
) HKL_NEXT
;
1610 else NewHkl
= (HKL
) lParam
;
1612 NtUserActivateKeyboardLayout(NewHkl
, 0);
1617 case WM_INPUTLANGCHANGE
:
1620 HWND
*win_array
= WIN_ListChildren( hWnd
);
1624 while (win_array
[count
])
1625 SendMessageW( win_array
[count
++], WM_INPUTLANGCHANGE
, wParam
, lParam
);
1626 HeapFree(GetProcessHeap(),0,win_array
);
1630 case WM_QUERYUISTATE
:
1633 PWND Wnd
= ValidateHwnd(hWnd
);
1637 Ret
|= UISF_HIDEFOCUS
;
1639 Ret
|= UISF_HIDEACCEL
;
1644 case WM_CHANGEUISTATE
:
1646 BOOL AlwaysShowCues
= FALSE
;
1647 WORD Action
= LOWORD(wParam
);
1648 WORD Flags
= HIWORD(wParam
);
1651 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1655 Wnd
= ValidateHwnd(hWnd
);
1656 if (!Wnd
|| lParam
!= 0)
1659 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1662 if (Flags
& UISF_ACTIVE
)
1664 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1667 if (Action
== UIS_INITIALIZE
)
1669 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1673 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1674 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1676 /* We need to update wParam in case we need to send out messages */
1677 wParam
= MAKEWPARAM(Action
, Flags
);
1683 /* See if we actually need to change something */
1684 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1686 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1689 /* Don't need to do anything... */
1693 /* See if we actually need to change something */
1694 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1696 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1699 /* Don't need to do anything... */
1703 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1707 if ((Wnd
->style
& WS_CHILD
) && Wnd
->spwndParent
!= NULL
)
1709 /* We're a child window and we need to pass this message down until
1710 we reach the root */
1711 hWnd
= UserHMGetHandle((PWND
)DesktopPtrToUser(Wnd
->spwndParent
));
1715 /* We're a top level window, we need to change the UI state */
1716 Msg
= WM_UPDATEUISTATE
;
1720 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1722 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1725 case WM_UPDATEUISTATE
:
1728 BOOL AlwaysShowCues
= FALSE
;
1729 WORD Action
= LOWORD(wParam
);
1730 WORD Flags
= HIWORD(wParam
);
1733 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1737 Wnd
= ValidateHwnd(hWnd
);
1738 if (!Wnd
|| lParam
!= 0)
1741 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1744 if (Flags
& UISF_ACTIVE
)
1746 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1749 if (Action
== UIS_INITIALIZE
)
1751 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1755 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1756 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1758 /* We need to update wParam for broadcasting the update */
1759 wParam
= MAKEWPARAM(Action
, Flags
);
1765 /* See if we actually need to change something */
1766 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1768 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1771 /* Don't need to do anything... */
1776 /* See if we actually need to change something */
1777 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1779 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1782 /* Don't need to do anything... */
1787 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1791 /* Pack the information and call win32k */
1794 if (!NtUserCallTwoParam((DWORD_PTR
)hWnd
, (DWORD_PTR
)Flags
| ((DWORD_PTR
)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE
))
1798 /* Always broadcast the update to all children */
1799 EnumChildWindows(hWnd
,
1800 UserSendUiUpdateMsg
,
1812 * helpers for calling IMM32 (from Wine 10/22/2008)
1814 * WM_IME_* messages are generated only by IMM32,
1815 * so I assume imm32 is already LoadLibrary-ed.
1818 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1820 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1821 HWND (WINAPI
*pFunc
)(HWND
);
1826 ERR("cannot get IMM32 handle\n");
1830 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1832 hwndRet
= (*pFunc
)(hwnd
);
1839 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1841 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1842 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1847 ERR("cannot get IMM32 handle\n");
1851 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1853 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1860 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1862 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1863 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1868 ERR("cannot get IMM32 handle\n");
1872 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1874 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1881 RealDefWindowProcA(HWND hWnd
,
1889 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1896 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1897 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1898 * may have child window IDs instead of window name */
1899 if (HIWORD(cs
->lpszName
))
1901 DefSetText(hWnd
, (PCWSTR
)cs
->lpszName
, TRUE
);
1908 case WM_GETTEXTLENGTH
:
1913 Wnd
= ValidateHwnd(hWnd
);
1914 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
1916 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1918 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1920 Wnd
->strName
.Length
)))
1922 Result
= (LRESULT
) len
;
1933 PSTR outbuf
= (PSTR
)lParam
;
1936 Wnd
= ValidateHwnd(hWnd
);
1937 if (Wnd
!= NULL
&& wParam
!= 0)
1939 if (Wnd
->strName
.Buffer
!= NULL
)
1940 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1946 if (Wnd
->strName
.Length
!= 0)
1948 copy
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1949 Result
= WideCharToMultiByte(CP_ACP
,
1957 outbuf
[Result
] = '\0';
1968 DefSetText(hWnd
, (PCWSTR
)lParam
, TRUE
);
1970 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1972 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1979 case WM_IME_KEYDOWN
:
1981 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
1987 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
1994 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
1995 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
1999 case WM_IME_STARTCOMPOSITION
:
2000 case WM_IME_COMPOSITION
:
2001 case WM_IME_ENDCOMPOSITION
:
2007 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2009 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
2013 case WM_IME_SETCONTEXT
:
2017 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2019 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
2025 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2028 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2034 RealDefWindowProcW(HWND hWnd
,
2042 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
2049 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
2050 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2051 * may have child window IDs instead of window name */
2053 if (HIWORD(cs
->lpszName
))
2055 DefSetText(hWnd
, cs
->lpszName
, FALSE
);
2062 case WM_GETTEXTLENGTH
:
2067 Wnd
= ValidateHwnd(hWnd
);
2068 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
2070 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2072 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
2074 Wnd
->strName
.Length
)))
2076 Result
= (LRESULT
) (Wnd
->strName
.Length
/ sizeof(WCHAR
));
2087 PWSTR outbuf
= (PWSTR
)lParam
;
2089 Wnd
= ValidateHwnd(hWnd
);
2090 if (Wnd
!= NULL
&& wParam
!= 0)
2092 if (Wnd
->strName
.Buffer
!= NULL
)
2093 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2099 if (Wnd
->strName
.Length
!= 0)
2101 Result
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
2102 RtlCopyMemory(outbuf
,
2104 Result
* sizeof(WCHAR
));
2105 outbuf
[Result
] = L
'\0';
2116 DefSetText(hWnd
, (PCWSTR
)lParam
, FALSE
);
2118 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2120 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
2128 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
2133 case WM_IME_KEYDOWN
:
2135 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2141 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
2145 case WM_IME_STARTCOMPOSITION
:
2146 case WM_IME_COMPOSITION
:
2147 case WM_IME_ENDCOMPOSITION
:
2153 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2155 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
2159 case WM_IME_SETCONTEXT
:
2163 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2165 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
2170 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
2172 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2178 DefWindowProcA(HWND hWnd
,
2183 BOOL Hook
, msgOverride
= FALSE
;
2188 Hook
= BeginIfHookedUserApiHook();
2190 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2192 /* Bypass SEH and go direct. */
2193 if (!Hook
|| !msgOverride
)
2194 return RealDefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2198 Result
= guah
.DefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2200 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2211 DefWindowProcW(HWND hWnd
,
2216 BOOL Hook
, msgOverride
= FALSE
;
2221 Hook
= BeginIfHookedUserApiHook();
2223 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2225 /* Bypass SEH and go direct. */
2226 if (!Hook
|| !msgOverride
)
2227 return RealDefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2231 Result
= guah
.DefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2233 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)