3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: dll/win32/user32/windows/defwnd.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
);
19 LRESULT
DefWndNCPaint(HWND hWnd
, HRGN hRgn
, BOOL Active
);
20 LRESULT
DefWndNCCalcSize(HWND hWnd
, BOOL CalcSizeStruct
, RECT
*Rect
);
21 LRESULT
DefWndNCActivate(HWND hWnd
, WPARAM wParam
);
22 LRESULT
DefWndNCHitTest(HWND hWnd
, POINT Point
);
23 LRESULT
DefWndNCLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
24 LRESULT
DefWndNCLButtonDblClk(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
25 void FASTCALL
MenuInitSysMenuPopup(HMENU Menu
, DWORD Style
, DWORD ClsStyle
, LONG HitTest
);
26 void MENU_EndMenu( HWND
);
28 /* GLOBALS *******************************************************************/
30 /* Bits in the dwKeyData */
31 #define KEYDATA_ALT 0x2000
32 #define KEYDATA_PREVSTATE 0x4000
34 static short iF10Key
= 0;
35 static short iMenuSysKey
= 0;
37 /* FUNCTIONS *****************************************************************/
40 InitStockObjects(void)
42 /* FIXME - Instead of copying the stuff to usermode we should map the tables to
43 userland. The current implementation has one big flaw: the system color
44 table doesn't get updated when another process changes them. That's why
45 we should rather map the table into usermode. But it only affects the
46 SysColors table - the pens, brushes and stock objects are not affected
47 as their handles never change. But it'd be faster to map them, too. */
56 GetSysColor(int nIndex
)
58 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
60 return gpsi
->argbSystem
[nIndex
];
63 SetLastError(ERROR_INVALID_PARAMETER
);
71 GetSysColorBrush(int nIndex
)
73 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
75 return gpsi
->ahbrSystem
[nIndex
];
78 SetLastError(ERROR_INVALID_PARAMETER
);
89 CONST INT
*lpaElements
,
90 CONST COLORREF
*lpaRgbValues
)
92 return NtUserSetSysColors(cElements
, lpaElements
, lpaRgbValues
, 0);
97 DefSetText(HWND hWnd
, PCWSTR String
, BOOL Ansi
)
100 LARGE_STRING lsString
;
105 RtlInitLargeAnsiString((PLARGE_ANSI_STRING
)&lsString
, (PCSZ
)String
, 0);
107 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING
)&lsString
, String
, 0);
109 Ret
= NtUserDefSetText(hWnd
, (String
? &lsString
: NULL
));
112 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE
, hWnd
, OBJID_WINDOW
, CHILDID_SELF
, 0);
118 UserGetInsideRectNC(PWND Wnd
, RECT
*rect
)
124 ExStyle
= Wnd
->ExStyle
;
126 rect
->top
= rect
->left
= 0;
127 rect
->right
= Wnd
->rcWindow
.right
- Wnd
->rcWindow
.left
;
128 rect
->bottom
= Wnd
->rcWindow
.bottom
- Wnd
->rcWindow
.top
;
130 if (Style
& WS_ICONIC
)
135 /* Remove frame from rectangle */
136 if (UserHasThickFrameStyle(Style
, ExStyle
))
138 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
139 -GetSystemMetrics(SM_CYFRAME
));
143 if (UserHasDlgFrameStyle(Style
, ExStyle
))
145 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
146 -GetSystemMetrics(SM_CYDLGFRAME
));
147 /* FIXME: this isn't in NC_AdjustRect? why not? */
148 if (ExStyle
& WS_EX_DLGMODALFRAME
)
149 InflateRect( rect
, -1, 0 );
153 if (UserHasThinFrameStyle(Style
, ExStyle
))
155 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
156 -GetSystemMetrics(SM_CYBORDER
));
164 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
166 LONG Style
= GetWindowLongPtr(hWnd
, GWL_STYLE
);
167 /* Content can be redrawn after a change. */
170 if (!(Style
& WS_VISIBLE
)) /* Not Visible */
172 SetWindowLongPtr(hWnd
, GWL_STYLE
, WS_VISIBLE
);
175 else /* Content cannot be redrawn after a change. */
177 if (Style
& WS_VISIBLE
) /* Visible */
179 RedrawWindow( hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
180 Style
&= ~WS_VISIBLE
;
181 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
); /* clear bits */
189 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
191 /* Not for child windows. */
192 if (hWnd
!= (HWND
)wParam
)
197 switch((INT_PTR
) LOWORD(lParam
))
201 WORD Msg
= HIWORD(lParam
);
202 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
203 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
212 HICON hCursor
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HCURSOR
);
224 if (Style
& WS_MAXIMIZE
)
228 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
234 if (Style
& WS_MAXIMIZE
)
238 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
244 if (Style
& WS_MAXIMIZE
)
248 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
254 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
258 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
261 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
265 DefWndStartSizeMove(HWND hWnd
, PWND Wnd
, WPARAM wParam
, POINT
*capturePoint
)
271 ULONG Style
= Wnd
->style
;
273 rectWindow
= Wnd
->rcWindow
;
275 if ((wParam
& 0xfff0) == SC_MOVE
)
277 /* Move pointer at the center of the caption */
279 UserGetInsideRectNC(Wnd
, &rect
);
280 if (Style
& WS_SYSMENU
)
281 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
282 if (Style
& WS_MINIMIZEBOX
)
283 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
284 if (Style
& WS_MAXIMIZEBOX
)
285 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
286 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
287 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
296 if (GetMessageW(&msg
, NULL
, 0, 0) <= 0)
301 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
302 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
314 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
315 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
319 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
320 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
324 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
325 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
329 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
330 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
333 case VK_ESCAPE
: return 0;
339 SetCursorPos( pt
.x
, pt
.y
);
340 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
344 #define ON_LEFT_BORDER(hit) \
345 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
346 #define ON_RIGHT_BORDER(hit) \
347 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
348 #define ON_TOP_BORDER(hit) \
349 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
350 #define ON_BOTTOM_BORDER(hit) \
351 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
354 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
355 ULONG width
, ULONG height
)
357 static HBRUSH hDraggingRectBrush
= NULL
;
360 if(!hDraggingRectBrush
)
362 static HBITMAP hDraggingPattern
= NULL
;
363 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
365 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
366 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
369 hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
370 PatBlt( hdc
, rect
->left
, rect
->top
,
371 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
372 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
373 rect
->bottom
- rect
->top
- height
, PATINVERT
);
374 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
375 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
376 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
377 rect
->bottom
- rect
->top
- height
, PATINVERT
);
378 SelectObject( hdc
, hbrush
);
382 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
386 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
));
390 UserDrawWindowFrame(hdc
, rect
, 1, 1);
395 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
399 RECT sizingRect
, mouseRect
, origRect
, clipRect
, unmodRect
;
401 LONG hittest
= (LONG
)(wParam
& 0x0f);
402 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
403 POINT minTrack
, maxTrack
;
404 POINT capturePoint
, pt
;
405 ULONG Style
, ExStyle
;
409 DWORD dwPoint
= GetMessagePos();
410 BOOL DragFullWindows
= FALSE
;
411 HWND hWndParent
= NULL
;
414 Wnd
= ValidateHwnd(hwnd
);
419 ExStyle
= Wnd
->ExStyle
;
420 iconic
= (Style
& WS_MINIMIZE
) != 0;
422 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
424 pt
.x
= GET_X_LPARAM(dwPoint
);
425 pt
.y
= GET_Y_LPARAM(dwPoint
);
428 if ((Style
& WS_MAXIMIZE
) || !IsWindowVisible(hwnd
))
433 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
434 if ((wParam
& 0xfff0) == SC_MOVE
)
438 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
451 if (hittest
&& ((wParam
& 0xfff0) != SC_MOUSEMENU
))
453 hittest
+= (HTLEFT
- WMSZ_LEFT
);
458 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
467 /* Get min/max info */
469 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
470 sizingRect
= Wnd
->rcWindow
;
471 if (Style
& WS_CHILD
)
473 hWndParent
= GetParent(hwnd
);
474 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
475 unmodRect
= sizingRect
;
476 GetClientRect(hWndParent
, &mouseRect
);
477 clipRect
= mouseRect
;
478 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
482 if(!(ExStyle
& WS_EX_TOPMOST
))
484 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
485 mouseRect
= clipRect
;
489 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
490 clipRect
= mouseRect
;
492 unmodRect
= sizingRect
;
494 ClipCursor(&clipRect
);
496 origRect
= sizingRect
;
497 if (ON_LEFT_BORDER(hittest
))
499 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
500 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
502 else if (ON_RIGHT_BORDER(hittest
))
504 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
505 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
507 if (ON_TOP_BORDER(hittest
))
509 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
510 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
512 else if (ON_BOTTOM_BORDER(hittest
))
514 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
515 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
517 if (Style
& WS_CHILD
)
519 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
522 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
523 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
524 if (GetCapture() != hwnd
) SetCapture( hwnd
);
526 if (Style
& WS_CHILD
)
528 /* Retrieve a default cache DC (without using the window style) */
529 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
535 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
538 SelectObject(hdc
, DesktopRgn
);
540 if( iconic
) /* create a cursor for dragging */
542 HICON hIcon
= (HICON
)GetClassLongPtrW(hwnd
, GCL_HICON
);
543 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
544 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
545 if( !hDragCursor
) iconic
= FALSE
;
548 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
549 if( !iconic
&& !DragFullWindows
)
551 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
558 if (GetMessageW(&msg
, 0, 0, 0) <= 0)
561 /* Exit on button-up, Return, or Esc */
562 if ((msg
.message
== WM_LBUTTONUP
) ||
563 ((msg
.message
== WM_KEYDOWN
) &&
564 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
566 if (msg
.message
== WM_PAINT
)
568 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
569 UpdateWindow( msg
.hwnd
);
570 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
574 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
575 continue; /* We are not interested in other messages */
579 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
581 case VK_UP
: pt
.y
-= 8; break;
582 case VK_DOWN
: pt
.y
+= 8; break;
583 case VK_LEFT
: pt
.x
-= 8; break;
584 case VK_RIGHT
: pt
.x
+= 8; break;
587 pt
.x
= max( pt
.x
, mouseRect
.left
);
588 pt
.x
= min( pt
.x
, mouseRect
.right
);
589 pt
.y
= max( pt
.y
, mouseRect
.top
);
590 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
592 dx
= pt
.x
- capturePoint
.x
;
593 dy
= pt
.y
- capturePoint
.y
;
601 if( iconic
) /* ok, no system popup tracking */
603 hOldCursor
= SetCursor(hDragCursor
);
608 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
611 RECT newRect
= unmodRect
;
612 WPARAM wpSizingHit
= 0;
614 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
615 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
616 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
617 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
618 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
619 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
622 /* determine the hit location */
623 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
624 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
626 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
631 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
633 /* To avoid any deadlocks, all the locks on the windows
634 structures must be suspended before the SetWindowPos */
635 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
636 newRect
.right
- newRect
.left
,
637 newRect
.bottom
- newRect
.top
,
638 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
641 sizingRect
= newRect
;
650 if( moved
) /* restore cursors, show icon title later on */
653 SetCursor( hOldCursor
);
655 DestroyCursor( hDragCursor
);
657 else if(!DragFullWindows
)
658 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
660 if (Style
& WS_CHILD
)
661 ReleaseDC( hWndParent
, hdc
);
667 DeleteObject(DesktopRgn
);
671 if (ISITHOOKED(WH_CBT
))
674 NtUserMessageCall( hwnd
, WM_CBT
, HCBT_MOVESIZE
, (LPARAM
)&sizingRect
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
675 if (lResult
) moved
= FALSE
;
678 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
679 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
680 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
682 /* window moved or resized */
685 /* if the moving/resizing isn't canceled call SetWindowPos
686 * with the new position or the new size of the window
688 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
690 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
692 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
693 sizingRect
.right
- sizingRect
.left
,
694 sizingRect
.bottom
- sizingRect
.top
,
695 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
697 else { /* restore previous size/position */
699 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
700 origRect
.right
- origRect
.left
,
701 origRect
.bottom
- origRect
.top
,
702 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
707 if( Style
& WS_MINIMIZE
)
709 /* Single click brings up the system menu when iconized */
713 if( Style
& WS_SYSMENU
)
714 SendMessageA( hwnd
, WM_SYSCOMMAND
,
715 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
721 /***********************************************************************
722 * DefWndTrackScrollBar
724 * Track a mouse button press on the horizontal or vertical scroll-bar.
727 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
731 if (SC_HSCROLL
== (wParam
& 0xfff0))
733 if (HTHSCROLL
!= (wParam
& 0x0f))
739 else /* SC_VSCROLL */
741 if (HTVSCROLL
!= (wParam
& 0x0f))
747 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
752 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
757 if (!IsWindowEnabled( hWnd
)) return 0;
759 if (ISITHOOKED(WH_CBT
))
762 NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
763 if (lResult
) return 0;
766 switch (wParam
& 0xfff0)
770 DefWndDoSizeMove(hWnd
, wParam
);
773 wp
.length
= sizeof(WINDOWPLACEMENT
);
774 if(GetWindowPlacement(hWnd
, &wp
))
776 wp
.showCmd
= SW_MINIMIZE
;
777 SetWindowPlacement(hWnd
, &wp
);
781 wp
.length
= sizeof(WINDOWPLACEMENT
);
782 if(GetWindowPlacement(hWnd
, &wp
))
784 wp
.showCmd
= SW_MAXIMIZE
;
785 SetWindowPlacement(hWnd
, &wp
);
789 wp
.length
= sizeof(WINDOWPLACEMENT
);
790 if(GetWindowPlacement(hWnd
, &wp
))
792 wp
.showCmd
= SW_RESTORE
;
793 SetWindowPlacement(hWnd
, &wp
);
797 return SendMessageW(hWnd
, WM_CLOSE
, 0, 0);
801 Pt
.x
= (short)LOWORD(lParam
);
802 Pt
.y
= (short)HIWORD(lParam
);
803 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
807 MenuTrackKbdMenuBar(hWnd
, wParam
, (WCHAR
)lParam
);
812 Pt
.x
= (short)LOWORD(lParam
);
813 Pt
.y
= (short)HIWORD(lParam
);
814 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
819 /* FIXME: Implement */
828 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
830 POINT maxTrack
, minTrack
;
831 LONG style
= GetWindowLongPtrA(hWnd
, GWL_STYLE
);
833 if (Pos
->flags
& SWP_NOSIZE
) return 0;
834 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
836 WinPosGetMinMaxInfo(hWnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
837 Pos
->cx
= min(Pos
->cx
, maxTrack
.x
);
838 Pos
->cy
= min(Pos
->cy
, maxTrack
.y
);
839 if (!(style
& WS_MINIMIZE
))
841 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
842 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
847 Pos
->cx
= max(Pos
->cx
, 0);
848 Pos
->cy
= max(Pos
->cy
, 0);
854 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
858 GetClientRect(hWnd
, &Rect
);
859 MapWindowPoints(hWnd
, (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
?
860 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
862 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
864 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
867 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
869 WPARAM wp
= SIZE_RESTORED
;
874 else if (IsIconic(hWnd
))
878 SendMessageW(hWnd
, WM_SIZE
, wp
,
879 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
885 /***********************************************************************
888 * Default colors for control painting.
891 DefWndControlColor(HDC hDC
, UINT ctlType
)
893 if (CTLCOLOR_SCROLLBAR
== ctlType
)
895 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
896 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
897 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
900 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
901 * we better use 0x55aa bitmap brush to make scrollbar's background
902 * look different from the window background.
904 if (bk
== GetSysColor(COLOR_WINDOW
))
906 static const WORD wPattern55AA
[] =
908 0x5555, 0xaaaa, 0x5555, 0xaaaa,
909 0x5555, 0xaaaa, 0x5555, 0xaaaa
911 static HBITMAP hPattern55AABitmap
= NULL
;
912 static HBRUSH hPattern55AABrush
= NULL
;
913 if (hPattern55AABrush
== NULL
)
915 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
916 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
918 return hPattern55AABrush
;
924 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
926 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
928 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
932 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
933 return GetSysColorBrush(COLOR_3DFACE
);
936 return GetSysColorBrush(COLOR_WINDOW
);
939 static void DefWndPrint( HWND hwnd
, HDC hdc
, ULONG uFlags
)
944 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
945 !IsWindowVisible(hwnd
) )
949 * Unimplemented flags.
951 if ( (uFlags
& PRF_CHILDREN
) ||
952 (uFlags
& PRF_OWNED
) ||
953 (uFlags
& PRF_NONCLIENT
) )
955 FIXME("WM_PRINT message with unsupported flags\n");
961 if ( uFlags
& PRF_ERASEBKGND
)
962 SendMessageW(hwnd
, WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
967 if ( uFlags
& PRF_CLIENT
)
968 SendMessageW(hwnd
, WM_PRINTCLIENT
, (WPARAM
)hdc
, uFlags
);
972 UserSendUiUpdateMsg(HWND hwnd
, LPARAM lParam
)
974 SendMessageW(hwnd
, WM_UPDATEUISTATE
, (WPARAM
)lParam
, 0);
980 DefWndScreenshot(HWND hWnd
)
992 hdc
= GetWindowDC(hWnd
);
993 GetWindowRect(hWnd
, &rect
);
994 w
= rect
.right
- rect
.left
;
995 h
= rect
.bottom
- rect
.top
;
997 hbitmap
= CreateCompatibleBitmap(hdc
, w
, h
);
998 hdc2
= CreateCompatibleDC(hdc
);
999 SelectObject(hdc2
, hbitmap
);
1001 BitBlt(hdc2
, 0, 0, w
, h
,
1005 SetClipboardData(CF_BITMAP
, hbitmap
);
1007 ReleaseDC(hWnd
, hdc
);
1008 ReleaseDC(hWnd
, hdc2
);
1017 User32DefWindowProc(HWND hWnd
,
1027 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
1032 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
1035 case WM_POPUPSYSTEMMENU
:
1037 /* This is an undocumented message used by the windows taskbar to
1038 display the system menu of windows that belong to other processes. */
1039 HMENU menu
= GetSystemMenu(hWnd
, FALSE
);
1042 TrackPopupMenu(menu
, TPM_LEFTBUTTON
|TPM_RIGHTBUTTON
,
1043 LOWORD(lParam
), HIWORD(lParam
), 0, hWnd
, NULL
);
1049 return DefWndNCActivate(hWnd
, wParam
);
1055 Point
.x
= GET_X_LPARAM(lParam
);
1056 Point
.y
= GET_Y_LPARAM(lParam
);
1057 return (DefWndNCHitTest(hWnd
, Point
));
1060 case WM_LBUTTONDOWN
:
1061 case WM_RBUTTONDOWN
:
1062 case WM_MBUTTONDOWN
:
1063 iF10Key
= iMenuSysKey
= 0;
1066 case WM_NCLBUTTONDOWN
:
1068 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
1071 case WM_LBUTTONDBLCLK
:
1072 return (DefWndNCLButtonDblClk(hWnd
, HTCLIENT
, lParam
));
1074 case WM_NCLBUTTONDBLCLK
:
1076 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
1079 case WM_WINDOWPOSCHANGING
:
1081 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1084 case WM_WINDOWPOSCHANGED
:
1086 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
1089 case WM_NCRBUTTONDOWN
:
1091 /* in Windows, capture is taken when right-clicking on the caption bar */
1092 if (wParam
== HTCAPTION
)
1102 if (hWnd
== GetCapture())
1106 Pt
.x
= GET_X_LPARAM(lParam
);
1107 Pt
.y
= GET_Y_LPARAM(lParam
);
1108 ClientToScreen(hWnd
, &Pt
);
1109 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1112 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1116 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1121 case WM_NCRBUTTONUP
:
1123 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1124 * in Windows), but what _should_ we do? According to MSDN :
1125 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1126 * message to the window". When is it appropriate?
1130 case WM_CONTEXTMENU
:
1132 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1136 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1140 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1149 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1151 Pt
.x
= GET_X_LPARAM(lParam
);
1152 Pt
.y
= GET_Y_LPARAM(lParam
);
1153 if (Style
& WS_CHILD
)
1155 ScreenToClient(GetParent(hWnd
), &Pt
);
1158 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1160 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1165 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1167 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongPtrW(hWnd
, GWL_STYLE
),
1168 GetClassLongPtrW(hWnd
, GCL_STYLE
), HitCode
);
1170 if(HitCode
== HTCAPTION
)
1171 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1173 Flags
= TPM_LEFTBUTTON
;
1175 TrackPopupMenu(SystemMenu
, Flags
,
1176 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1185 DefWndPrint(hWnd
, (HDC
)wParam
, lParam
);
1189 case WM_SYSCOLORCHANGE
:
1191 /* force to redraw non-client area */
1192 DefWndNCPaint(hWnd
, HRGN_WINDOW
, -1);
1193 /* Use InvalidateRect to redraw client area, enable
1194 * erase to redraw all subcontrols otherwise send the
1195 * WM_SYSCOLORCHANGE to child windows/controls is required
1197 InvalidateRect(hWnd
,NULL
,TRUE
);
1205 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1210 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1211 (hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
)) != NULL
)
1215 GetClientRect(hWnd
, &ClientRect
);
1216 x
= (ClientRect
.right
- ClientRect
.left
-
1217 GetSystemMetrics(SM_CXICON
)) / 2;
1218 y
= (ClientRect
.bottom
- ClientRect
.top
-
1219 GetSystemMetrics(SM_CYICON
)) / 2;
1220 DrawIcon(hDC
, x
, y
, hIcon
);
1222 EndPaint(hWnd
, &Ps
);
1230 hRgn
= CreateRectRgn(0, 0, 0, 0);
1231 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1233 RedrawWindow(hWnd
, NULL
, hRgn
,
1234 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1243 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1244 if (wParam
) SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
| WS_VISIBLE
);
1247 RedrawWindow(hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
1248 Style
&= ~WS_VISIBLE
;
1249 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
);
1256 DestroyWindow(hWnd
);
1260 case WM_MOUSEACTIVATE
:
1262 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1267 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1272 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1280 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1285 /* Check if the window is minimized. */
1286 if (LOWORD(wParam
) != WA_INACTIVE
&&
1287 !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1296 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1300 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1305 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1313 case WM_ICONERASEBKGND
:
1316 HBRUSH hBrush
= (HBRUSH
)GetClassLongPtrW(hWnd
, GCL_HBRBACKGROUND
);
1322 if (GetClassLongPtrW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1324 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1325 GetClientRect(hWnd
, &Rect
);
1326 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1330 GetClipBox((HDC
)wParam
, &Rect
);
1332 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1336 case WM_CTLCOLORMSGBOX
:
1337 case WM_CTLCOLOREDIT
:
1338 case WM_CTLCOLORLISTBOX
:
1339 case WM_CTLCOLORBTN
:
1340 case WM_CTLCOLORDLG
:
1341 case WM_CTLCOLORSTATIC
:
1342 case WM_CTLCOLORSCROLLBAR
:
1343 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1346 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
1350 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1352 if (Style
& WS_CHILD
)
1354 /* with the exception of the border around a resizable wnd,
1355 * give the parent first chance to set the cursor */
1356 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1358 HWND parent
= GetParent( hWnd
);
1361 if (parent
!= GetDesktopWindow() &&
1362 SendMessageW( parent
, WM_SETCURSOR
, wParam
, lParam
))
1367 if (parent
!= GetDesktopWindow() &&
1368 SendMessageA( parent
, WM_SETCURSOR
, wParam
, lParam
))
1373 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1377 return (DefWndHandleSysCommand(hWnd
, wParam
, lParam
));
1380 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
1383 /* FIXME: This is also incomplete. */
1386 if (HIWORD(lParam
) & KEYDATA_ALT
)
1388 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1389 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
1390 if ( (wParam
== VK_MENU
|| wParam
== VK_LMENU
1391 || wParam
== VK_RMENU
) && !iMenuSysKey
)
1398 if (wParam
== VK_F4
) /* Try to close the window */
1400 if (!(GetClassLongPtrW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1403 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1405 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1408 else if (wParam
== VK_SNAPSHOT
)
1411 while (GetParent(hwnd
) != NULL
)
1413 hwnd
= GetParent(hwnd
);
1415 DefWndScreenshot(hwnd
);
1418 else if( wParam
== VK_F10
)
1420 if (GetKeyState(VK_SHIFT
) & 0x8000)
1421 SendMessageW( hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, MAKELPARAM(-1, -1) );
1424 else if( wParam
== VK_ESCAPE
&& (GetKeyState(VK_SHIFT
) & 0x8000))
1425 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, ' ' );
1432 /* Press and release F10 or ALT */
1433 if (((wParam
== VK_MENU
|| wParam
== VK_LMENU
|| wParam
== VK_RMENU
)
1434 && iMenuSysKey
) || ((wParam
== VK_F10
) && iF10Key
))
1435 SendMessageW( GetAncestor( hWnd
, GA_ROOT
), WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1436 iMenuSysKey
= iF10Key
= 0;
1443 if (wParam
== '\r' && IsIconic(hWnd
))
1445 PostMessageW( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0L );
1448 if ((HIWORD(lParam
) & KEYDATA_ALT
) && wParam
)
1450 if (wParam
== '\t' || wParam
== '\x1b') break;
1451 if (wParam
== ' ' && (GetWindowLongPtrW( hWnd
, GWL_STYLE
) & WS_CHILD
))
1452 SendMessageW( GetParent(hWnd
), Msg
, wParam
, lParam
);
1454 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, wParam
);
1456 else /* check for Ctrl-Esc */
1457 if (wParam
!= '\x1b') MessageBeep(0);
1463 if (lParam
) // Call when it is necessary.
1464 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, 0, FNID_DEFWINDOWPROC
, FALSE
);
1468 case WM_CLIENTSHUTDOWN
:
1471 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
1478 /* FIXME: Check for a desktop. */
1479 //if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
1480 MENU_EndMenu( hWnd
);
1481 if (GetCapture() == hWnd
)
1495 case WM_QUERYDROPOBJECT
:
1497 if (GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1504 case WM_QUERYDRAGICON
:
1509 hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
);
1512 return ((LRESULT
)hIcon
);
1514 for (Len
= 1; Len
< 64; Len
++)
1516 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1518 return((LRESULT
)hIcon
);
1521 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1524 case WM_ISACTIVEICON
:
1528 pWnd
= ValidateHwnd(hWnd
);
1529 if (!pWnd
) return 0;
1530 isai
= (pWnd
->state
& WNDS_ACTIVEFRAME
) != 0;
1534 case WM_NOTIFYFORMAT
:
1536 if (lParam
== NF_QUERY
)
1537 return IsWindowUnicode(hWnd
) ? NFR_UNICODE
: NFR_ANSI
;
1543 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1544 HICON hOldIcon
= (HICON
)GetClassLongPtrW(hWnd
, Index
);
1545 SetClassLongPtrW(hWnd
, Index
, lParam
);
1546 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1547 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1548 SWP_NOACTIVATE
| SWP_NOZORDER
);
1549 return ((LRESULT
)hOldIcon
);
1554 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1555 return (GetClassLongPtrW(hWnd
, Index
));
1562 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1566 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1573 THRDCARETINFO CaretInfo
;
1576 case 0xffff: /* Caret timer */
1577 /* switch showing byte in win32k and get information about the caret */
1578 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1580 DrawCaret(hWnd
, &CaretInfo
);
1588 case WM_QUERYENDSESSION
:
1593 case WM_INPUTLANGCHANGEREQUEST
:
1597 if(wParam
& INPUTLANGCHANGE_BACKWARD
1598 && wParam
& INPUTLANGCHANGE_FORWARD
)
1603 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1605 if(wParam
& INPUTLANGCHANGE_BACKWARD
) NewHkl
= (HKL
) HKL_PREV
;
1606 else if(wParam
& INPUTLANGCHANGE_FORWARD
) NewHkl
= (HKL
) HKL_NEXT
;
1607 else NewHkl
= (HKL
) lParam
;
1609 NtUserActivateKeyboardLayout(NewHkl
, 0);
1614 case WM_INPUTLANGCHANGE
:
1617 HWND
*win_array
= WIN_ListChildren( hWnd
);
1621 while (win_array
[count
])
1622 SendMessageW( win_array
[count
++], WM_INPUTLANGCHANGE
, wParam
, lParam
);
1623 HeapFree(GetProcessHeap(),0,win_array
);
1627 case WM_QUERYUISTATE
:
1630 PWND Wnd
= ValidateHwnd(hWnd
);
1634 Ret
|= UISF_HIDEFOCUS
;
1636 Ret
|= UISF_HIDEACCEL
;
1641 case WM_CHANGEUISTATE
:
1643 BOOL AlwaysShowCues
= FALSE
;
1644 WORD Action
= LOWORD(wParam
);
1645 WORD Flags
= HIWORD(wParam
);
1648 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1652 Wnd
= ValidateHwnd(hWnd
);
1653 if (!Wnd
|| lParam
!= 0)
1656 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1659 if (Flags
& UISF_ACTIVE
)
1661 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1664 if (Action
== UIS_INITIALIZE
)
1666 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1670 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1671 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1673 /* We need to update wParam in case we need to send out messages */
1674 wParam
= MAKEWPARAM(Action
, Flags
);
1680 /* See if we actually need to change something */
1681 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1683 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1686 /* Don't need to do anything... */
1690 /* See if we actually need to change something */
1691 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1693 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1696 /* Don't need to do anything... */
1700 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1704 if ((Wnd
->style
& WS_CHILD
) && Wnd
->spwndParent
!= NULL
)
1706 /* We're a child window and we need to pass this message down until
1707 we reach the root */
1708 hWnd
= UserHMGetHandle((PWND
)DesktopPtrToUser(Wnd
->spwndParent
));
1712 /* We're a top level window, we need to change the UI state */
1713 Msg
= WM_UPDATEUISTATE
;
1717 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1719 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1722 case WM_UPDATEUISTATE
:
1725 BOOL AlwaysShowCues
= FALSE
;
1726 WORD Action
= LOWORD(wParam
);
1727 WORD Flags
= HIWORD(wParam
);
1730 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1734 Wnd
= ValidateHwnd(hWnd
);
1735 if (!Wnd
|| lParam
!= 0)
1738 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1741 if (Flags
& UISF_ACTIVE
)
1743 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1746 if (Action
== UIS_INITIALIZE
)
1748 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1752 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1753 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1755 /* We need to update wParam for broadcasting the update */
1756 wParam
= MAKEWPARAM(Action
, Flags
);
1762 /* See if we actually need to change something */
1763 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1765 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1768 /* Don't need to do anything... */
1773 /* See if we actually need to change something */
1774 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1776 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1779 /* Don't need to do anything... */
1784 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1788 /* Pack the information and call win32k */
1791 if (!NtUserCallTwoParam((DWORD_PTR
)hWnd
, (DWORD_PTR
)Flags
| ((DWORD_PTR
)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE
))
1795 /* Always broadcast the update to all children */
1796 EnumChildWindows(hWnd
,
1797 UserSendUiUpdateMsg
,
1809 * helpers for calling IMM32 (from Wine 10/22/2008)
1811 * WM_IME_* messages are generated only by IMM32,
1812 * so I assume imm32 is already LoadLibrary-ed.
1815 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1817 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1818 HWND (WINAPI
*pFunc
)(HWND
);
1823 ERR("cannot get IMM32 handle\n");
1827 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1829 hwndRet
= (*pFunc
)(hwnd
);
1836 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1838 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1839 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1844 ERR("cannot get IMM32 handle\n");
1848 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1850 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1857 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1859 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1860 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1865 ERR("cannot get IMM32 handle\n");
1869 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1871 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1878 RealDefWindowProcA(HWND hWnd
,
1886 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1893 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1894 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1895 * may have child window IDs instead of window name */
1896 if (HIWORD(cs
->lpszName
))
1898 DefSetText(hWnd
, (PCWSTR
)cs
->lpszName
, TRUE
);
1905 case WM_GETTEXTLENGTH
:
1910 Wnd
= ValidateHwnd(hWnd
);
1911 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
1913 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1915 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1917 Wnd
->strName
.Length
)))
1919 Result
= (LRESULT
) len
;
1930 PSTR outbuf
= (PSTR
)lParam
;
1933 Wnd
= ValidateHwnd(hWnd
);
1934 if (Wnd
!= NULL
&& wParam
!= 0)
1936 if (Wnd
->strName
.Buffer
!= NULL
)
1937 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1943 if (Wnd
->strName
.Length
!= 0)
1945 copy
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1946 Result
= WideCharToMultiByte(CP_ACP
,
1954 outbuf
[Result
] = '\0';
1965 DefSetText(hWnd
, (PCWSTR
)lParam
, TRUE
);
1967 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1969 DefWndNCPaint(hWnd
, HRGN_WINDOW
, -1);
1975 case WM_IME_KEYDOWN
:
1977 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
1983 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
1990 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
1991 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
1995 case WM_IME_STARTCOMPOSITION
:
1996 case WM_IME_COMPOSITION
:
1997 case WM_IME_ENDCOMPOSITION
:
2003 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2005 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
2009 case WM_IME_SETCONTEXT
:
2013 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2015 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
2021 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2024 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2030 RealDefWindowProcW(HWND hWnd
,
2038 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
2045 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
2046 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2047 * may have child window IDs instead of window name */
2048 if (HIWORD(cs
->lpszName
))
2050 DefSetText(hWnd
, cs
->lpszName
, FALSE
);
2057 case WM_GETTEXTLENGTH
:
2062 Wnd
= ValidateHwnd(hWnd
);
2063 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
2065 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2067 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
2069 Wnd
->strName
.Length
)))
2071 Result
= (LRESULT
) (Wnd
->strName
.Length
/ sizeof(WCHAR
));
2082 PWSTR outbuf
= (PWSTR
)lParam
;
2084 Wnd
= ValidateHwnd(hWnd
);
2085 if (Wnd
!= NULL
&& wParam
!= 0)
2087 if (Wnd
->strName
.Buffer
!= NULL
)
2088 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2094 if (Wnd
->strName
.Length
!= 0)
2096 Result
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
2097 RtlCopyMemory(outbuf
,
2099 Result
* sizeof(WCHAR
));
2100 outbuf
[Result
] = L
'\0';
2111 DefSetText(hWnd
, (PCWSTR
)lParam
, FALSE
);
2113 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2115 DefWndNCPaint(hWnd
, HRGN_WINDOW
, -1);
2123 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
2128 case WM_IME_KEYDOWN
:
2130 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2136 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
2140 case WM_IME_STARTCOMPOSITION
:
2141 case WM_IME_COMPOSITION
:
2142 case WM_IME_ENDCOMPOSITION
:
2148 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2150 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
2154 case WM_IME_SETCONTEXT
:
2158 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2160 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
2165 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
2167 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2173 DefWindowProcA(HWND hWnd
,
2178 BOOL Hook
, msgOverride
= FALSE
;
2183 Hook
= BeginIfHookedUserApiHook();
2185 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2187 /* Bypass SEH and go direct. */
2188 if (!Hook
|| !msgOverride
)
2189 return RealDefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2193 Result
= guah
.DefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2195 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2206 DefWindowProcW(HWND hWnd
,
2211 BOOL Hook
, msgOverride
= FALSE
;
2216 Hook
= BeginIfHookedUserApiHook();
2218 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2220 /* Bypass SEH and go direct. */
2221 if (!Hook
|| !msgOverride
)
2222 return RealDefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2226 Result
= guah
.DefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2228 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)