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
);
1209 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1214 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1215 (hIcon
= (HICON
)GetClassLongW(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 DefWndSetRedraw(hWnd
, wParam
);
1253 DestroyWindow(hWnd
);
1257 case WM_MOUSEACTIVATE
:
1259 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1264 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1269 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1277 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1282 /* Check if the window is minimized. */
1283 if (LOWORD(wParam
) != WA_INACTIVE
&&
1284 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1293 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1297 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1302 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1310 case WM_ICONERASEBKGND
:
1313 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1319 if (GetClassLongW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1321 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1322 GetClientRect(hWnd
, &Rect
);
1323 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1327 GetClipBox((HDC
)wParam
, &Rect
);
1329 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1333 case WM_CTLCOLORMSGBOX
:
1334 case WM_CTLCOLOREDIT
:
1335 case WM_CTLCOLORLISTBOX
:
1336 case WM_CTLCOLORBTN
:
1337 case WM_CTLCOLORDLG
:
1338 case WM_CTLCOLORSTATIC
:
1339 case WM_CTLCOLORSCROLLBAR
:
1340 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1343 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
1347 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1349 if (Style
& WS_CHILD
)
1351 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1356 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1361 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1370 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1374 return (DefWndHandleSysCommand(hWnd
, wParam
, lParam
));
1377 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
1380 /* FIXME: This is also incomplete. */
1383 if (HIWORD(lParam
) & KEYDATA_ALT
)
1385 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
1386 if ( (wParam
== VK_MENU
|| wParam
== VK_LMENU
1387 || wParam
== VK_RMENU
) && !iMenuSysKey
)
1394 if (wParam
== VK_F4
) /* Try to close the window */
1396 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1397 if (!(GetClassLongW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1400 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1402 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1405 else if (wParam
== VK_SNAPSHOT
)
1408 while (GetParent(hwnd
) != NULL
)
1410 hwnd
= GetParent(hwnd
);
1412 DefWndScreenshot(hwnd
);
1415 else if( wParam
== VK_F10
)
1417 else if( wParam
== VK_ESCAPE
&& (GetKeyState(VK_SHIFT
) & 0x8000))
1418 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, ' ' );
1425 /* Press and release F10 or ALT */
1426 if (((wParam
== VK_MENU
|| wParam
== VK_LMENU
|| wParam
== VK_RMENU
)
1427 && iMenuSysKey
) || ((wParam
== VK_F10
) && iF10Key
))
1428 SendMessageW( GetAncestor( hWnd
, GA_ROOT
), WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1429 iMenuSysKey
= iF10Key
= 0;
1436 if (wParam
== '\r' && IsIconic(hWnd
))
1438 PostMessageW( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0L );
1441 if ((HIWORD(lParam
) & KEYDATA_ALT
) && wParam
)
1443 if (wParam
== '\t' || wParam
== '\x1b') break;
1444 if (wParam
== ' ' && (GetWindowLongW( hWnd
, GWL_STYLE
) & WS_CHILD
))
1445 SendMessageW( GetParent(hWnd
), Msg
, wParam
, lParam
);
1447 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, wParam
);
1449 else /* check for Ctrl-Esc */
1450 if (wParam
!= '\x1b') MessageBeep(0);
1456 if (lParam
) // Call when it is necessary.
1457 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, 0, FNID_DEFWINDOWPROC
, FALSE
);
1464 /* FIXME: Check for a desktop. */
1465 if (!(GetWindowLongW( hWnd
, GWL_STYLE
) & WS_CHILD
)) EndMenu();
1466 if (GetCapture() == hWnd
)
1480 case WM_QUERYDROPOBJECT
:
1482 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1489 case WM_QUERYDRAGICON
:
1494 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1497 return ((LRESULT
)hIcon
);
1499 for (Len
= 1; Len
< 64; Len
++)
1501 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1503 return((LRESULT
)hIcon
);
1506 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1509 /* FIXME: WM_ISACTIVEICON */
1511 case WM_NOTIFYFORMAT
:
1513 if (lParam
== NF_QUERY
)
1514 return IsWindowUnicode(hWnd
) ? NFR_UNICODE
: NFR_ANSI
;
1520 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1521 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1522 SetClassLongW(hWnd
, Index
, lParam
);
1523 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1524 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1525 SWP_NOACTIVATE
| SWP_NOZORDER
);
1526 return ((LRESULT
)hOldIcon
);
1531 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1532 return (GetClassLongW(hWnd
, Index
));
1539 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1543 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1550 THRDCARETINFO CaretInfo
;
1553 case 0xffff: /* Caret timer */
1554 /* switch showing byte in win32k and get information about the caret */
1555 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1557 DrawCaret(hWnd
, &CaretInfo
);
1565 case WM_QUERYENDSESSION
:
1570 case WM_INPUTLANGCHANGEREQUEST
:
1574 if(wParam
& INPUTLANGCHANGE_BACKWARD
1575 && wParam
& INPUTLANGCHANGE_FORWARD
)
1580 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1582 if(wParam
& INPUTLANGCHANGE_BACKWARD
) NewHkl
= (HKL
) HKL_PREV
;
1583 else if(wParam
& INPUTLANGCHANGE_FORWARD
) NewHkl
= (HKL
) HKL_NEXT
;
1584 else NewHkl
= (HKL
) lParam
;
1586 NtUserActivateKeyboardLayout(NewHkl
, 0);
1591 case WM_INPUTLANGCHANGE
:
1594 HWND
*win_array
= WIN_ListChildren( hWnd
);
1598 while (win_array
[count
])
1599 SendMessageW( win_array
[count
++], WM_INPUTLANGCHANGE
, wParam
, lParam
);
1600 HeapFree(GetProcessHeap(),0,win_array
);
1605 if (wParam
) PostQuitMessage(0);
1608 case WM_QUERYUISTATE
:
1611 PWINDOW Wnd
= ValidateHwnd(hWnd
);
1615 Ret
|= UISF_HIDEFOCUS
;
1617 Ret
|= UISF_HIDEACCEL
;
1622 case WM_CHANGEUISTATE
:
1624 BOOL AlwaysShowCues
= TRUE
;
1625 WORD Action
= LOWORD(wParam
);
1626 WORD Flags
= HIWORD(wParam
);
1629 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1633 Wnd
= ValidateHwnd(hWnd
);
1634 if (!Wnd
|| lParam
!= 0)
1637 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1640 if (Flags
& UISF_ACTIVE
)
1642 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1645 if (Action
== UIS_INITIALIZE
)
1647 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1651 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1652 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1654 /* We need to update wParam in case we need to send out messages */
1655 wParam
= MAKEWPARAM(Action
, Flags
);
1661 /* See if we actually need to change something */
1662 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1664 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1667 /* Don't need to do anything... */
1671 /* See if we actually need to change something */
1672 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1674 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1677 /* Don't need to do anything... */
1681 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1685 if ((Wnd
->Style
& WS_CHILD
) && Wnd
->Parent
!= NULL
)
1687 /* We're a child window and we need to pass this message down until
1688 we reach the root */
1689 hWnd
= UserHMGetHandle((PWINDOW
)DesktopPtrToUser(Wnd
->Parent
));
1693 /* We're a top level window, we need to change the UI state */
1694 Msg
= WM_UPDATEUISTATE
;
1698 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1700 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1703 case WM_UPDATEUISTATE
:
1706 BOOL AlwaysShowCues
= TRUE
;
1707 WORD Action
= LOWORD(wParam
);
1708 WORD Flags
= HIWORD(wParam
);
1711 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1715 Wnd
= ValidateHwnd(hWnd
);
1716 if (!Wnd
|| lParam
!= 0)
1719 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1722 if (Flags
& UISF_ACTIVE
)
1724 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1727 if (Action
== UIS_INITIALIZE
)
1729 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1733 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1734 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1736 /* We need to update wParam for broadcasting the update */
1737 wParam
= MAKEWPARAM(Action
, Flags
);
1743 /* See if we actually need to change something */
1744 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1746 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1749 /* Don't need to do anything... */
1754 /* See if we actually need to change something */
1755 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1757 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1760 /* Don't need to do anything... */
1765 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1769 /* Pack the information and call win32k */
1772 if (!NtUserCallTwoParam((DWORD
)hWnd
, (DWORD
)Flags
| ((DWORD
)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE
))
1776 /* Always broadcast the update to all children */
1777 EnumChildWindows(hWnd
,
1778 UserSendUiUpdateMsg
,
1790 * helpers for calling IMM32 (from Wine 10/22/2008)
1792 * WM_IME_* messages are generated only by IMM32,
1793 * so I assume imm32 is already LoadLibrary-ed.
1796 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1798 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1799 HWND (WINAPI
*pFunc
)(HWND
);
1804 ERR("cannot get IMM32 handle\n");
1808 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1810 hwndRet
= (*pFunc
)(hwnd
);
1817 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1819 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1820 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1825 ERR("cannot get IMM32 handle\n");
1829 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1831 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1838 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1840 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1841 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1846 ERR("cannot get IMM32 handle\n");
1850 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1852 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1859 DefWindowProcA(HWND hWnd
,
1867 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1872 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1873 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1874 * may have child window IDs instead of window name */
1876 DefSetText(hWnd
, (PCWSTR
)cs
->lpszName
, TRUE
);
1882 case WM_GETTEXTLENGTH
:
1887 Wnd
= ValidateHwnd(hWnd
);
1888 if (Wnd
!= NULL
&& Wnd
->WindowName
.Length
!= 0)
1890 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
1892 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1894 Wnd
->WindowName
.Length
)))
1896 Result
= (LRESULT
) len
;
1907 PSTR outbuf
= (PSTR
)lParam
;
1910 Wnd
= ValidateHwnd(hWnd
);
1911 if (Wnd
!= NULL
&& wParam
!= 0)
1913 if (Wnd
->WindowName
.Buffer
!= NULL
)
1914 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
1920 if (Wnd
->WindowName
.Length
!= 0)
1922 copy
= min(Wnd
->WindowName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1923 Result
= WideCharToMultiByte(CP_ACP
,
1931 outbuf
[Result
] = '\0';
1942 DefSetText(hWnd
, (PCWSTR
)lParam
, TRUE
);
1944 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1946 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1953 case WM_IME_KEYDOWN
:
1955 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
1961 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
1968 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
1969 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
1973 case WM_IME_STARTCOMPOSITION
:
1974 case WM_IME_COMPOSITION
:
1975 case WM_IME_ENDCOMPOSITION
:
1981 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
1983 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
1987 case WM_IME_SETCONTEXT
:
1991 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
1993 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
1999 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2002 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2008 DefWindowProcW(HWND hWnd
,
2016 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
2021 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
2022 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2023 * may have child window IDs instead of window name */
2025 DefSetText(hWnd
, cs
->lpszName
, FALSE
);
2030 case WM_GETTEXTLENGTH
:
2035 Wnd
= ValidateHwnd(hWnd
);
2036 if (Wnd
!= NULL
&& Wnd
->WindowName
.Length
!= 0)
2038 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
2040 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
2042 Wnd
->WindowName
.Length
)))
2044 Result
= (LRESULT
) (Wnd
->WindowName
.Length
/ sizeof(WCHAR
));
2055 PWSTR outbuf
= (PWSTR
)lParam
;
2057 Wnd
= ValidateHwnd(hWnd
);
2058 if (Wnd
!= NULL
&& wParam
!= 0)
2060 if (Wnd
->WindowName
.Buffer
!= NULL
)
2061 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
2067 if (Wnd
->WindowName
.Length
!= 0)
2069 Result
= min(Wnd
->WindowName
.Length
/ sizeof(WCHAR
), wParam
- 1);
2070 RtlCopyMemory(outbuf
,
2072 Result
* sizeof(WCHAR
));
2073 outbuf
[Result
] = L
'\0';
2084 DefSetText(hWnd
, (PCWSTR
)lParam
, FALSE
);
2086 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2088 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
2096 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
2101 case WM_IME_KEYDOWN
:
2103 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2109 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
2113 case WM_IME_STARTCOMPOSITION
:
2114 case WM_IME_COMPOSITION
:
2115 case WM_IME_ENDCOMPOSITION
:
2121 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2123 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
2127 case WM_IME_SETCONTEXT
:
2131 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2133 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
2138 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
2140 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);