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 g_psi
->SysColors
[nIndex
];
69 SetLastError(ERROR_INVALID_PARAMETER
);
77 GetSysColorPen(int nIndex
)
79 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
81 return g_psi
->SysColorPens
[nIndex
];
84 SetLastError(ERROR_INVALID_PARAMETER
);
92 GetSysColorBrush(int nIndex
)
94 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
96 return g_psi
->SysColorBrushes
[nIndex
];
99 SetLastError(ERROR_INVALID_PARAMETER
);
110 CONST INT
*lpaElements
,
111 CONST COLORREF
*lpaRgbValues
)
113 return NtUserSetSysColors(cElements
, lpaElements
, lpaRgbValues
, 0);
118 DefSetText(HWND hWnd
, PCWSTR String
, BOOL Ansi
)
120 LARGE_STRING lsString
;
125 RtlInitLargeAnsiString((PLARGE_ANSI_STRING
)&lsString
, (PCSZ
)String
, 0);
127 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING
)&lsString
, String
, 0);
129 return NtUserDefSetText(hWnd
, (String
? &lsString
: NULL
));
133 UserGetInsideRectNC(PWINDOW Wnd
, RECT
*rect
)
139 ExStyle
= Wnd
->ExStyle
;
141 rect
->top
= rect
->left
= 0;
142 rect
->right
= Wnd
->WindowRect
.right
- Wnd
->WindowRect
.left
;
143 rect
->bottom
= Wnd
->WindowRect
.bottom
- Wnd
->WindowRect
.top
;
145 if (Style
& WS_ICONIC
)
150 /* Remove frame from rectangle */
151 if (UserHasThickFrameStyle(Style
, ExStyle
))
153 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
154 -GetSystemMetrics(SM_CYFRAME
));
158 if (UserHasDlgFrameStyle(Style
, ExStyle
))
160 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
161 -GetSystemMetrics(SM_CYDLGFRAME
));
162 /* FIXME: this isn't in NC_AdjustRect? why not? */
163 if (ExStyle
& WS_EX_DLGMODALFRAME
)
164 InflateRect( rect
, -1, 0 );
168 if (UserHasThinFrameStyle(Style
, ExStyle
))
170 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
171 -GetSystemMetrics(SM_CYBORDER
));
179 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
181 LONG Style
= GetWindowLong(hWnd
, GWL_STYLE
);
182 /* Content can be redrawn after a change. */
185 if (!(Style
& WS_VISIBLE
)) /* Not Visible */
187 SetWindowLong(hWnd
, GWL_STYLE
, WS_VISIBLE
);
190 else /* Content cannot be redrawn after a change. */
192 if (Style
& WS_VISIBLE
) /* Visible */
194 RedrawWindow( hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
195 Style
&= ~WS_VISIBLE
;
196 SetWindowLong(hWnd
, GWL_STYLE
, Style
); /* clear bits */
204 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
206 /* Not for child windows. */
207 if (hWnd
!= (HWND
)wParam
)
212 switch((INT_PTR
) LOWORD(lParam
))
216 WORD Msg
= HIWORD(lParam
);
217 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
218 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
227 HICON hCursor
= (HICON
)GetClassLongW(hWnd
, GCL_HCURSOR
);
239 if (Style
& WS_MAXIMIZE
)
243 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
249 if (Style
& WS_MAXIMIZE
)
253 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
259 if (Style
& WS_MAXIMIZE
)
263 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
269 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
273 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
276 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
280 DefWndStartSizeMove(HWND hWnd
, PWINDOW Wnd
, WPARAM wParam
, POINT
*capturePoint
)
286 ULONG Style
= Wnd
->Style
;
288 rectWindow
= Wnd
->WindowRect
;
290 if ((wParam
& 0xfff0) == SC_MOVE
)
292 /* Move pointer at the center of the caption */
294 UserGetInsideRectNC(Wnd
, &rect
);
295 if (Style
& WS_SYSMENU
)
296 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
297 if (Style
& WS_MINIMIZEBOX
)
298 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
299 if (Style
& WS_MAXIMIZEBOX
)
300 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
301 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
302 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
311 if (GetMessageW(&msg
, NULL
, 0, 0) <= 0)
316 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
317 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
329 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
330 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
334 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
335 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
339 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
340 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
344 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
345 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
348 case VK_ESCAPE
: return 0;
354 SetCursorPos( pt
.x
, pt
.y
);
355 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
359 #define ON_LEFT_BORDER(hit) \
360 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
361 #define ON_RIGHT_BORDER(hit) \
362 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
363 #define ON_TOP_BORDER(hit) \
364 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
365 #define ON_BOTTOM_BORDER(hit) \
366 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
369 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
370 ULONG width
, ULONG height
)
372 static HBRUSH hDraggingRectBrush
= NULL
;
375 if(!hDraggingRectBrush
)
377 static HBITMAP hDraggingPattern
= NULL
;
378 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
380 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
381 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
384 hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
385 PatBlt( hdc
, rect
->left
, rect
->top
,
386 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
387 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
388 rect
->bottom
- rect
->top
- height
, PATINVERT
);
389 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
390 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
391 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
392 rect
->bottom
- rect
->top
- height
, PATINVERT
);
393 SelectObject( hdc
, hbrush
);
397 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
401 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
));
405 UserDrawWindowFrame(hdc
, rect
, 1, 1);
410 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
414 RECT sizingRect
, mouseRect
, origRect
, clipRect
, unmodRect
;
416 LONG hittest
= (LONG
)(wParam
& 0x0f);
417 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
418 POINT minTrack
, maxTrack
;
419 POINT capturePoint
, pt
;
420 ULONG Style
, ExStyle
;
424 DWORD dwPoint
= GetMessagePos();
425 BOOL DragFullWindows
= FALSE
;
426 HWND hWndParent
= NULL
;
429 Wnd
= ValidateHwnd(hwnd
);
434 ExStyle
= Wnd
->ExStyle
;
435 iconic
= (Style
& WS_MINIMIZE
) != 0;
437 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
439 pt
.x
= GET_X_LPARAM(dwPoint
);
440 pt
.y
= GET_Y_LPARAM(dwPoint
);
443 if ((Style
& WS_MAXIMIZE
) || !IsWindowVisible(hwnd
))
448 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
449 if ((wParam
& 0xfff0) == SC_MOVE
)
453 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
466 if (hittest
&& ((wParam
& 0xfff0) != SC_MOUSEMENU
))
468 hittest
+= (HTLEFT
- WMSZ_LEFT
);
473 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
482 /* Get min/max info */
484 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
485 sizingRect
= Wnd
->WindowRect
;
486 if (Style
& WS_CHILD
)
488 hWndParent
= GetParent(hwnd
);
489 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
490 unmodRect
= sizingRect
;
491 GetClientRect(hWndParent
, &mouseRect
);
492 clipRect
= mouseRect
;
493 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
497 if(!(ExStyle
& WS_EX_TOPMOST
))
499 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
500 mouseRect
= clipRect
;
504 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
505 clipRect
= mouseRect
;
507 unmodRect
= sizingRect
;
509 ClipCursor(&clipRect
);
511 origRect
= sizingRect
;
512 if (ON_LEFT_BORDER(hittest
))
514 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
515 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
517 else if (ON_RIGHT_BORDER(hittest
))
519 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
520 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
522 if (ON_TOP_BORDER(hittest
))
524 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
525 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
527 else if (ON_BOTTOM_BORDER(hittest
))
529 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
530 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
532 if (Style
& WS_CHILD
)
534 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
537 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
538 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
539 if (GetCapture() != hwnd
) SetCapture( hwnd
);
541 if (Style
& WS_CHILD
)
543 /* Retrieve a default cache DC (without using the window style) */
544 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
550 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
553 SelectObject(hdc
, DesktopRgn
);
555 if( iconic
) /* create a cursor for dragging */
557 HICON hIcon
= (HICON
)GetClassLongW(hwnd
, GCL_HICON
);
558 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
559 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
560 if( !hDragCursor
) iconic
= FALSE
;
563 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
564 if( !iconic
&& !DragFullWindows
)
566 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
573 if (GetMessageW(&msg
, 0, 0, 0) <= 0)
576 /* Exit on button-up, Return, or Esc */
577 if ((msg
.message
== WM_LBUTTONUP
) ||
578 ((msg
.message
== WM_KEYDOWN
) &&
579 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
581 if (msg
.message
== WM_PAINT
)
583 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
584 UpdateWindow( msg
.hwnd
);
585 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
589 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
590 continue; /* We are not interested in other messages */
594 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
596 case VK_UP
: pt
.y
-= 8; break;
597 case VK_DOWN
: pt
.y
+= 8; break;
598 case VK_LEFT
: pt
.x
-= 8; break;
599 case VK_RIGHT
: pt
.x
+= 8; break;
602 pt
.x
= max( pt
.x
, mouseRect
.left
);
603 pt
.x
= min( pt
.x
, mouseRect
.right
);
604 pt
.y
= max( pt
.y
, mouseRect
.top
);
605 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
607 dx
= pt
.x
- capturePoint
.x
;
608 dy
= pt
.y
- capturePoint
.y
;
616 if( iconic
) /* ok, no system popup tracking */
618 hOldCursor
= SetCursor(hDragCursor
);
623 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
626 RECT newRect
= unmodRect
;
627 WPARAM wpSizingHit
= 0;
629 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
630 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
631 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
632 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
633 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
634 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
637 /* determine the hit location */
638 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
639 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
641 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
646 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
648 /* To avoid any deadlocks, all the locks on the windows
649 structures must be suspended before the SetWindowPos */
650 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
651 newRect
.right
- newRect
.left
,
652 newRect
.bottom
- newRect
.top
,
653 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
656 sizingRect
= newRect
;
665 if( moved
) /* restore cursors, show icon title later on */
668 SetCursor( hOldCursor
);
670 DestroyCursor( hDragCursor
);
672 else if(!DragFullWindows
)
673 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
675 if (Style
& WS_CHILD
)
676 ReleaseDC( hWndParent
, hdc
);
682 DeleteObject(DesktopRgn
);
686 if (ISITHOOKED(WH_CBT
))
688 if (NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, (LPARAM
)&sizingRect
, 0, FNID_DEFWINDOWPROC
, FALSE
))
692 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
693 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
694 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
696 /* window moved or resized */
699 /* if the moving/resizing isn't canceled call SetWindowPos
700 * with the new position or the new size of the window
702 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
704 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
706 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
707 sizingRect
.right
- sizingRect
.left
,
708 sizingRect
.bottom
- sizingRect
.top
,
709 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
711 else { /* restore previous size/position */
713 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
714 origRect
.right
- origRect
.left
,
715 origRect
.bottom
- origRect
.top
,
716 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
721 if( Style
& WS_MINIMIZE
)
723 /* Single click brings up the system menu when iconized */
727 if( Style
& WS_SYSMENU
)
728 SendMessageA( hwnd
, WM_SYSCOMMAND
,
729 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
735 /***********************************************************************
736 * DefWndTrackScrollBar
738 * Track a mouse button press on the horizontal or vertical scroll-bar.
741 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
745 if (SC_HSCROLL
== (wParam
& 0xfff0))
747 if (HTHSCROLL
!= (wParam
& 0x0f))
753 else /* SC_VSCROLL */
755 if (HTVSCROLL
!= (wParam
& 0x0f))
761 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
766 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
772 if (ISITHOOKED(WH_CBT
))
774 if (NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
, 0, FNID_DEFWINDOWPROC
, FALSE
))
778 switch (wParam
& 0xfff0)
782 DefWndDoSizeMove(hWnd
, wParam
);
785 wp
.length
= sizeof(WINDOWPLACEMENT
);
786 if(GetWindowPlacement(hWnd
, &wp
))
788 wp
.showCmd
= SW_MINIMIZE
;
789 SetWindowPlacement(hWnd
, &wp
);
793 wp
.length
= sizeof(WINDOWPLACEMENT
);
794 if(GetWindowPlacement(hWnd
, &wp
))
796 wp
.showCmd
= SW_MAXIMIZE
;
797 SetWindowPlacement(hWnd
, &wp
);
801 wp
.length
= sizeof(WINDOWPLACEMENT
);
802 if(GetWindowPlacement(hWnd
, &wp
))
804 wp
.showCmd
= SW_RESTORE
;
805 SetWindowPlacement(hWnd
, &wp
);
809 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
813 Pt
.x
= (short)LOWORD(lParam
);
814 Pt
.y
= (short)HIWORD(lParam
);
815 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
819 MenuTrackKbdMenuBar(hWnd
, wParam
, (WCHAR
)lParam
);
824 Pt
.x
= (short)LOWORD(lParam
);
825 Pt
.y
= (short)HIWORD(lParam
);
826 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
831 /* FIXME: Implement */
840 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
842 POINT maxTrack
, minTrack
;
843 LONG style
= GetWindowLongA(hWnd
, GWL_STYLE
);
845 if (Pos
->flags
& SWP_NOSIZE
) return 0;
846 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
848 WinPosGetMinMaxInfo(hWnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
849 Pos
->cx
= min(Pos
->cx
, maxTrack
.x
);
850 Pos
->cy
= min(Pos
->cy
, maxTrack
.y
);
851 if (!(style
& WS_MINIMIZE
))
853 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
854 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
859 Pos
->cx
= max(Pos
->cx
, 0);
860 Pos
->cy
= max(Pos
->cy
, 0);
865 /* Undocumented flags. */
866 #define SWP_NOCLIENTMOVE 0x0800
867 #define SWP_NOCLIENTSIZE 0x1000
870 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
874 GetClientRect(hWnd
, &Rect
);
875 MapWindowPoints(hWnd
, (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
?
876 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
878 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
880 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
883 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
885 WPARAM wp
= SIZE_RESTORED
;
890 else if (IsIconic(hWnd
))
894 SendMessageW(hWnd
, WM_SIZE
, wp
,
895 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
901 /***********************************************************************
904 * Default colors for control painting.
907 DefWndControlColor(HDC hDC
, UINT ctlType
)
909 if (CTLCOLOR_SCROLLBAR
== ctlType
)
911 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
912 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
913 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
916 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
917 * we better use 0x55aa bitmap brush to make scrollbar's background
918 * look different from the window background.
920 if (bk
== GetSysColor(COLOR_WINDOW
))
922 static const WORD wPattern55AA
[] =
924 0x5555, 0xaaaa, 0x5555, 0xaaaa,
925 0x5555, 0xaaaa, 0x5555, 0xaaaa
927 static HBITMAP hPattern55AABitmap
= NULL
;
928 static HBRUSH hPattern55AABrush
= NULL
;
929 if (hPattern55AABrush
== NULL
)
931 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
932 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
934 return hPattern55AABrush
;
940 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
942 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
944 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
948 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
949 return GetSysColorBrush(COLOR_3DFACE
);
952 return GetSysColorBrush(COLOR_WINDOW
);
955 static void DefWndPrint( HWND hwnd
, HDC hdc
, ULONG uFlags
)
960 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
961 !IsWindowVisible(hwnd
) )
965 * Unimplemented flags.
967 if ( (uFlags
& PRF_CHILDREN
) ||
968 (uFlags
& PRF_OWNED
) ||
969 (uFlags
& PRF_NONCLIENT
) )
971 FIXME("WM_PRINT message with unsupported flags\n");
977 if ( uFlags
& PRF_ERASEBKGND
)
978 SendMessageW(hwnd
, WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
983 if ( uFlags
& PRF_CLIENT
)
984 SendMessageW(hwnd
, WM_PRINTCLIENT
, (WPARAM
)hdc
, PRF_CLIENT
);
988 UserSendUiUpdateMsg(HWND hwnd
, LPARAM lParam
)
990 SendMessageW(hwnd
, WM_UPDATEUISTATE
, (WPARAM
)lParam
, 0);
996 DefWndScreenshot(HWND hWnd
)
1005 OpenClipboard(hWnd
);
1008 hdc
= GetWindowDC(hWnd
);
1009 GetWindowRect(hWnd
, &rect
);
1010 w
= rect
.right
- rect
.left
;
1011 h
= rect
.bottom
- rect
.top
;
1013 hbitmap
= CreateCompatibleBitmap(hdc
, w
, h
);
1014 hdc2
= CreateCompatibleDC(hdc
);
1015 SelectObject(hdc2
, hbitmap
);
1017 BitBlt(hdc2
, 0, 0, w
, h
,
1021 SetClipboardData(CF_BITMAP
, hbitmap
);
1023 ReleaseDC(hWnd
, hdc
);
1024 ReleaseDC(hWnd
, hdc2
);
1033 User32DefWindowProc(HWND hWnd
,
1043 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
1048 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
1051 case WM_POPUPSYSTEMMENU
:
1053 /* This is an undocumented message used by the windows taskbar to
1054 display the system menu of windows that belong to other processes. */
1055 HMENU menu
= GetSystemMenu(hWnd
, FALSE
);
1058 TrackPopupMenu(menu
, TPM_LEFTBUTTON
|TPM_RIGHTBUTTON
,
1059 LOWORD(lParam
), HIWORD(lParam
), 0, hWnd
, NULL
);
1065 return DefWndNCActivate(hWnd
, wParam
);
1071 Point
.x
= GET_X_LPARAM(lParam
);
1072 Point
.y
= GET_Y_LPARAM(lParam
);
1073 return (DefWndNCHitTest(hWnd
, Point
));
1076 case WM_LBUTTONDOWN
:
1077 case WM_RBUTTONDOWN
:
1078 case WM_MBUTTONDOWN
:
1079 iF10Key
= iMenuSysKey
= 0;
1082 case WM_NCLBUTTONDOWN
:
1084 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
1087 case WM_LBUTTONDBLCLK
:
1088 return (DefWndNCLButtonDblClk(hWnd
, HTCLIENT
, lParam
));
1090 case WM_NCLBUTTONDBLCLK
:
1092 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
1095 case WM_WINDOWPOSCHANGING
:
1097 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1100 case WM_WINDOWPOSCHANGED
:
1102 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
1105 case WM_NCRBUTTONDOWN
:
1107 /* in Windows, capture is taken when right-clicking on the caption bar */
1108 if (wParam
== HTCAPTION
)
1118 if (hWnd
== GetCapture())
1122 Pt
.x
= GET_X_LPARAM(lParam
);
1123 Pt
.y
= GET_Y_LPARAM(lParam
);
1124 ClientToScreen(hWnd
, &Pt
);
1125 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1128 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1132 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1137 case WM_NCRBUTTONUP
:
1139 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1140 * in Windows), but what _should_ we do? According to MSDN :
1141 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1142 * message to the window". When is it appropriate?
1146 case WM_CONTEXTMENU
:
1148 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1152 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1156 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1165 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1167 Pt
.x
= GET_X_LPARAM(lParam
);
1168 Pt
.y
= GET_Y_LPARAM(lParam
);
1169 if (Style
& WS_CHILD
)
1171 ScreenToClient(GetParent(hWnd
), &Pt
);
1174 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1176 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1181 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1183 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongW(hWnd
, GWL_STYLE
),
1184 GetClassLongW(hWnd
, GCL_STYLE
), HitCode
);
1186 if(HitCode
== HTCAPTION
)
1187 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1189 Flags
= TPM_LEFTBUTTON
;
1191 TrackPopupMenu(SystemMenu
, Flags
,
1192 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1201 DefWndPrint(hWnd
, (HDC
)wParam
, lParam
);
1205 case WM_SYSCOLORCHANGE
:
1207 /* force to redraw non-client area */
1208 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1209 /* Use InvalidateRect to redraw client area, enable
1210 * erase to redraw all subcontrols otherwise send the
1211 * WM_SYSCOLORCHANGE to child windows/controls is required
1213 InvalidateRect(hWnd
,NULL
,TRUE
);
1221 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1226 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1227 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1231 GetClientRect(hWnd
, &ClientRect
);
1232 x
= (ClientRect
.right
- ClientRect
.left
-
1233 GetSystemMetrics(SM_CXICON
)) / 2;
1234 y
= (ClientRect
.bottom
- ClientRect
.top
-
1235 GetSystemMetrics(SM_CYICON
)) / 2;
1236 DrawIcon(hDC
, x
, y
, hIcon
);
1238 EndPaint(hWnd
, &Ps
);
1246 hRgn
= CreateRectRgn(0, 0, 0, 0);
1247 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1249 RedrawWindow(hWnd
, NULL
, hRgn
,
1250 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1259 DefWndSetRedraw(hWnd
, wParam
);
1265 DestroyWindow(hWnd
);
1269 case WM_MOUSEACTIVATE
:
1271 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1276 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1281 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1289 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1294 /* Check if the window is minimized. */
1295 if (LOWORD(wParam
) != WA_INACTIVE
&&
1296 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1305 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1309 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1314 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1322 case WM_ICONERASEBKGND
:
1325 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1331 if (GetClassLongW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1333 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1334 GetClientRect(hWnd
, &Rect
);
1335 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1339 GetClipBox((HDC
)wParam
, &Rect
);
1341 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1345 case WM_CTLCOLORMSGBOX
:
1346 case WM_CTLCOLOREDIT
:
1347 case WM_CTLCOLORLISTBOX
:
1348 case WM_CTLCOLORBTN
:
1349 case WM_CTLCOLORDLG
:
1350 case WM_CTLCOLORSTATIC
:
1351 case WM_CTLCOLORSCROLLBAR
:
1352 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1355 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
1359 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1361 if (Style
& WS_CHILD
)
1363 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1368 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1373 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1382 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1386 return (DefWndHandleSysCommand(hWnd
, wParam
, lParam
));
1389 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
1392 /* FIXME: This is also incomplete. */
1395 if (HIWORD(lParam
) & KEYDATA_ALT
)
1397 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1398 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
1399 if ( (wParam
== VK_MENU
|| wParam
== VK_LMENU
1400 || wParam
== VK_RMENU
) && !iMenuSysKey
)
1403 /* mimic behaviour of XP, sending a WM_SYSCOMMAND when pressing <alt> */
1404 SendMessageW( top
, WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1411 if (wParam
== VK_F4
) /* Try to close the window */
1413 if (!(GetClassLongW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1416 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1418 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1421 else if (wParam
== VK_SNAPSHOT
)
1424 while (GetParent(hwnd
) != NULL
)
1426 hwnd
= GetParent(hwnd
);
1428 DefWndScreenshot(hwnd
);
1431 else if( wParam
== VK_F10
)
1433 else if( wParam
== VK_ESCAPE
&& (GetKeyState(VK_SHIFT
) & 0x8000))
1434 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, ' ' );
1441 /* Press and release F10 or ALT */
1442 if (((wParam
== VK_MENU
|| wParam
== VK_LMENU
|| wParam
== VK_RMENU
)
1443 && iMenuSysKey
) || ((wParam
== VK_F10
) && iF10Key
))
1444 SendMessageW( GetAncestor( hWnd
, GA_ROOT
), WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1445 iMenuSysKey
= iF10Key
= 0;
1452 if (wParam
== '\r' && IsIconic(hWnd
))
1454 PostMessageW( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0L );
1457 if ((HIWORD(lParam
) & KEYDATA_ALT
) && wParam
)
1459 if (wParam
== '\t' || wParam
== '\x1b') break;
1460 if (wParam
== ' ' && (GetWindowLongW( hWnd
, GWL_STYLE
) & WS_CHILD
))
1461 SendMessageW( GetParent(hWnd
), Msg
, wParam
, lParam
);
1463 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, wParam
);
1465 else /* check for Ctrl-Esc */
1466 if (wParam
!= '\x1b') MessageBeep(0);
1472 if (lParam
) // Call when it is necessary.
1473 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, 0, FNID_DEFWINDOWPROC
, FALSE
);
1480 /* FIXME: Check for a desktop. */
1481 if (!(GetWindowLongW( hWnd
, GWL_STYLE
) & WS_CHILD
)) EndMenu();
1482 if (GetCapture() == hWnd
)
1496 case WM_QUERYDROPOBJECT
:
1498 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1505 case WM_QUERYDRAGICON
:
1510 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1513 return ((LRESULT
)hIcon
);
1515 for (Len
= 1; Len
< 64; Len
++)
1517 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1519 return((LRESULT
)hIcon
);
1522 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1525 /* FIXME: WM_ISACTIVEICON */
1527 case WM_NOTIFYFORMAT
:
1529 if (lParam
== NF_QUERY
)
1530 return IsWindowUnicode(hWnd
) ? NFR_UNICODE
: NFR_ANSI
;
1536 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1537 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1538 SetClassLongW(hWnd
, Index
, lParam
);
1539 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1540 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1541 SWP_NOACTIVATE
| SWP_NOZORDER
);
1542 return ((LRESULT
)hOldIcon
);
1547 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1548 return (GetClassLongW(hWnd
, Index
));
1555 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1559 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1566 THRDCARETINFO CaretInfo
;
1569 case 0xffff: /* Caret timer */
1570 /* switch showing byte in win32k and get information about the caret */
1571 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1573 DrawCaret(hWnd
, &CaretInfo
);
1581 case WM_QUERYENDSESSION
:
1586 case WM_INPUTLANGCHANGEREQUEST
:
1590 if(wParam
& INPUTLANGCHANGE_BACKWARD
1591 && wParam
& INPUTLANGCHANGE_FORWARD
)
1596 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1598 if(wParam
& INPUTLANGCHANGE_BACKWARD
) NewHkl
= (HKL
) HKL_PREV
;
1599 else if(wParam
& INPUTLANGCHANGE_FORWARD
) NewHkl
= (HKL
) HKL_NEXT
;
1600 else NewHkl
= (HKL
) lParam
;
1602 NtUserActivateKeyboardLayout(NewHkl
, 0);
1607 case WM_INPUTLANGCHANGE
:
1610 HWND
*win_array
= WIN_ListChildren( hWnd
);
1614 while (win_array
[count
])
1615 SendMessageW( win_array
[count
++], WM_INPUTLANGCHANGE
, wParam
, lParam
);
1616 HeapFree(GetProcessHeap(),0,win_array
);
1620 case WM_QUERYUISTATE
:
1623 PWINDOW Wnd
= ValidateHwnd(hWnd
);
1627 Ret
|= UISF_HIDEFOCUS
;
1629 Ret
|= UISF_HIDEACCEL
;
1634 case WM_CHANGEUISTATE
:
1636 BOOL AlwaysShowCues
= FALSE
;
1637 WORD Action
= LOWORD(wParam
);
1638 WORD Flags
= HIWORD(wParam
);
1641 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1645 Wnd
= ValidateHwnd(hWnd
);
1646 if (!Wnd
|| lParam
!= 0)
1649 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1652 if (Flags
& UISF_ACTIVE
)
1654 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1657 if (Action
== UIS_INITIALIZE
)
1659 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1663 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1664 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1666 /* We need to update wParam in case we need to send out messages */
1667 wParam
= MAKEWPARAM(Action
, Flags
);
1673 /* See if we actually need to change something */
1674 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1676 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1679 /* Don't need to do anything... */
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 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1697 if ((Wnd
->Style
& WS_CHILD
) && Wnd
->Parent
!= NULL
)
1699 /* We're a child window and we need to pass this message down until
1700 we reach the root */
1701 hWnd
= UserHMGetHandle((PWINDOW
)DesktopPtrToUser(Wnd
->Parent
));
1705 /* We're a top level window, we need to change the UI state */
1706 Msg
= WM_UPDATEUISTATE
;
1710 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1712 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1715 case WM_UPDATEUISTATE
:
1718 BOOL AlwaysShowCues
= FALSE
;
1719 WORD Action
= LOWORD(wParam
);
1720 WORD Flags
= HIWORD(wParam
);
1723 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1727 Wnd
= ValidateHwnd(hWnd
);
1728 if (!Wnd
|| lParam
!= 0)
1731 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1734 if (Flags
& UISF_ACTIVE
)
1736 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1739 if (Action
== UIS_INITIALIZE
)
1741 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1745 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1746 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1748 /* We need to update wParam for broadcasting the update */
1749 wParam
= MAKEWPARAM(Action
, Flags
);
1755 /* See if we actually need to change something */
1756 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1758 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1761 /* Don't need to do anything... */
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 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1781 /* Pack the information and call win32k */
1784 if (!NtUserCallTwoParam((DWORD
)hWnd
, (DWORD
)Flags
| ((DWORD
)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE
))
1788 /* Always broadcast the update to all children */
1789 EnumChildWindows(hWnd
,
1790 UserSendUiUpdateMsg
,
1802 * helpers for calling IMM32 (from Wine 10/22/2008)
1804 * WM_IME_* messages are generated only by IMM32,
1805 * so I assume imm32 is already LoadLibrary-ed.
1808 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1810 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1811 HWND (WINAPI
*pFunc
)(HWND
);
1816 ERR("cannot get IMM32 handle\n");
1820 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1822 hwndRet
= (*pFunc
)(hwnd
);
1829 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1831 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1832 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1837 ERR("cannot get IMM32 handle\n");
1841 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1843 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1850 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1852 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1853 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1858 ERR("cannot get IMM32 handle\n");
1862 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1864 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1871 DefWindowProcA(HWND hWnd
,
1879 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1884 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1885 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1886 * may have child window IDs instead of window name */
1888 DefSetText(hWnd
, (PCWSTR
)cs
->lpszName
, TRUE
);
1894 case WM_GETTEXTLENGTH
:
1899 Wnd
= ValidateHwnd(hWnd
);
1900 if (Wnd
!= NULL
&& Wnd
->WindowName
.Length
!= 0)
1902 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
1904 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1906 Wnd
->WindowName
.Length
)))
1908 Result
= (LRESULT
) len
;
1919 PSTR outbuf
= (PSTR
)lParam
;
1922 Wnd
= ValidateHwnd(hWnd
);
1923 if (Wnd
!= NULL
&& wParam
!= 0)
1925 if (Wnd
->WindowName
.Buffer
!= NULL
)
1926 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
1932 if (Wnd
->WindowName
.Length
!= 0)
1934 copy
= min(Wnd
->WindowName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1935 Result
= WideCharToMultiByte(CP_ACP
,
1943 outbuf
[Result
] = '\0';
1954 DefSetText(hWnd
, (PCWSTR
)lParam
, TRUE
);
1956 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1958 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1965 case WM_IME_KEYDOWN
:
1967 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
1973 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
1980 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
1981 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
1985 case WM_IME_STARTCOMPOSITION
:
1986 case WM_IME_COMPOSITION
:
1987 case WM_IME_ENDCOMPOSITION
:
1993 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
1995 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
1999 case WM_IME_SETCONTEXT
:
2003 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2005 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
2011 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2014 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2020 DefWindowProcW(HWND hWnd
,
2028 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
2033 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
2034 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2035 * may have child window IDs instead of window name */
2037 DefSetText(hWnd
, cs
->lpszName
, FALSE
);
2042 case WM_GETTEXTLENGTH
:
2047 Wnd
= ValidateHwnd(hWnd
);
2048 if (Wnd
!= NULL
&& Wnd
->WindowName
.Length
!= 0)
2050 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
2052 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
2054 Wnd
->WindowName
.Length
)))
2056 Result
= (LRESULT
) (Wnd
->WindowName
.Length
/ sizeof(WCHAR
));
2067 PWSTR outbuf
= (PWSTR
)lParam
;
2069 Wnd
= ValidateHwnd(hWnd
);
2070 if (Wnd
!= NULL
&& wParam
!= 0)
2072 if (Wnd
->WindowName
.Buffer
!= NULL
)
2073 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
2079 if (Wnd
->WindowName
.Length
!= 0)
2081 Result
= min(Wnd
->WindowName
.Length
/ sizeof(WCHAR
), wParam
- 1);
2082 RtlCopyMemory(outbuf
,
2084 Result
* sizeof(WCHAR
));
2085 outbuf
[Result
] = L
'\0';
2096 DefSetText(hWnd
, (PCWSTR
)lParam
, FALSE
);
2098 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2100 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
2108 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
2113 case WM_IME_KEYDOWN
:
2115 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2121 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
2125 case WM_IME_STARTCOMPOSITION
:
2126 case WM_IME_COMPOSITION
:
2127 case WM_IME_ENDCOMPOSITION
:
2133 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2135 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
2139 case WM_IME_SETCONTEXT
:
2143 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2145 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
2150 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
2152 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);