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
, LPARAM lParam
);
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 LRESULT
NC_HandleNCRButtonDown( HWND hwnd
, WPARAM wParam
, LPARAM lParam
);
26 void FASTCALL
MenuInitSysMenuPopup(HMENU Menu
, DWORD Style
, DWORD ClsStyle
, LONG HitTest
);
27 void MENU_EndMenu( HWND
);
29 /* GLOBALS *******************************************************************/
31 static short iF10Key
= 0;
32 static short iMenuSysKey
= 0;
34 /* FUNCTIONS *****************************************************************/
42 GetSysColor(int nIndex
)
44 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
46 return gpsi
->argbSystem
[nIndex
];
49 SetLastError(ERROR_INVALID_PARAMETER
);
59 GetSysColorBrush(int nIndex
)
61 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
63 return gpsi
->ahbrSystem
[nIndex
];
66 SetLastError(ERROR_INVALID_PARAMETER
);
77 CONST INT
*lpaElements
,
78 CONST COLORREF
*lpaRgbValues
)
80 return NtUserSetSysColors(cElements
, lpaElements
, lpaRgbValues
, 0);
85 DefSetText(HWND hWnd
, PCWSTR String
, BOOL Ansi
)
88 LARGE_STRING lsString
;
93 RtlInitLargeAnsiString((PLARGE_ANSI_STRING
)&lsString
, (PCSZ
)String
, 0);
95 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING
)&lsString
, String
, 0);
97 Ret
= NtUserDefSetText(hWnd
, (String
? &lsString
: NULL
));
100 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE
, hWnd
, OBJID_WINDOW
, CHILDID_SELF
, 0);
106 UserGetInsideRectNC(PWND Wnd
, RECT
*rect
)
112 ExStyle
= Wnd
->ExStyle
;
114 rect
->top
= rect
->left
= 0;
115 rect
->right
= Wnd
->rcWindow
.right
- Wnd
->rcWindow
.left
;
116 rect
->bottom
= Wnd
->rcWindow
.bottom
- Wnd
->rcWindow
.top
;
118 if (Style
& WS_ICONIC
)
123 /* Remove frame from rectangle */
124 if (UserHasThickFrameStyle(Style
, ExStyle
))
126 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
));
130 if (UserHasDlgFrameStyle(Style
, ExStyle
))
132 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
133 /* FIXME: this isn't in NC_AdjustRect? why not? */
134 if (ExStyle
& WS_EX_DLGMODALFRAME
)
135 InflateRect( rect
, -1, 0 );
139 if (UserHasThinFrameStyle(Style
, ExStyle
))
141 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
145 /* We have additional border information if the window
146 * is a child (but not an MDI child) */
147 if ((Style
& WS_CHILD
) && !(ExStyle
& WS_EX_MDICHILD
))
149 if (ExStyle
& WS_EX_CLIENTEDGE
)
150 InflateRect (rect
, -GetSystemMetrics(SM_CXEDGE
), -GetSystemMetrics(SM_CYEDGE
));
151 if (ExStyle
& WS_EX_STATICEDGE
)
152 InflateRect (rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
157 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
159 /* Not for child windows. */
160 if (hWnd
!= (HWND
)wParam
)
165 switch((INT_PTR
) LOWORD(lParam
))
169 WORD Msg
= HIWORD(lParam
);
170 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
171 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
180 HICON hCursor
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HCURSOR
);
192 if (Style
& WS_MAXIMIZE
)
196 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
202 if (Style
& WS_MAXIMIZE
)
206 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
212 if (Style
& WS_MAXIMIZE
)
216 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
222 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
226 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
229 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
232 /***********************************************************************
233 * DefWndTrackScrollBar
235 * Track a mouse button press on the horizontal or vertical scroll-bar.
238 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
242 if (SC_HSCROLL
== (wParam
& 0xfff0))
244 if (HTHSCROLL
!= (wParam
& 0x0f))
250 else /* SC_VSCROLL */
252 if (HTVSCROLL
!= (wParam
& 0x0f))
258 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
261 LRESULT WINAPI
DoAppSwitch( WPARAM wParam
, LPARAM lParam
);
264 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
269 if (!IsWindowEnabled( hWnd
)) return 0;
271 if (ISITHOOKED(WH_CBT
))
273 NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
274 if (lResult
) return 0;
277 switch (wParam
& 0xfff0)
281 NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
285 if (hWnd
== GetActiveWindow())
286 ShowOwnedPopups(hWnd
,FALSE
);
287 ShowWindow( hWnd
, SW_MINIMIZE
);
291 if (IsIconic(hWnd
) && hWnd
== GetActiveWindow())
292 ShowOwnedPopups(hWnd
,TRUE
);
293 ShowWindow( hWnd
, SW_MAXIMIZE
);
297 if (IsIconic(hWnd
) && hWnd
== GetActiveWindow())
298 ShowOwnedPopups(hWnd
,TRUE
);
299 ShowWindow( hWnd
, SW_RESTORE
);
303 return SendMessageW(hWnd
, WM_CLOSE
, 0, 0);
308 Pt
.x
= (short)LOWORD(lParam
);
309 Pt
.y
= (short)HIWORD(lParam
);
310 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
314 MenuTrackKbdMenuBar(hWnd
, wParam
, (WCHAR
)lParam
);
319 Pt
.x
= (short)LOWORD(lParam
);
320 Pt
.y
= (short)HIWORD(lParam
);
321 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
326 WinExec( "taskman.exe", SW_SHOWNORMAL
);
330 NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
335 DoAppSwitch( wParam
, lParam
);
340 HWND hwnd
, hWndLastActive
;
344 pWnd
= ValidateHwnd(hwnd
);
347 hWndLastActive
= GetLastActivePopup(hwnd
);
350 hwnd
= hWndLastActive
;
351 pWnd
= ValidateHwnd(hwnd
);
353 SetForegroundWindow(hwnd
);
354 if (pWnd
->style
& WS_MINIMIZE
)
356 PostMessage(hwnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
363 FIXME("Unimplemented DefWndHandleSysCommand wParam 0x%x\n",wParam
);
370 /***********************************************************************
373 * Default colors for control painting.
376 DefWndControlColor(HDC hDC
, UINT ctlType
)
378 if (ctlType
== CTLCOLOR_SCROLLBAR
)
380 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
381 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
382 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
385 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
386 * we better use 0x55aa bitmap brush to make scrollbar's background
387 * look different from the window background.
389 if ( bk
== GetSysColor(COLOR_WINDOW
))
390 return gpsi
->hbrGray
;
392 UnrealizeObject( hb
);
396 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
398 if ((ctlType
== CTLCOLOR_EDIT
) || (ctlType
== CTLCOLOR_LISTBOX
))
400 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
404 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
405 return GetSysColorBrush(COLOR_3DFACE
);
408 return GetSysColorBrush(COLOR_WINDOW
);
411 static void DefWndPrint( HWND hwnd
, HDC hdc
, ULONG uFlags
)
416 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
417 !IsWindowVisible(hwnd
) )
421 * Unimplemented flags.
423 if ( (uFlags
& PRF_CHILDREN
) ||
424 (uFlags
& PRF_OWNED
) ||
425 (uFlags
& PRF_NONCLIENT
) )
427 FIXME("WM_PRINT message with unsupported flags\n");
433 if ( uFlags
& PRF_ERASEBKGND
)
434 SendMessageW(hwnd
, WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
439 if ( uFlags
& PRF_CLIENT
)
440 SendMessageW(hwnd
, WM_PRINTCLIENT
, (WPARAM
)hdc
, uFlags
);
444 UserSendUiUpdateMsg(HWND hwnd
, LPARAM lParam
)
446 SendMessageW(hwnd
, WM_UPDATEUISTATE
, (WPARAM
)lParam
, 0);
452 DefWndSetIcon(PWND pWnd
, WPARAM wParam
, LPARAM lParam
)
454 HICON hIcon
, hIconSmall
, hIconOld
;
456 if ( wParam
> ICON_SMALL2
)
458 SetLastError(ERROR_INVALID_PARAMETER
);
461 hIconSmall
= UserGetProp(UserHMGetHandle(pWnd
), gpsi
->atomIconSmProp
);
462 hIcon
= UserGetProp(UserHMGetHandle(pWnd
), gpsi
->atomIconProp
);
464 hIconOld
= wParam
== ICON_BIG
? hIcon
: hIconSmall
;
469 hIcon
= (HICON
)lParam
;
472 hIconSmall
= (HICON
)lParam
;
475 ERR("FIXME: Set ICON_SMALL2 support!\n");
480 NtUserSetProp(UserHMGetHandle(pWnd
), gpsi
->atomIconProp
, hIcon
);
481 NtUserSetProp(UserHMGetHandle(pWnd
), gpsi
->atomIconSmProp
, hIconSmall
);
483 if ((pWnd
->style
& WS_CAPTION
) == WS_CAPTION
)
484 DefWndNCPaint(UserHMGetHandle(pWnd
), HRGN_WINDOW
, -1); /* Repaint caption */
486 return (LRESULT
)hIconOld
;
490 DefWndGetIcon(PWND pWnd
, WPARAM wParam
, LPARAM lParam
)
493 if ( wParam
> ICON_SMALL2
)
495 SetLastError(ERROR_INVALID_PARAMETER
);
501 hIconRet
= UserGetProp(UserHMGetHandle(pWnd
), gpsi
->atomIconProp
);
505 hIconRet
= UserGetProp(UserHMGetHandle(pWnd
), gpsi
->atomIconSmProp
);
510 return (LRESULT
)hIconRet
;
514 DefWndScreenshot(HWND hWnd
)
526 hdc
= GetWindowDC(hWnd
);
527 GetWindowRect(hWnd
, &rect
);
528 w
= rect
.right
- rect
.left
;
529 h
= rect
.bottom
- rect
.top
;
531 hbitmap
= CreateCompatibleBitmap(hdc
, w
, h
);
532 hdc2
= CreateCompatibleDC(hdc
);
533 SelectObject(hdc2
, hbitmap
);
535 BitBlt(hdc2
, 0, 0, w
, h
,
539 SetClipboardData(CF_BITMAP
, hbitmap
);
541 ReleaseDC(hWnd
, hdc
);
542 ReleaseDC(hWnd
, hdc2
);
550 User32DefWindowProc(HWND hWnd
,
559 pWnd
= ValidateHwnd(hWnd
);
567 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
572 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
575 case WM_POPUPSYSTEMMENU
:
577 /* This is an undocumented message used by the windows taskbar to
578 display the system menu of windows that belong to other processes. */
579 HMENU menu
= GetSystemMenu(hWnd
, FALSE
);
582 TrackPopupMenu(menu
, TPM_LEFTBUTTON
|TPM_RIGHTBUTTON
,
583 LOWORD(lParam
), HIWORD(lParam
), 0, hWnd
, NULL
);
589 return DefWndNCActivate(hWnd
, wParam
, lParam
);
595 Point
.x
= GET_X_LPARAM(lParam
);
596 Point
.y
= GET_Y_LPARAM(lParam
);
597 return (DefWndNCHitTest(hWnd
, Point
));
603 iF10Key
= iMenuSysKey
= 0;
606 case WM_NCLBUTTONDOWN
:
608 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
611 case WM_LBUTTONDBLCLK
:
612 return (DefWndNCLButtonDblClk(hWnd
, HTCLIENT
, lParam
));
614 case WM_NCLBUTTONDBLCLK
:
616 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
619 case WM_NCRBUTTONDOWN
:
620 return NC_HandleNCRButtonDown( hWnd
, wParam
, lParam
);
625 if (hWnd
== GetCapture())
629 Pt
.x
= GET_X_LPARAM(lParam
);
630 Pt
.y
= GET_Y_LPARAM(lParam
);
631 ClientToScreen(hWnd
, &Pt
);
632 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
635 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
639 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
646 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
647 * in Windows), but what _should_ we do? According to MSDN :
648 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
649 * message to the window". When is it appropriate?
655 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
659 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
663 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
672 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
674 Pt
.x
= GET_X_LPARAM(lParam
);
675 Pt
.y
= GET_Y_LPARAM(lParam
);
676 if (Style
& WS_CHILD
)
678 ScreenToClient(GetParent(hWnd
), &Pt
);
681 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
683 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
688 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
690 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongPtrW(hWnd
, GWL_STYLE
),
691 GetClassLongPtrW(hWnd
, GCL_STYLE
), HitCode
);
693 if(HitCode
== HTCAPTION
)
694 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
696 Flags
= TPM_LEFTBUTTON
;
698 TrackPopupMenu(SystemMenu
, Flags
,
699 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
708 DefWndPrint(hWnd
, (HDC
)wParam
, lParam
);
712 case WM_SYSCOLORCHANGE
:
714 /* force to redraw non-client area */
715 DefWndNCPaint(hWnd
, HRGN_WINDOW
, -1);
716 /* Use InvalidateRect to redraw client area, enable
717 * erase to redraw all subcontrols otherwise send the
718 * WM_SYSCOLORCHANGE to child windows/controls is required
720 InvalidateRect(hWnd
,NULL
,TRUE
);
730 /* If already in Paint and Client area is not empty just return. */
731 if (pWnd
->state2
& WNDS2_STARTPAINT
&& !IsRectEmpty(&pWnd
->rcClient
))
733 ERR("In Paint and Client area is not empty!\n");
737 hDC
= BeginPaint(hWnd
, &Ps
);
742 if (IsIconic(hWnd
) && ((hIcon
= (HICON
)GetClassLongPtrW( hWnd
, GCLP_HICON
))))
746 GetClientRect(hWnd
, &ClientRect
);
747 x
= (ClientRect
.right
- ClientRect
.left
-
748 GetSystemMetrics(SM_CXICON
)) / 2;
749 y
= (ClientRect
.bottom
- ClientRect
.top
-
750 GetSystemMetrics(SM_CYICON
)) / 2;
751 DrawIcon(hDC
, x
, y
, hIcon
);
762 case WM_MOUSEACTIVATE
:
763 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
765 LONG Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
, wParam
, lParam
);
766 if (Ret
) return (Ret
);
768 return ( (HIWORD(lParam
) == WM_LBUTTONDOWN
&& LOWORD(lParam
) == HTCAPTION
) ? MA_NOACTIVATE
: MA_ACTIVATE
);
771 /* The default action in Windows is to set the keyboard focus to
772 * the window, if it's being activated and not minimized */
773 if (LOWORD(wParam
) != WA_INACTIVE
&&
774 !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
776 //ERR("WM_ACTIVATE %p\n",hWnd);
782 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
783 return SendMessageW( GetParent(hWnd
), WM_MOUSEWHEEL
, wParam
, lParam
);
787 case WM_ICONERASEBKGND
:
790 HBRUSH hBrush
= (HBRUSH
)GetClassLongPtrW(hWnd
, GCL_HBRBACKGROUND
);
796 if (GetClassLongPtrW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
798 /* can't use GetClipBox with a parent DC or we fill the whole parent */
799 GetClientRect(hWnd
, &Rect
);
800 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
804 GetClipBox((HDC
)wParam
, &Rect
);
806 FillRect((HDC
)wParam
, &Rect
, hBrush
);
810 case WM_CTLCOLORMSGBOX
:
811 case WM_CTLCOLOREDIT
:
812 case WM_CTLCOLORLISTBOX
:
815 case WM_CTLCOLORSTATIC
:
816 case WM_CTLCOLORSCROLLBAR
:
817 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
820 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
824 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
826 if (Style
& WS_CHILD
)
828 /* with the exception of the border around a resizable wnd,
829 * give the parent first chance to set the cursor */
830 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
832 HWND parent
= GetParent( hWnd
);
835 if (parent
!= GetDesktopWindow() &&
836 SendMessageW( parent
, WM_SETCURSOR
, wParam
, lParam
))
841 if (parent
!= GetDesktopWindow() &&
842 SendMessageA( parent
, WM_SETCURSOR
, wParam
, lParam
))
847 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
851 return (DefWndHandleSysCommand(hWnd
, wParam
, lParam
));
854 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
859 if (HIWORD(lParam
) & KF_ALTDOWN
)
860 { /* Previous state, if the key was down before this message,
861 this is a cheap way to ignore autorepeat keys. */
862 if ( !(HIWORD(lParam
) & KF_REPEAT
) )
864 if ( ( wParam
== VK_MENU
||
865 wParam
== VK_LMENU
||
866 wParam
== VK_RMENU
) && !iMenuSysKey
)
874 if (wParam
== VK_F4
) /* Try to close the window */
876 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
877 if (!(GetClassLongPtrW(top
, GCL_STYLE
) & CS_NOCLOSE
))
878 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
880 else if (wParam
== VK_SNAPSHOT
) // Alt-VK_SNAPSHOT?
883 while (GetParent(hwnd
) != NULL
)
885 hwnd
= GetParent(hwnd
);
887 DefWndScreenshot(hwnd
);
889 else if ( wParam
== VK_ESCAPE
|| wParam
== VK_TAB
) // Alt-Tab/ESC Alt-Shift-Tab/ESC
892 HWND Active
= GetActiveWindow(); // Noticed MDI problem.
895 FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n");
898 wParamTmp
= GetKeyState(VK_SHIFT
) & 0x8000 ? SC_PREVWINDOW
: SC_NEXTWINDOW
;
899 SendMessageW( Active
, WM_SYSCOMMAND
, wParamTmp
, wParam
);
902 else if( wParam
== VK_F10
)
904 if (GetKeyState(VK_SHIFT
) & 0x8000)
905 SendMessageW( hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, MAKELPARAM(-1, -1) );
914 /* Press and release F10 or ALT */
915 if (((wParam
== VK_MENU
|| wParam
== VK_LMENU
|| wParam
== VK_RMENU
)
916 && iMenuSysKey
) || ((wParam
== VK_F10
) && iF10Key
))
917 SendMessageW( GetAncestor( hWnd
, GA_ROOT
), WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
918 iMenuSysKey
= iF10Key
= 0;
925 if (wParam
== VK_RETURN
&& IsIconic(hWnd
))
927 PostMessageW( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0L );
930 if ((HIWORD(lParam
) & KF_ALTDOWN
) && wParam
)
932 if (wParam
== VK_TAB
|| wParam
== VK_ESCAPE
) break;
933 if (wParam
== VK_SPACE
&& (GetWindowLongPtrW( hWnd
, GWL_STYLE
) & WS_CHILD
))
934 SendMessageW( GetParent(hWnd
), Msg
, wParam
, lParam
);
936 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, wParam
);
938 else /* check for Ctrl-Esc */
939 if (wParam
!= VK_ESCAPE
) MessageBeep(0);
946 /* FIXME: Check for a desktop. */
947 //if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
948 MENU_EndMenu( hWnd
);
949 if (GetCapture() == hWnd
)
963 case WM_QUERYDROPOBJECT
:
965 if (GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
972 case WM_QUERYDRAGICON
:
977 hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
);
980 return ((LRESULT
)hIcon
);
982 for (Len
= 1; Len
< 64; Len
++)
984 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
986 return((LRESULT
)hIcon
);
989 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
992 case WM_ISACTIVEICON
:
995 isai
= (pWnd
->state
& WNDS_ACTIVEFRAME
) != 0;
999 case WM_NOTIFYFORMAT
:
1001 if (lParam
== NF_QUERY
)
1002 return IsWindowUnicode(hWnd
) ? NFR_UNICODE
: NFR_ANSI
;
1008 return DefWndSetIcon(pWnd
, wParam
, lParam
);
1013 return DefWndGetIcon(pWnd
, wParam
, lParam
);
1020 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1024 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1031 THRDCARETINFO CaretInfo
;
1034 case 0xffff: /* Caret timer */
1035 /* switch showing byte in win32k and get information about the caret */
1036 if(NtUserxSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1038 DrawCaret(hWnd
, &CaretInfo
);
1046 case WM_QUERYENDSESSION
:
1051 case WM_INPUTLANGCHANGEREQUEST
:
1055 if(wParam
& INPUTLANGCHANGE_BACKWARD
1056 && wParam
& INPUTLANGCHANGE_FORWARD
)
1061 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1063 if(wParam
& INPUTLANGCHANGE_BACKWARD
) NewHkl
= (HKL
) HKL_PREV
;
1064 else if(wParam
& INPUTLANGCHANGE_FORWARD
) NewHkl
= (HKL
) HKL_NEXT
;
1065 else NewHkl
= (HKL
) lParam
;
1067 NtUserActivateKeyboardLayout(NewHkl
, 0);
1072 case WM_INPUTLANGCHANGE
:
1075 HWND
*win_array
= WIN_ListChildren( hWnd
);
1079 while (win_array
[count
])
1080 SendMessageW( win_array
[count
++], WM_INPUTLANGCHANGE
, wParam
, lParam
);
1081 HeapFree(GetProcessHeap(),0,win_array
);
1085 case WM_QUERYUISTATE
:
1088 PWND Wnd
= ValidateHwnd(hWnd
);
1092 Ret
|= UISF_HIDEFOCUS
;
1094 Ret
|= UISF_HIDEACCEL
;
1099 case WM_CHANGEUISTATE
:
1101 BOOL AlwaysShowCues
= FALSE
;
1102 WORD Action
= LOWORD(wParam
);
1103 WORD Flags
= HIWORD(wParam
);
1106 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1110 Wnd
= ValidateHwnd(hWnd
);
1111 if (!Wnd
|| lParam
!= 0)
1114 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1117 if (Flags
& UISF_ACTIVE
)
1119 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1122 if (Action
== UIS_INITIALIZE
)
1124 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1128 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1129 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1131 /* We need to update wParam in case we need to send out messages */
1132 wParam
= MAKEWPARAM(Action
, Flags
);
1138 /* See if we actually need to change something */
1139 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1141 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1144 /* Don't need to do anything... */
1148 /* See if we actually need to change something */
1149 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1151 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1154 /* Don't need to do anything... */
1158 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1162 if ((Wnd
->style
& WS_CHILD
) && Wnd
->spwndParent
!= NULL
)
1164 /* We're a child window and we need to pass this message down until
1165 we reach the root */
1166 hWnd
= UserHMGetHandle((PWND
)DesktopPtrToUser(Wnd
->spwndParent
));
1170 /* We're a top level window, we need to change the UI state */
1171 Msg
= WM_UPDATEUISTATE
;
1175 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1177 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1180 case WM_UPDATEUISTATE
:
1183 BOOL AlwaysShowCues
= FALSE
;
1184 WORD Action
= LOWORD(wParam
);
1185 WORD Flags
= HIWORD(wParam
);
1188 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1192 Wnd
= ValidateHwnd(hWnd
);
1193 if (!Wnd
|| lParam
!= 0)
1196 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1199 if (Flags
& UISF_ACTIVE
)
1201 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1204 if (Action
== UIS_INITIALIZE
)
1206 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1210 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1211 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1213 /* We need to update wParam for broadcasting the update */
1214 wParam
= MAKEWPARAM(Action
, Flags
);
1220 /* See if we actually need to change something */
1221 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1223 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1226 /* Don't need to do anything... */
1231 /* See if we actually need to change something */
1232 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1234 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1237 /* Don't need to do anything... */
1242 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1246 /* Pack the information and call win32k */
1249 if (!NtUserxUpdateUiState(hWnd
, Flags
| ((DWORD
)Action
<< 3)))
1253 /* Always broadcast the update to all children */
1254 EnumChildWindows(hWnd
,
1255 UserSendUiUpdateMsg
,
1261 /* Move to Win32k !*/
1263 if (!lParam
) break; // Call when it is necessary.
1266 case WM_CLIENTSHUTDOWN
:
1269 case WM_WINDOWPOSCHANGING
:
1270 case WM_WINDOWPOSCHANGED
:
1274 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, !bUnicode
);
1283 * helpers for calling IMM32 (from Wine 10/22/2008)
1285 * WM_IME_* messages are generated only by IMM32,
1286 * so I assume imm32 is already LoadLibrary-ed.
1289 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1291 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1292 HWND (WINAPI
*pFunc
)(HWND
);
1297 ERR("cannot get IMM32 handle\n");
1301 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1303 hwndRet
= (*pFunc
)(hwnd
);
1310 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1312 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1313 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1318 ERR("cannot get IMM32 handle\n");
1322 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1324 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1331 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1333 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1334 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1339 ERR("cannot get IMM32 handle\n");
1343 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1345 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1352 RealDefWindowProcA(HWND hWnd
,
1360 Wnd
= ValidateHwnd(hWnd
);
1363 Msg
!= WM_CTLCOLORMSGBOX
&&
1364 Msg
!= WM_CTLCOLORBTN
&&
1365 Msg
!= WM_CTLCOLORDLG
&&
1366 Msg
!= WM_CTLCOLORSTATIC
)
1369 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1375 Wnd
->style
& (WS_HSCROLL
| WS_VSCROLL
) )
1379 SCROLLINFO si
= {sizeof si
, SIF_ALL
, 0, 100, 0, 0, 0};
1380 SetScrollInfo( hWnd
, SB_HORZ
, &si
, FALSE
);
1381 SetScrollInfo( hWnd
, SB_VERT
, &si
, FALSE
);
1387 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1388 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1389 * may have child window IDs instead of window name */
1390 if (HIWORD(cs
->lpszName
))
1392 DefSetText(hWnd
, (PCWSTR
)cs
->lpszName
, TRUE
);
1399 case WM_GETTEXTLENGTH
:
1404 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
1406 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1408 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1410 Wnd
->strName
.Length
)))
1412 Result
= (LRESULT
) len
;
1423 PSTR outbuf
= (PSTR
)lParam
;
1426 if (Wnd
!= NULL
&& wParam
!= 0)
1428 if (Wnd
->strName
.Buffer
!= NULL
)
1429 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1435 if (Wnd
->strName
.Length
!= 0)
1437 copy
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1438 Result
= WideCharToMultiByte(CP_ACP
,
1446 outbuf
[Result
] = '\0';
1457 DefSetText(hWnd
, (PCWSTR
)lParam
, TRUE
);
1459 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1461 /* FIXME: this is not 100% correct */
1462 if(gpsi
->dwSRVIFlags
& SRVINFO_APIHOOK
)
1464 SendMessage(hWnd
, WM_NCUAHDRAWCAPTION
,0,0);
1468 DefWndNCPaint(hWnd
, HRGN_WINDOW
, -1);
1475 case WM_IME_KEYDOWN
:
1477 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
1483 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
1490 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
1491 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
1495 case WM_IME_STARTCOMPOSITION
:
1496 case WM_IME_COMPOSITION
:
1497 case WM_IME_ENDCOMPOSITION
:
1503 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
1505 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
1509 case WM_IME_SETCONTEXT
:
1513 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
1515 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
1521 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
1524 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
1530 RealDefWindowProcW(HWND hWnd
,
1538 Wnd
= ValidateHwnd(hWnd
);
1541 Msg
!= WM_CTLCOLORMSGBOX
&&
1542 Msg
!= WM_CTLCOLORBTN
&&
1543 Msg
!= WM_CTLCOLORDLG
&&
1544 Msg
!= WM_CTLCOLORSTATIC
)
1547 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1553 Wnd
->style
& (WS_HSCROLL
| WS_VSCROLL
) )
1557 SCROLLINFO si
= {sizeof si
, SIF_ALL
, 0, 100, 0, 0, 0};
1558 SetScrollInfo( hWnd
, SB_HORZ
, &si
, FALSE
);
1559 SetScrollInfo( hWnd
, SB_VERT
, &si
, FALSE
);
1565 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
1566 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1567 * may have child window IDs instead of window name */
1568 if (HIWORD(cs
->lpszName
))
1570 DefSetText(hWnd
, cs
->lpszName
, FALSE
);
1577 case WM_GETTEXTLENGTH
:
1582 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
1584 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1586 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1588 Wnd
->strName
.Length
)))
1590 Result
= (LRESULT
) (Wnd
->strName
.Length
/ sizeof(WCHAR
));
1601 PWSTR outbuf
= (PWSTR
)lParam
;
1603 if (Wnd
!= NULL
&& wParam
!= 0)
1605 if (Wnd
->strName
.Buffer
!= NULL
)
1606 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1612 if (Wnd
->strName
.Length
!= 0)
1614 Result
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1615 RtlCopyMemory(outbuf
,
1617 Result
* sizeof(WCHAR
));
1618 outbuf
[Result
] = L
'\0';
1629 DefSetText(hWnd
, (PCWSTR
)lParam
, FALSE
);
1631 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1633 /* FIXME: this is not 100% correct */
1634 if(gpsi
->dwSRVIFlags
& SRVINFO_APIHOOK
)
1636 SendMessage(hWnd
, WM_NCUAHDRAWCAPTION
,0,0);
1640 DefWndNCPaint(hWnd
, HRGN_WINDOW
, -1);
1649 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
1654 case WM_IME_KEYDOWN
:
1656 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
1662 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
1666 case WM_IME_STARTCOMPOSITION
:
1667 case WM_IME_COMPOSITION
:
1668 case WM_IME_ENDCOMPOSITION
:
1674 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
1676 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
1680 case WM_IME_SETCONTEXT
:
1684 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
1686 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
1691 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
1693 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
1699 DefWindowProcA(HWND hWnd
,
1704 BOOL Hook
, msgOverride
= FALSE
;
1709 Hook
= BeginIfHookedUserApiHook();
1712 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
1713 if(msgOverride
== FALSE
)
1719 /* Bypass SEH and go direct. */
1720 if (!Hook
|| !msgOverride
)
1721 return RealDefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
1725 Result
= guah
.DefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
1727 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1738 DefWindowProcW(HWND hWnd
,
1743 BOOL Hook
, msgOverride
= FALSE
;
1748 Hook
= BeginIfHookedUserApiHook();
1751 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
1752 if(msgOverride
== FALSE
)
1758 /* Bypass SEH and go direct. */
1759 if (!Hook
|| !msgOverride
)
1760 return RealDefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
1764 Result
= guah
.DefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
1766 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)