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;
760 // if (ISITHOOKED(WH_CBT))
763 NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
764 if (lResult
) return 0;
767 switch (wParam
& 0xfff0)
771 DefWndDoSizeMove(hWnd
, wParam
);
774 wp
.length
= sizeof(WINDOWPLACEMENT
);
775 if(GetWindowPlacement(hWnd
, &wp
))
777 wp
.showCmd
= SW_MINIMIZE
;
778 SetWindowPlacement(hWnd
, &wp
);
782 wp
.length
= sizeof(WINDOWPLACEMENT
);
783 if(GetWindowPlacement(hWnd
, &wp
))
785 wp
.showCmd
= SW_MAXIMIZE
;
786 SetWindowPlacement(hWnd
, &wp
);
790 wp
.length
= sizeof(WINDOWPLACEMENT
);
791 if(GetWindowPlacement(hWnd
, &wp
))
793 wp
.showCmd
= SW_RESTORE
;
794 SetWindowPlacement(hWnd
, &wp
);
798 return SendMessageW(hWnd
, WM_CLOSE
, 0, 0);
802 Pt
.x
= (short)LOWORD(lParam
);
803 Pt
.y
= (short)HIWORD(lParam
);
804 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
808 MenuTrackKbdMenuBar(hWnd
, wParam
, (WCHAR
)lParam
);
813 Pt
.x
= (short)LOWORD(lParam
);
814 Pt
.y
= (short)HIWORD(lParam
);
815 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
820 /* FIXME: Implement */
829 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
831 POINT maxTrack
, minTrack
;
832 LONG style
= GetWindowLongPtrA(hWnd
, GWL_STYLE
);
834 if (Pos
->flags
& SWP_NOSIZE
) return 0;
835 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
837 WinPosGetMinMaxInfo(hWnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
838 Pos
->cx
= min(Pos
->cx
, maxTrack
.x
);
839 Pos
->cy
= min(Pos
->cy
, maxTrack
.y
);
840 if (!(style
& WS_MINIMIZE
))
842 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
843 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
848 Pos
->cx
= max(Pos
->cx
, 0);
849 Pos
->cy
= max(Pos
->cy
, 0);
854 /* Undocumented flags. */
855 #define SWP_NOCLIENTMOVE 0x0800
856 #define SWP_NOCLIENTSIZE 0x1000
859 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
863 GetClientRect(hWnd
, &Rect
);
864 MapWindowPoints(hWnd
, (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
?
865 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
867 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
869 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
872 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
874 WPARAM wp
= SIZE_RESTORED
;
879 else if (IsIconic(hWnd
))
883 SendMessageW(hWnd
, WM_SIZE
, wp
,
884 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
890 /***********************************************************************
893 * Default colors for control painting.
896 DefWndControlColor(HDC hDC
, UINT ctlType
)
898 if (CTLCOLOR_SCROLLBAR
== ctlType
)
900 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
901 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
902 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
905 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
906 * we better use 0x55aa bitmap brush to make scrollbar's background
907 * look different from the window background.
909 if (bk
== GetSysColor(COLOR_WINDOW
))
911 static const WORD wPattern55AA
[] =
913 0x5555, 0xaaaa, 0x5555, 0xaaaa,
914 0x5555, 0xaaaa, 0x5555, 0xaaaa
916 static HBITMAP hPattern55AABitmap
= NULL
;
917 static HBRUSH hPattern55AABrush
= NULL
;
918 if (hPattern55AABrush
== NULL
)
920 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
921 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
923 return hPattern55AABrush
;
929 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
931 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
933 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
937 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
938 return GetSysColorBrush(COLOR_3DFACE
);
941 return GetSysColorBrush(COLOR_WINDOW
);
944 static void DefWndPrint( HWND hwnd
, HDC hdc
, ULONG uFlags
)
949 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
950 !IsWindowVisible(hwnd
) )
954 * Unimplemented flags.
956 if ( (uFlags
& PRF_CHILDREN
) ||
957 (uFlags
& PRF_OWNED
) ||
958 (uFlags
& PRF_NONCLIENT
) )
960 FIXME("WM_PRINT message with unsupported flags\n");
966 if ( uFlags
& PRF_ERASEBKGND
)
967 SendMessageW(hwnd
, WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
972 if ( uFlags
& PRF_CLIENT
)
973 SendMessageW(hwnd
, WM_PRINTCLIENT
, (WPARAM
)hdc
, uFlags
);
977 UserSendUiUpdateMsg(HWND hwnd
, LPARAM lParam
)
979 SendMessageW(hwnd
, WM_UPDATEUISTATE
, (WPARAM
)lParam
, 0);
985 DefWndScreenshot(HWND hWnd
)
997 hdc
= GetWindowDC(hWnd
);
998 GetWindowRect(hWnd
, &rect
);
999 w
= rect
.right
- rect
.left
;
1000 h
= rect
.bottom
- rect
.top
;
1002 hbitmap
= CreateCompatibleBitmap(hdc
, w
, h
);
1003 hdc2
= CreateCompatibleDC(hdc
);
1004 SelectObject(hdc2
, hbitmap
);
1006 BitBlt(hdc2
, 0, 0, w
, h
,
1010 SetClipboardData(CF_BITMAP
, hbitmap
);
1012 ReleaseDC(hWnd
, hdc
);
1013 ReleaseDC(hWnd
, hdc2
);
1022 User32DefWindowProc(HWND hWnd
,
1032 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
1037 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
1040 case WM_POPUPSYSTEMMENU
:
1042 /* This is an undocumented message used by the windows taskbar to
1043 display the system menu of windows that belong to other processes. */
1044 HMENU menu
= GetSystemMenu(hWnd
, FALSE
);
1047 TrackPopupMenu(menu
, TPM_LEFTBUTTON
|TPM_RIGHTBUTTON
,
1048 LOWORD(lParam
), HIWORD(lParam
), 0, hWnd
, NULL
);
1054 return DefWndNCActivate(hWnd
, wParam
);
1060 Point
.x
= GET_X_LPARAM(lParam
);
1061 Point
.y
= GET_Y_LPARAM(lParam
);
1062 return (DefWndNCHitTest(hWnd
, Point
));
1065 case WM_LBUTTONDOWN
:
1066 case WM_RBUTTONDOWN
:
1067 case WM_MBUTTONDOWN
:
1068 iF10Key
= iMenuSysKey
= 0;
1071 case WM_NCLBUTTONDOWN
:
1073 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
1076 case WM_LBUTTONDBLCLK
:
1077 return (DefWndNCLButtonDblClk(hWnd
, HTCLIENT
, lParam
));
1079 case WM_NCLBUTTONDBLCLK
:
1081 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
1084 case WM_WINDOWPOSCHANGING
:
1086 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1089 case WM_WINDOWPOSCHANGED
:
1091 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
1094 case WM_NCRBUTTONDOWN
:
1096 /* in Windows, capture is taken when right-clicking on the caption bar */
1097 if (wParam
== HTCAPTION
)
1107 if (hWnd
== GetCapture())
1111 Pt
.x
= GET_X_LPARAM(lParam
);
1112 Pt
.y
= GET_Y_LPARAM(lParam
);
1113 ClientToScreen(hWnd
, &Pt
);
1114 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1117 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1121 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1126 case WM_NCRBUTTONUP
:
1128 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1129 * in Windows), but what _should_ we do? According to MSDN :
1130 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1131 * message to the window". When is it appropriate?
1135 case WM_CONTEXTMENU
:
1137 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1141 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1145 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1154 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1156 Pt
.x
= GET_X_LPARAM(lParam
);
1157 Pt
.y
= GET_Y_LPARAM(lParam
);
1158 if (Style
& WS_CHILD
)
1160 ScreenToClient(GetParent(hWnd
), &Pt
);
1163 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1165 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1170 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1172 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongPtrW(hWnd
, GWL_STYLE
),
1173 GetClassLongPtrW(hWnd
, GCL_STYLE
), HitCode
);
1175 if(HitCode
== HTCAPTION
)
1176 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1178 Flags
= TPM_LEFTBUTTON
;
1180 TrackPopupMenu(SystemMenu
, Flags
,
1181 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1190 DefWndPrint(hWnd
, (HDC
)wParam
, lParam
);
1194 case WM_SYSCOLORCHANGE
:
1196 /* force to redraw non-client area */
1197 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1198 /* Use InvalidateRect to redraw client area, enable
1199 * erase to redraw all subcontrols otherwise send the
1200 * WM_SYSCOLORCHANGE to child windows/controls is required
1202 InvalidateRect(hWnd
,NULL
,TRUE
);
1210 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1215 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1216 (hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
)) != NULL
)
1220 GetClientRect(hWnd
, &ClientRect
);
1221 x
= (ClientRect
.right
- ClientRect
.left
-
1222 GetSystemMetrics(SM_CXICON
)) / 2;
1223 y
= (ClientRect
.bottom
- ClientRect
.top
-
1224 GetSystemMetrics(SM_CYICON
)) / 2;
1225 DrawIcon(hDC
, x
, y
, hIcon
);
1227 EndPaint(hWnd
, &Ps
);
1235 hRgn
= CreateRectRgn(0, 0, 0, 0);
1236 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1238 RedrawWindow(hWnd
, NULL
, hRgn
,
1239 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1248 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1249 if (wParam
) SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
| WS_VISIBLE
);
1252 RedrawWindow(hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
1253 Style
&= ~WS_VISIBLE
;
1254 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
);
1261 DestroyWindow(hWnd
);
1265 case WM_MOUSEACTIVATE
:
1267 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1272 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1277 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1285 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1290 /* Check if the window is minimized. */
1291 if (LOWORD(wParam
) != WA_INACTIVE
&&
1292 !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1301 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1305 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1310 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1318 case WM_ICONERASEBKGND
:
1321 HBRUSH hBrush
= (HBRUSH
)GetClassLongPtrW(hWnd
, GCL_HBRBACKGROUND
);
1327 if (GetClassLongPtrW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1329 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1330 GetClientRect(hWnd
, &Rect
);
1331 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1335 GetClipBox((HDC
)wParam
, &Rect
);
1337 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1341 case WM_CTLCOLORMSGBOX
:
1342 case WM_CTLCOLOREDIT
:
1343 case WM_CTLCOLORLISTBOX
:
1344 case WM_CTLCOLORBTN
:
1345 case WM_CTLCOLORDLG
:
1346 case WM_CTLCOLORSTATIC
:
1347 case WM_CTLCOLORSCROLLBAR
:
1348 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1351 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
1355 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1357 if (Style
& WS_CHILD
)
1359 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1364 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1369 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1378 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1382 return (DefWndHandleSysCommand(hWnd
, wParam
, lParam
));
1385 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
1388 /* FIXME: This is also incomplete. */
1391 if (HIWORD(lParam
) & KEYDATA_ALT
)
1393 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1394 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
1395 if ( (wParam
== VK_MENU
|| wParam
== VK_LMENU
1396 || wParam
== VK_RMENU
) && !iMenuSysKey
)
1399 /* mimic behaviour of XP, sending a WM_SYSCOMMAND when pressing <alt> */
1400 SendMessageW( top
, WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1407 if (wParam
== VK_F4
) /* Try to close the window */
1409 if (!(GetClassLongPtrW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1412 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1414 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1417 else if (wParam
== VK_SNAPSHOT
)
1420 while (GetParent(hwnd
) != NULL
)
1422 hwnd
= GetParent(hwnd
);
1424 DefWndScreenshot(hwnd
);
1427 else if( wParam
== VK_F10
)
1429 else if( wParam
== VK_ESCAPE
&& (GetKeyState(VK_SHIFT
) & 0x8000))
1430 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, ' ' );
1437 /* Press and release F10 or ALT */
1438 if (((wParam
== VK_MENU
|| wParam
== VK_LMENU
|| wParam
== VK_RMENU
)
1439 && iMenuSysKey
) || ((wParam
== VK_F10
) && iF10Key
))
1440 SendMessageW( GetAncestor( hWnd
, GA_ROOT
), WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1441 iMenuSysKey
= iF10Key
= 0;
1448 if (wParam
== '\r' && IsIconic(hWnd
))
1450 PostMessageW( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0L );
1453 if ((HIWORD(lParam
) & KEYDATA_ALT
) && wParam
)
1455 if (wParam
== '\t' || wParam
== '\x1b') break;
1456 if (wParam
== ' ' && (GetWindowLongPtrW( hWnd
, GWL_STYLE
) & WS_CHILD
))
1457 SendMessageW( GetParent(hWnd
), Msg
, wParam
, lParam
);
1459 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, wParam
);
1461 else /* check for Ctrl-Esc */
1462 if (wParam
!= '\x1b') MessageBeep(0);
1468 if (lParam
) // Call when it is necessary.
1469 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, 0, FNID_DEFWINDOWPROC
, FALSE
);
1473 case WM_CLIENTSHUTDOWN
:
1476 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
1483 /* FIXME: Check for a desktop. */
1484 if (!(GetWindowLongPtrW( hWnd
, GWL_STYLE
) & WS_CHILD
)) EndMenu();
1485 if (GetCapture() == hWnd
)
1499 case WM_QUERYDROPOBJECT
:
1501 if (GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1508 case WM_QUERYDRAGICON
:
1513 hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
);
1516 return ((LRESULT
)hIcon
);
1518 for (Len
= 1; Len
< 64; Len
++)
1520 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1522 return((LRESULT
)hIcon
);
1525 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1528 case WM_ISACTIVEICON
:
1532 pWnd
= ValidateHwnd(hWnd
);
1533 if (!pWnd
) return 0;
1534 isai
= (pWnd
->state
& WNDS_ACTIVEFRAME
) != 0;
1538 case WM_NOTIFYFORMAT
:
1540 if (lParam
== NF_QUERY
)
1541 return IsWindowUnicode(hWnd
) ? NFR_UNICODE
: NFR_ANSI
;
1547 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1548 HICON hOldIcon
= (HICON
)GetClassLongPtrW(hWnd
, Index
);
1549 SetClassLongPtrW(hWnd
, Index
, lParam
);
1550 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1551 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1552 SWP_NOACTIVATE
| SWP_NOZORDER
);
1553 return ((LRESULT
)hOldIcon
);
1558 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1559 return (GetClassLongPtrW(hWnd
, Index
));
1566 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1570 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1577 THRDCARETINFO CaretInfo
;
1580 case 0xffff: /* Caret timer */
1581 /* switch showing byte in win32k and get information about the caret */
1582 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1584 DrawCaret(hWnd
, &CaretInfo
);
1592 case WM_QUERYENDSESSION
:
1597 case WM_INPUTLANGCHANGEREQUEST
:
1601 if(wParam
& INPUTLANGCHANGE_BACKWARD
1602 && wParam
& INPUTLANGCHANGE_FORWARD
)
1607 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1609 if(wParam
& INPUTLANGCHANGE_BACKWARD
) NewHkl
= (HKL
) HKL_PREV
;
1610 else if(wParam
& INPUTLANGCHANGE_FORWARD
) NewHkl
= (HKL
) HKL_NEXT
;
1611 else NewHkl
= (HKL
) lParam
;
1613 NtUserActivateKeyboardLayout(NewHkl
, 0);
1618 case WM_INPUTLANGCHANGE
:
1621 HWND
*win_array
= WIN_ListChildren( hWnd
);
1625 while (win_array
[count
])
1626 SendMessageW( win_array
[count
++], WM_INPUTLANGCHANGE
, wParam
, lParam
);
1627 HeapFree(GetProcessHeap(),0,win_array
);
1631 case WM_QUERYUISTATE
:
1634 PWND Wnd
= ValidateHwnd(hWnd
);
1638 Ret
|= UISF_HIDEFOCUS
;
1640 Ret
|= UISF_HIDEACCEL
;
1645 case WM_CHANGEUISTATE
:
1647 BOOL AlwaysShowCues
= FALSE
;
1648 WORD Action
= LOWORD(wParam
);
1649 WORD Flags
= HIWORD(wParam
);
1652 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1656 Wnd
= ValidateHwnd(hWnd
);
1657 if (!Wnd
|| lParam
!= 0)
1660 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1663 if (Flags
& UISF_ACTIVE
)
1665 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1668 if (Action
== UIS_INITIALIZE
)
1670 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1674 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1675 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1677 /* We need to update wParam in case we need to send out messages */
1678 wParam
= MAKEWPARAM(Action
, Flags
);
1684 /* See if we actually need to change something */
1685 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1687 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1690 /* Don't need to do anything... */
1694 /* See if we actually need to change something */
1695 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1697 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1700 /* Don't need to do anything... */
1704 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1708 if ((Wnd
->style
& WS_CHILD
) && Wnd
->spwndParent
!= NULL
)
1710 /* We're a child window and we need to pass this message down until
1711 we reach the root */
1712 hWnd
= UserHMGetHandle((PWND
)DesktopPtrToUser(Wnd
->spwndParent
));
1716 /* We're a top level window, we need to change the UI state */
1717 Msg
= WM_UPDATEUISTATE
;
1721 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1723 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1726 case WM_UPDATEUISTATE
:
1729 BOOL AlwaysShowCues
= FALSE
;
1730 WORD Action
= LOWORD(wParam
);
1731 WORD Flags
= HIWORD(wParam
);
1734 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1738 Wnd
= ValidateHwnd(hWnd
);
1739 if (!Wnd
|| lParam
!= 0)
1742 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1745 if (Flags
& UISF_ACTIVE
)
1747 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1750 if (Action
== UIS_INITIALIZE
)
1752 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1756 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1757 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1759 /* We need to update wParam for broadcasting the update */
1760 wParam
= MAKEWPARAM(Action
, Flags
);
1766 /* See if we actually need to change something */
1767 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1769 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1772 /* Don't need to do anything... */
1777 /* See if we actually need to change something */
1778 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1780 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1783 /* Don't need to do anything... */
1788 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1792 /* Pack the information and call win32k */
1795 if (!NtUserCallTwoParam((DWORD
)hWnd
, (DWORD
)Flags
| ((DWORD
)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE
))
1799 /* Always broadcast the update to all children */
1800 EnumChildWindows(hWnd
,
1801 UserSendUiUpdateMsg
,
1813 * helpers for calling IMM32 (from Wine 10/22/2008)
1815 * WM_IME_* messages are generated only by IMM32,
1816 * so I assume imm32 is already LoadLibrary-ed.
1819 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1821 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1822 HWND (WINAPI
*pFunc
)(HWND
);
1827 ERR("cannot get IMM32 handle\n");
1831 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1833 hwndRet
= (*pFunc
)(hwnd
);
1840 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1842 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1843 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1848 ERR("cannot get IMM32 handle\n");
1852 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1854 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1861 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1863 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1864 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1869 ERR("cannot get IMM32 handle\n");
1873 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1875 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1882 RealDefWindowProcA(HWND hWnd
,
1890 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1897 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1898 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1899 * may have child window IDs instead of window name */
1900 if (HIWORD(cs
->lpszName
))
1902 DefSetText(hWnd
, (PCWSTR
)cs
->lpszName
, TRUE
);
1909 case WM_GETTEXTLENGTH
:
1914 Wnd
= ValidateHwnd(hWnd
);
1915 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
1917 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1919 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1921 Wnd
->strName
.Length
)))
1923 Result
= (LRESULT
) len
;
1934 PSTR outbuf
= (PSTR
)lParam
;
1937 Wnd
= ValidateHwnd(hWnd
);
1938 if (Wnd
!= NULL
&& wParam
!= 0)
1940 if (Wnd
->strName
.Buffer
!= NULL
)
1941 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1947 if (Wnd
->strName
.Length
!= 0)
1949 copy
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1950 Result
= WideCharToMultiByte(CP_ACP
,
1958 outbuf
[Result
] = '\0';
1969 DefSetText(hWnd
, (PCWSTR
)lParam
, TRUE
);
1971 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1973 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1980 case WM_IME_KEYDOWN
:
1982 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
1988 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
1995 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
1996 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
2000 case WM_IME_STARTCOMPOSITION
:
2001 case WM_IME_COMPOSITION
:
2002 case WM_IME_ENDCOMPOSITION
:
2008 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2010 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
2014 case WM_IME_SETCONTEXT
:
2018 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2020 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
2026 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2029 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2035 RealDefWindowProcW(HWND hWnd
,
2043 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
2050 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
2051 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2052 * may have child window IDs instead of window name */
2054 if (HIWORD(cs
->lpszName
))
2056 DefSetText(hWnd
, cs
->lpszName
, FALSE
);
2063 case WM_GETTEXTLENGTH
:
2068 Wnd
= ValidateHwnd(hWnd
);
2069 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
2071 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2073 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
2075 Wnd
->strName
.Length
)))
2077 Result
= (LRESULT
) (Wnd
->strName
.Length
/ sizeof(WCHAR
));
2088 PWSTR outbuf
= (PWSTR
)lParam
;
2090 Wnd
= ValidateHwnd(hWnd
);
2091 if (Wnd
!= NULL
&& wParam
!= 0)
2093 if (Wnd
->strName
.Buffer
!= NULL
)
2094 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2100 if (Wnd
->strName
.Length
!= 0)
2102 Result
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
2103 RtlCopyMemory(outbuf
,
2105 Result
* sizeof(WCHAR
));
2106 outbuf
[Result
] = L
'\0';
2117 DefSetText(hWnd
, (PCWSTR
)lParam
, FALSE
);
2119 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2121 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
2129 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
2134 case WM_IME_KEYDOWN
:
2136 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2142 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
2146 case WM_IME_STARTCOMPOSITION
:
2147 case WM_IME_COMPOSITION
:
2148 case WM_IME_ENDCOMPOSITION
:
2154 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2156 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
2160 case WM_IME_SETCONTEXT
:
2164 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2166 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
2171 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
2173 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2179 DefWindowProcA(HWND hWnd
,
2184 BOOL Hook
, msgOverride
;
2189 Hook
= BeginIfHookedUserApiHook();
2191 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2193 /* Bypass SEH and go direct. */
2194 if (!Hook
|| !msgOverride
)
2195 return RealDefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2199 Result
= guah
.DefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2201 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2212 DefWindowProcW(HWND hWnd
,
2217 BOOL Hook
, msgOverride
;
2222 Hook
= BeginIfHookedUserApiHook();
2224 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2226 /* Bypass SEH and go direct. */
2227 if (!Hook
|| !msgOverride
)
2228 return RealDefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2232 Result
= guah
.DefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2234 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)