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
)
758 if (!IsWindowEnabled( hWnd
)) return 0;
760 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 NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
824 FIXME("Implement Alt-Tab!!! wParam 0x%x lParam 0x%x\n",wParam
,lParam
);
829 HWND hwnd
, hWndLastActive
;
832 PWND pWnd
= ValidateHwnd(hwnd
);
835 hWndLastActive
= GetLastActivePopup(hwnd
);
838 hwnd
= hWndLastActive
;
839 pWnd
= ValidateHwnd(hwnd
);
841 SetForegroundWindow(hwnd
);
842 if (pWnd
->style
& WS_MINIMIZE
)
844 PostMessage(hwnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
851 FIXME("Unimplemented DefWndHandleSysCommand wParam 0x%x\n",wParam
);
859 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
861 POINT maxTrack
, minTrack
;
862 LONG style
= GetWindowLongPtrA(hWnd
, GWL_STYLE
);
864 if (Pos
->flags
& SWP_NOSIZE
) return 0;
865 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
867 WinPosGetMinMaxInfo(hWnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
868 Pos
->cx
= min(Pos
->cx
, maxTrack
.x
);
869 Pos
->cy
= min(Pos
->cy
, maxTrack
.y
);
870 if (!(style
& WS_MINIMIZE
))
872 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
873 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
878 Pos
->cx
= max(Pos
->cx
, 0);
879 Pos
->cy
= max(Pos
->cy
, 0);
885 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
889 GetClientRect(hWnd
, &Rect
);
890 MapWindowPoints(hWnd
, (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
?
891 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
893 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
895 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
898 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
900 WPARAM wp
= SIZE_RESTORED
;
905 else if (IsIconic(hWnd
))
909 SendMessageW(hWnd
, WM_SIZE
, wp
,
910 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
916 /***********************************************************************
919 * Default colors for control painting.
922 DefWndControlColor(HDC hDC
, UINT ctlType
)
924 if (CTLCOLOR_SCROLLBAR
== ctlType
)
926 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
927 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
928 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
931 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
932 * we better use 0x55aa bitmap brush to make scrollbar's background
933 * look different from the window background.
935 if (bk
== GetSysColor(COLOR_WINDOW
))
937 static const WORD wPattern55AA
[] =
939 0x5555, 0xaaaa, 0x5555, 0xaaaa,
940 0x5555, 0xaaaa, 0x5555, 0xaaaa
942 static HBITMAP hPattern55AABitmap
= NULL
;
943 static HBRUSH hPattern55AABrush
= NULL
;
944 if (hPattern55AABrush
== NULL
)
946 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
947 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
949 return hPattern55AABrush
;
955 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
957 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
959 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
963 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
964 return GetSysColorBrush(COLOR_3DFACE
);
967 return GetSysColorBrush(COLOR_WINDOW
);
970 static void DefWndPrint( HWND hwnd
, HDC hdc
, ULONG uFlags
)
975 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
976 !IsWindowVisible(hwnd
) )
980 * Unimplemented flags.
982 if ( (uFlags
& PRF_CHILDREN
) ||
983 (uFlags
& PRF_OWNED
) ||
984 (uFlags
& PRF_NONCLIENT
) )
986 FIXME("WM_PRINT message with unsupported flags\n");
992 if ( uFlags
& PRF_ERASEBKGND
)
993 SendMessageW(hwnd
, WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
998 if ( uFlags
& PRF_CLIENT
)
999 SendMessageW(hwnd
, WM_PRINTCLIENT
, (WPARAM
)hdc
, uFlags
);
1002 static BOOL CALLBACK
1003 UserSendUiUpdateMsg(HWND hwnd
, LPARAM lParam
)
1005 SendMessageW(hwnd
, WM_UPDATEUISTATE
, (WPARAM
)lParam
, 0);
1011 DefWndScreenshot(HWND hWnd
)
1020 OpenClipboard(hWnd
);
1023 hdc
= GetWindowDC(hWnd
);
1024 GetWindowRect(hWnd
, &rect
);
1025 w
= rect
.right
- rect
.left
;
1026 h
= rect
.bottom
- rect
.top
;
1028 hbitmap
= CreateCompatibleBitmap(hdc
, w
, h
);
1029 hdc2
= CreateCompatibleDC(hdc
);
1030 SelectObject(hdc2
, hbitmap
);
1032 BitBlt(hdc2
, 0, 0, w
, h
,
1036 SetClipboardData(CF_BITMAP
, hbitmap
);
1038 ReleaseDC(hWnd
, hdc
);
1039 ReleaseDC(hWnd
, hdc2
);
1048 User32DefWindowProc(HWND hWnd
,
1058 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
1063 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
1066 case WM_POPUPSYSTEMMENU
:
1068 /* This is an undocumented message used by the windows taskbar to
1069 display the system menu of windows that belong to other processes. */
1070 HMENU menu
= GetSystemMenu(hWnd
, FALSE
);
1073 TrackPopupMenu(menu
, TPM_LEFTBUTTON
|TPM_RIGHTBUTTON
,
1074 LOWORD(lParam
), HIWORD(lParam
), 0, hWnd
, NULL
);
1080 return DefWndNCActivate(hWnd
, wParam
);
1086 Point
.x
= GET_X_LPARAM(lParam
);
1087 Point
.y
= GET_Y_LPARAM(lParam
);
1088 return (DefWndNCHitTest(hWnd
, Point
));
1091 case WM_LBUTTONDOWN
:
1092 case WM_RBUTTONDOWN
:
1093 case WM_MBUTTONDOWN
:
1094 iF10Key
= iMenuSysKey
= 0;
1097 case WM_NCLBUTTONDOWN
:
1099 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
1102 case WM_LBUTTONDBLCLK
:
1103 return (DefWndNCLButtonDblClk(hWnd
, HTCLIENT
, lParam
));
1105 case WM_NCLBUTTONDBLCLK
:
1107 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
1110 case WM_WINDOWPOSCHANGING
:
1112 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1115 case WM_WINDOWPOSCHANGED
:
1117 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
1120 case WM_NCRBUTTONDOWN
:
1122 /* in Windows, capture is taken when right-clicking on the caption bar */
1123 if (wParam
== HTCAPTION
)
1133 if (hWnd
== GetCapture())
1137 Pt
.x
= GET_X_LPARAM(lParam
);
1138 Pt
.y
= GET_Y_LPARAM(lParam
);
1139 ClientToScreen(hWnd
, &Pt
);
1140 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1143 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1147 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1152 case WM_NCRBUTTONUP
:
1154 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1155 * in Windows), but what _should_ we do? According to MSDN :
1156 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1157 * message to the window". When is it appropriate?
1161 case WM_CONTEXTMENU
:
1163 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1167 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1171 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1180 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1182 Pt
.x
= GET_X_LPARAM(lParam
);
1183 Pt
.y
= GET_Y_LPARAM(lParam
);
1184 if (Style
& WS_CHILD
)
1186 ScreenToClient(GetParent(hWnd
), &Pt
);
1189 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1191 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1196 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1198 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongPtrW(hWnd
, GWL_STYLE
),
1199 GetClassLongPtrW(hWnd
, GCL_STYLE
), HitCode
);
1201 if(HitCode
== HTCAPTION
)
1202 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1204 Flags
= TPM_LEFTBUTTON
;
1206 TrackPopupMenu(SystemMenu
, Flags
,
1207 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1216 DefWndPrint(hWnd
, (HDC
)wParam
, lParam
);
1220 case WM_SYSCOLORCHANGE
:
1222 /* force to redraw non-client area */
1223 DefWndNCPaint(hWnd
, HRGN_WINDOW
, -1);
1224 /* Use InvalidateRect to redraw client area, enable
1225 * erase to redraw all subcontrols otherwise send the
1226 * WM_SYSCOLORCHANGE to child windows/controls is required
1228 InvalidateRect(hWnd
,NULL
,TRUE
);
1236 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1241 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1242 (hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
)) != NULL
)
1246 GetClientRect(hWnd
, &ClientRect
);
1247 x
= (ClientRect
.right
- ClientRect
.left
-
1248 GetSystemMetrics(SM_CXICON
)) / 2;
1249 y
= (ClientRect
.bottom
- ClientRect
.top
-
1250 GetSystemMetrics(SM_CYICON
)) / 2;
1251 DrawIcon(hDC
, x
, y
, hIcon
);
1253 EndPaint(hWnd
, &Ps
);
1261 hRgn
= CreateRectRgn(0, 0, 0, 0);
1262 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1264 RedrawWindow(hWnd
, NULL
, hRgn
,
1265 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1274 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1275 if (wParam
) SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
| WS_VISIBLE
);
1278 RedrawWindow(hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
1279 Style
&= ~WS_VISIBLE
;
1280 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
);
1287 DestroyWindow(hWnd
);
1291 case WM_MOUSEACTIVATE
:
1293 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1298 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1303 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1311 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1316 /* Check if the window is minimized. */
1317 if (LOWORD(wParam
) != WA_INACTIVE
&&
1318 !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1327 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1331 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1336 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1344 case WM_ICONERASEBKGND
:
1347 HBRUSH hBrush
= (HBRUSH
)GetClassLongPtrW(hWnd
, GCL_HBRBACKGROUND
);
1353 if (GetClassLongPtrW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1355 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1356 GetClientRect(hWnd
, &Rect
);
1357 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1361 GetClipBox((HDC
)wParam
, &Rect
);
1363 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1367 case WM_CTLCOLORMSGBOX
:
1368 case WM_CTLCOLOREDIT
:
1369 case WM_CTLCOLORLISTBOX
:
1370 case WM_CTLCOLORBTN
:
1371 case WM_CTLCOLORDLG
:
1372 case WM_CTLCOLORSTATIC
:
1373 case WM_CTLCOLORSCROLLBAR
:
1374 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1377 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
1381 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1383 if (Style
& WS_CHILD
)
1385 /* with the exception of the border around a resizable wnd,
1386 * give the parent first chance to set the cursor */
1387 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1389 HWND parent
= GetParent( hWnd
);
1392 if (parent
!= GetDesktopWindow() &&
1393 SendMessageW( parent
, WM_SETCURSOR
, wParam
, lParam
))
1398 if (parent
!= GetDesktopWindow() &&
1399 SendMessageA( parent
, WM_SETCURSOR
, wParam
, lParam
))
1404 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1408 return (DefWndHandleSysCommand(hWnd
, wParam
, lParam
));
1411 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
1416 if (HIWORD(lParam
) & KEYDATA_ALT
)
1417 { /* Previous state, if the key was down before this message,
1418 this is a cheap way to ignore autorepeat keys. */
1419 if ( !(HIWORD(lParam
) & KEYDATA_PREVSTATE
) )
1421 if ( ( wParam
== VK_MENU
||
1422 wParam
== VK_LMENU
||
1423 wParam
== VK_RMENU
) && !iMenuSysKey
)
1431 if (wParam
== VK_F4
) /* Try to close the window */
1433 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1434 if (!(GetClassLongPtrW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1435 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1437 else if (wParam
== VK_SNAPSHOT
) // Alt-VK_SNAPSHOT?
1440 while (GetParent(hwnd
) != NULL
)
1442 hwnd
= GetParent(hwnd
);
1444 DefWndScreenshot(hwnd
);
1446 else if ( wParam
== VK_ESCAPE
|| wParam
== VK_TAB
) // Alt-Tab/ESC Alt-Shift-Tab/ESC
1449 HWND Active
= GetActiveWindow(); // Noticed MDI problem.
1452 FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n");
1455 wParamTmp
= GetKeyState(VK_SHIFT
) & 0x8000 ? SC_PREVWINDOW
: SC_NEXTWINDOW
;
1456 SendMessageW( Active
, WM_SYSCOMMAND
, wParamTmp
, wParam
);
1459 else if( wParam
== VK_F10
)
1461 if (GetKeyState(VK_SHIFT
) & 0x8000)
1462 SendMessageW( hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, MAKELPARAM(-1, -1) );
1471 /* Press and release F10 or ALT */
1472 if (((wParam
== VK_MENU
|| wParam
== VK_LMENU
|| wParam
== VK_RMENU
)
1473 && iMenuSysKey
) || ((wParam
== VK_F10
) && iF10Key
))
1474 SendMessageW( GetAncestor( hWnd
, GA_ROOT
), WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1475 iMenuSysKey
= iF10Key
= 0;
1482 if (wParam
== VK_RETURN
&& IsIconic(hWnd
))
1484 PostMessageW( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0L );
1487 if ((HIWORD(lParam
) & KEYDATA_ALT
) && wParam
)
1489 if (wParam
== VK_TAB
|| wParam
== VK_ESCAPE
) break;
1490 if (wParam
== VK_SPACE
&& (GetWindowLongPtrW( hWnd
, GWL_STYLE
) & WS_CHILD
))
1491 SendMessageW( GetParent(hWnd
), Msg
, wParam
, lParam
);
1493 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, wParam
);
1495 else /* check for Ctrl-Esc */
1496 if (wParam
!= VK_ESCAPE
) MessageBeep(0);
1503 /* FIXME: Check for a desktop. */
1504 //if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
1505 MENU_EndMenu( hWnd
);
1506 if (GetCapture() == hWnd
)
1520 case WM_QUERYDROPOBJECT
:
1522 if (GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1529 case WM_QUERYDRAGICON
:
1534 hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
);
1537 return ((LRESULT
)hIcon
);
1539 for (Len
= 1; Len
< 64; Len
++)
1541 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1543 return((LRESULT
)hIcon
);
1546 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1549 case WM_ISACTIVEICON
:
1553 pWnd
= ValidateHwnd(hWnd
);
1554 if (!pWnd
) return 0;
1555 isai
= (pWnd
->state
& WNDS_ACTIVEFRAME
) != 0;
1559 case WM_NOTIFYFORMAT
:
1561 if (lParam
== NF_QUERY
)
1562 return IsWindowUnicode(hWnd
) ? NFR_UNICODE
: NFR_ANSI
;
1568 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1569 HICON hOldIcon
= (HICON
)GetClassLongPtrW(hWnd
, Index
);
1570 SetClassLongPtrW(hWnd
, Index
, lParam
);
1571 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1572 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1573 SWP_NOACTIVATE
| SWP_NOZORDER
);
1574 return ((LRESULT
)hOldIcon
);
1579 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1580 return (GetClassLongPtrW(hWnd
, Index
));
1587 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1591 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1598 THRDCARETINFO CaretInfo
;
1601 case 0xffff: /* Caret timer */
1602 /* switch showing byte in win32k and get information about the caret */
1603 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1605 DrawCaret(hWnd
, &CaretInfo
);
1613 case WM_QUERYENDSESSION
:
1618 case WM_INPUTLANGCHANGEREQUEST
:
1622 if(wParam
& INPUTLANGCHANGE_BACKWARD
1623 && wParam
& INPUTLANGCHANGE_FORWARD
)
1628 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1630 if(wParam
& INPUTLANGCHANGE_BACKWARD
) NewHkl
= (HKL
) HKL_PREV
;
1631 else if(wParam
& INPUTLANGCHANGE_FORWARD
) NewHkl
= (HKL
) HKL_NEXT
;
1632 else NewHkl
= (HKL
) lParam
;
1634 NtUserActivateKeyboardLayout(NewHkl
, 0);
1639 case WM_INPUTLANGCHANGE
:
1642 HWND
*win_array
= WIN_ListChildren( hWnd
);
1646 while (win_array
[count
])
1647 SendMessageW( win_array
[count
++], WM_INPUTLANGCHANGE
, wParam
, lParam
);
1648 HeapFree(GetProcessHeap(),0,win_array
);
1652 case WM_QUERYUISTATE
:
1655 PWND Wnd
= ValidateHwnd(hWnd
);
1659 Ret
|= UISF_HIDEFOCUS
;
1661 Ret
|= UISF_HIDEACCEL
;
1666 case WM_CHANGEUISTATE
:
1668 BOOL AlwaysShowCues
= FALSE
;
1669 WORD Action
= LOWORD(wParam
);
1670 WORD Flags
= HIWORD(wParam
);
1673 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1677 Wnd
= ValidateHwnd(hWnd
);
1678 if (!Wnd
|| lParam
!= 0)
1681 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1684 if (Flags
& UISF_ACTIVE
)
1686 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1689 if (Action
== UIS_INITIALIZE
)
1691 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1695 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1696 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1698 /* We need to update wParam in case we need to send out messages */
1699 wParam
= MAKEWPARAM(Action
, Flags
);
1705 /* See if we actually need to change something */
1706 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1708 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1711 /* Don't need to do anything... */
1715 /* See if we actually need to change something */
1716 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1718 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1721 /* Don't need to do anything... */
1725 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1729 if ((Wnd
->style
& WS_CHILD
) && Wnd
->spwndParent
!= NULL
)
1731 /* We're a child window and we need to pass this message down until
1732 we reach the root */
1733 hWnd
= UserHMGetHandle((PWND
)DesktopPtrToUser(Wnd
->spwndParent
));
1737 /* We're a top level window, we need to change the UI state */
1738 Msg
= WM_UPDATEUISTATE
;
1742 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1744 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1747 case WM_UPDATEUISTATE
:
1750 BOOL AlwaysShowCues
= FALSE
;
1751 WORD Action
= LOWORD(wParam
);
1752 WORD Flags
= HIWORD(wParam
);
1755 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1759 Wnd
= ValidateHwnd(hWnd
);
1760 if (!Wnd
|| lParam
!= 0)
1763 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1766 if (Flags
& UISF_ACTIVE
)
1768 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1771 if (Action
== UIS_INITIALIZE
)
1773 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1777 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1778 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1780 /* We need to update wParam for broadcasting the update */
1781 wParam
= MAKEWPARAM(Action
, Flags
);
1787 /* See if we actually need to change something */
1788 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1790 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1793 /* Don't need to do anything... */
1798 /* See if we actually need to change something */
1799 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1801 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1804 /* Don't need to do anything... */
1809 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1813 /* Pack the information and call win32k */
1816 if (!NtUserCallTwoParam((DWORD_PTR
)hWnd
, (DWORD_PTR
)Flags
| ((DWORD_PTR
)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE
))
1820 /* Always broadcast the update to all children */
1821 EnumChildWindows(hWnd
,
1822 UserSendUiUpdateMsg
,
1828 /* Move to win32k !*/
1830 if (!lParam
) break; // Call when it is necessary.
1831 case WM_CLIENTSHUTDOWN
:
1836 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, !bUnicode
);
1845 * helpers for calling IMM32 (from Wine 10/22/2008)
1847 * WM_IME_* messages are generated only by IMM32,
1848 * so I assume imm32 is already LoadLibrary-ed.
1851 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1853 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1854 HWND (WINAPI
*pFunc
)(HWND
);
1859 ERR("cannot get IMM32 handle\n");
1863 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1865 hwndRet
= (*pFunc
)(hwnd
);
1872 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1874 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1875 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1880 ERR("cannot get IMM32 handle\n");
1884 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1886 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1893 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1895 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1896 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1901 ERR("cannot get IMM32 handle\n");
1905 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1907 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1914 RealDefWindowProcA(HWND hWnd
,
1922 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1929 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1930 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1931 * may have child window IDs instead of window name */
1932 if (HIWORD(cs
->lpszName
))
1934 DefSetText(hWnd
, (PCWSTR
)cs
->lpszName
, TRUE
);
1941 case WM_GETTEXTLENGTH
:
1946 Wnd
= ValidateHwnd(hWnd
);
1947 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
1949 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1951 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1953 Wnd
->strName
.Length
)))
1955 Result
= (LRESULT
) len
;
1966 PSTR outbuf
= (PSTR
)lParam
;
1969 Wnd
= ValidateHwnd(hWnd
);
1970 if (Wnd
!= NULL
&& wParam
!= 0)
1972 if (Wnd
->strName
.Buffer
!= NULL
)
1973 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1979 if (Wnd
->strName
.Length
!= 0)
1981 copy
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1982 Result
= WideCharToMultiByte(CP_ACP
,
1990 outbuf
[Result
] = '\0';
2001 DefSetText(hWnd
, (PCWSTR
)lParam
, TRUE
);
2003 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2005 DefWndNCPaint(hWnd
, HRGN_WINDOW
, -1);
2011 case WM_IME_KEYDOWN
:
2013 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2019 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
2026 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
2027 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
2031 case WM_IME_STARTCOMPOSITION
:
2032 case WM_IME_COMPOSITION
:
2033 case WM_IME_ENDCOMPOSITION
:
2039 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2041 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
2045 case WM_IME_SETCONTEXT
:
2049 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2051 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
2057 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2060 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2066 RealDefWindowProcW(HWND hWnd
,
2074 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
2081 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
2082 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2083 * may have child window IDs instead of window name */
2084 if (HIWORD(cs
->lpszName
))
2086 DefSetText(hWnd
, cs
->lpszName
, FALSE
);
2093 case WM_GETTEXTLENGTH
:
2098 Wnd
= ValidateHwnd(hWnd
);
2099 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
2101 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2103 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
2105 Wnd
->strName
.Length
)))
2107 Result
= (LRESULT
) (Wnd
->strName
.Length
/ sizeof(WCHAR
));
2118 PWSTR outbuf
= (PWSTR
)lParam
;
2120 Wnd
= ValidateHwnd(hWnd
);
2121 if (Wnd
!= NULL
&& wParam
!= 0)
2123 if (Wnd
->strName
.Buffer
!= NULL
)
2124 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2130 if (Wnd
->strName
.Length
!= 0)
2132 Result
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
2133 RtlCopyMemory(outbuf
,
2135 Result
* sizeof(WCHAR
));
2136 outbuf
[Result
] = L
'\0';
2147 DefSetText(hWnd
, (PCWSTR
)lParam
, FALSE
);
2149 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2151 DefWndNCPaint(hWnd
, HRGN_WINDOW
, -1);
2159 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
2164 case WM_IME_KEYDOWN
:
2166 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2172 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
2176 case WM_IME_STARTCOMPOSITION
:
2177 case WM_IME_COMPOSITION
:
2178 case WM_IME_ENDCOMPOSITION
:
2184 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2186 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
2190 case WM_IME_SETCONTEXT
:
2194 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2196 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
2201 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
2203 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2209 DefWindowProcA(HWND hWnd
,
2214 BOOL Hook
, msgOverride
= FALSE
;
2219 Hook
= BeginIfHookedUserApiHook();
2221 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2223 /* Bypass SEH and go direct. */
2224 if (!Hook
|| !msgOverride
)
2225 return RealDefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2229 Result
= guah
.DefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2231 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2242 DefWindowProcW(HWND hWnd
,
2247 BOOL Hook
, msgOverride
= FALSE
;
2252 Hook
= BeginIfHookedUserApiHook();
2254 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2256 /* Bypass SEH and go direct. */
2257 if (!Hook
|| !msgOverride
)
2258 return RealDefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2262 Result
= guah
.DefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2264 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)