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
);
20 #define WM_SETVISIBLE 9
22 #ifndef WM_QUERYDROPOBJECT
23 #define WM_QUERYDROPOBJECT 0x022B
26 LRESULT
DefWndNCPaint(HWND hWnd
, HRGN hRgn
, BOOL Active
);
27 LRESULT
DefWndNCCalcSize(HWND hWnd
, BOOL CalcSizeStruct
, RECT
*Rect
);
28 LRESULT
DefWndNCActivate(HWND hWnd
, WPARAM wParam
);
29 LRESULT
DefWndNCHitTest(HWND hWnd
, POINT Point
);
30 LRESULT
DefWndNCLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
31 LRESULT
DefWndNCLButtonDblClk(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
32 void FASTCALL
MenuInitSysMenuPopup(HMENU Menu
, DWORD Style
, DWORD ClsStyle
, LONG HitTest
);
33 void MENU_EndMenu( HWND
);
35 /* GLOBALS *******************************************************************/
37 /* Bits in the dwKeyData */
38 #define KEYDATA_ALT 0x2000
39 #define KEYDATA_PREVSTATE 0x4000
41 static short iF10Key
= 0;
42 static short iMenuSysKey
= 0;
44 /* FUNCTIONS *****************************************************************/
47 InitStockObjects(void)
49 /* FIXME - Instead of copying the stuff to usermode we should map the tables to
50 userland. The current implementation has one big flaw: the system color
51 table doesn't get updated when another process changes them. That's why
52 we should rather map the table into usermode. But it only affects the
53 SysColors table - the pens, brushes and stock objects are not affected
54 as their handles never change. But it'd be faster to map them, too. */
63 GetSysColor(int nIndex
)
65 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
67 return gpsi
->argbSystem
[nIndex
];
70 SetLastError(ERROR_INVALID_PARAMETER
);
78 GetSysColorBrush(int nIndex
)
80 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
82 return gpsi
->ahbrSystem
[nIndex
];
85 SetLastError(ERROR_INVALID_PARAMETER
);
96 CONST INT
*lpaElements
,
97 CONST COLORREF
*lpaRgbValues
)
99 return NtUserSetSysColors(cElements
, lpaElements
, lpaRgbValues
, 0);
104 DefSetText(HWND hWnd
, PCWSTR String
, BOOL Ansi
)
107 LARGE_STRING lsString
;
112 RtlInitLargeAnsiString((PLARGE_ANSI_STRING
)&lsString
, (PCSZ
)String
, 0);
114 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING
)&lsString
, String
, 0);
116 Ret
= NtUserDefSetText(hWnd
, (String
? &lsString
: NULL
));
119 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE
, hWnd
, OBJID_WINDOW
, CHILDID_SELF
, 0);
125 UserGetInsideRectNC(PWND Wnd
, RECT
*rect
)
131 ExStyle
= Wnd
->ExStyle
;
133 rect
->top
= rect
->left
= 0;
134 rect
->right
= Wnd
->rcWindow
.right
- Wnd
->rcWindow
.left
;
135 rect
->bottom
= Wnd
->rcWindow
.bottom
- Wnd
->rcWindow
.top
;
137 if (Style
& WS_ICONIC
)
142 /* Remove frame from rectangle */
143 if (UserHasThickFrameStyle(Style
, ExStyle
))
145 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
146 -GetSystemMetrics(SM_CYFRAME
));
150 if (UserHasDlgFrameStyle(Style
, ExStyle
))
152 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
153 -GetSystemMetrics(SM_CYDLGFRAME
));
154 /* FIXME: this isn't in NC_AdjustRect? why not? */
155 if (ExStyle
& WS_EX_DLGMODALFRAME
)
156 InflateRect( rect
, -1, 0 );
160 if (UserHasThinFrameStyle(Style
, ExStyle
))
162 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
163 -GetSystemMetrics(SM_CYBORDER
));
171 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
173 LONG Style
= GetWindowLongPtr(hWnd
, GWL_STYLE
);
174 /* Content can be redrawn after a change. */
177 if (!(Style
& WS_VISIBLE
)) /* Not Visible */
179 SetWindowLongPtr(hWnd
, GWL_STYLE
, WS_VISIBLE
);
182 else /* Content cannot be redrawn after a change. */
184 if (Style
& WS_VISIBLE
) /* Visible */
186 RedrawWindow( hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
187 Style
&= ~WS_VISIBLE
;
188 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
); /* clear bits */
196 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
198 /* Not for child windows. */
199 if (hWnd
!= (HWND
)wParam
)
204 switch((INT_PTR
) LOWORD(lParam
))
208 WORD Msg
= HIWORD(lParam
);
209 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
210 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
219 HICON hCursor
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HCURSOR
);
231 if (Style
& WS_MAXIMIZE
)
235 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
241 if (Style
& WS_MAXIMIZE
)
245 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
251 if (Style
& WS_MAXIMIZE
)
255 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
261 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
265 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
268 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
272 DefWndStartSizeMove(HWND hWnd
, PWND Wnd
, WPARAM wParam
, POINT
*capturePoint
)
278 ULONG Style
= Wnd
->style
;
280 rectWindow
= Wnd
->rcWindow
;
282 if ((wParam
& 0xfff0) == SC_MOVE
)
284 /* Move pointer at the center of the caption */
286 UserGetInsideRectNC(Wnd
, &rect
);
287 if (Style
& WS_SYSMENU
)
288 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
289 if (Style
& WS_MINIMIZEBOX
)
290 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
291 if (Style
& WS_MAXIMIZEBOX
)
292 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
293 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
294 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
303 if (GetMessageW(&msg
, NULL
, 0, 0) <= 0)
308 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
309 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
321 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
322 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
326 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
327 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
331 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
332 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
336 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
337 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
340 case VK_ESCAPE
: return 0;
346 SetCursorPos( pt
.x
, pt
.y
);
347 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
351 #define ON_LEFT_BORDER(hit) \
352 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
353 #define ON_RIGHT_BORDER(hit) \
354 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
355 #define ON_TOP_BORDER(hit) \
356 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
357 #define ON_BOTTOM_BORDER(hit) \
358 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
361 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
362 ULONG width
, ULONG height
)
364 static HBRUSH hDraggingRectBrush
= NULL
;
367 if(!hDraggingRectBrush
)
369 static HBITMAP hDraggingPattern
= NULL
;
370 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
372 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
373 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
376 hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
377 PatBlt( hdc
, rect
->left
, rect
->top
,
378 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
379 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
380 rect
->bottom
- rect
->top
- height
, PATINVERT
);
381 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
382 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
383 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
384 rect
->bottom
- rect
->top
- height
, PATINVERT
);
385 SelectObject( hdc
, hbrush
);
389 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
393 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
));
397 UserDrawWindowFrame(hdc
, rect
, 1, 1);
402 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
406 RECT sizingRect
, mouseRect
, origRect
, clipRect
, unmodRect
;
408 LONG hittest
= (LONG
)(wParam
& 0x0f);
409 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
410 POINT minTrack
, maxTrack
;
411 POINT capturePoint
, pt
;
412 ULONG Style
, ExStyle
;
416 DWORD dwPoint
= GetMessagePos();
417 BOOL DragFullWindows
= FALSE
;
418 HWND hWndParent
= NULL
;
421 Wnd
= ValidateHwnd(hwnd
);
426 ExStyle
= Wnd
->ExStyle
;
427 iconic
= (Style
& WS_MINIMIZE
) != 0;
429 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
431 pt
.x
= GET_X_LPARAM(dwPoint
);
432 pt
.y
= GET_Y_LPARAM(dwPoint
);
435 if ((Style
& WS_MAXIMIZE
) || !IsWindowVisible(hwnd
))
440 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
441 if ((wParam
& 0xfff0) == SC_MOVE
)
445 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
458 if (hittest
&& ((wParam
& 0xfff0) != SC_MOUSEMENU
))
460 hittest
+= (HTLEFT
- WMSZ_LEFT
);
465 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
474 /* Get min/max info */
476 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
477 sizingRect
= Wnd
->rcWindow
;
478 if (Style
& WS_CHILD
)
480 hWndParent
= GetParent(hwnd
);
481 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
482 unmodRect
= sizingRect
;
483 GetClientRect(hWndParent
, &mouseRect
);
484 clipRect
= mouseRect
;
485 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
489 if(!(ExStyle
& WS_EX_TOPMOST
))
491 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
492 mouseRect
= clipRect
;
496 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
497 clipRect
= mouseRect
;
499 unmodRect
= sizingRect
;
501 ClipCursor(&clipRect
);
503 origRect
= sizingRect
;
504 if (ON_LEFT_BORDER(hittest
))
506 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
507 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
509 else if (ON_RIGHT_BORDER(hittest
))
511 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
512 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
514 if (ON_TOP_BORDER(hittest
))
516 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
517 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
519 else if (ON_BOTTOM_BORDER(hittest
))
521 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
522 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
524 if (Style
& WS_CHILD
)
526 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
529 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
530 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
531 if (GetCapture() != hwnd
) SetCapture( hwnd
);
533 if (Style
& WS_CHILD
)
535 /* Retrieve a default cache DC (without using the window style) */
536 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
542 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
545 SelectObject(hdc
, DesktopRgn
);
547 if( iconic
) /* create a cursor for dragging */
549 HICON hIcon
= (HICON
)GetClassLongPtrW(hwnd
, GCL_HICON
);
550 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
551 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
552 if( !hDragCursor
) iconic
= FALSE
;
555 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
556 if( !iconic
&& !DragFullWindows
)
558 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
565 if (GetMessageW(&msg
, 0, 0, 0) <= 0)
568 /* Exit on button-up, Return, or Esc */
569 if ((msg
.message
== WM_LBUTTONUP
) ||
570 ((msg
.message
== WM_KEYDOWN
) &&
571 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
573 if (msg
.message
== WM_PAINT
)
575 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
576 UpdateWindow( msg
.hwnd
);
577 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
581 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
582 continue; /* We are not interested in other messages */
586 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
588 case VK_UP
: pt
.y
-= 8; break;
589 case VK_DOWN
: pt
.y
+= 8; break;
590 case VK_LEFT
: pt
.x
-= 8; break;
591 case VK_RIGHT
: pt
.x
+= 8; break;
594 pt
.x
= max( pt
.x
, mouseRect
.left
);
595 pt
.x
= min( pt
.x
, mouseRect
.right
);
596 pt
.y
= max( pt
.y
, mouseRect
.top
);
597 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
599 dx
= pt
.x
- capturePoint
.x
;
600 dy
= pt
.y
- capturePoint
.y
;
608 if( iconic
) /* ok, no system popup tracking */
610 hOldCursor
= SetCursor(hDragCursor
);
615 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
618 RECT newRect
= unmodRect
;
619 WPARAM wpSizingHit
= 0;
621 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
622 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
623 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
624 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
625 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
626 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
629 /* determine the hit location */
630 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
631 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
633 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
638 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
640 /* To avoid any deadlocks, all the locks on the windows
641 structures must be suspended before the SetWindowPos */
642 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
643 newRect
.right
- newRect
.left
,
644 newRect
.bottom
- newRect
.top
,
645 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
648 sizingRect
= newRect
;
657 if( moved
) /* restore cursors, show icon title later on */
660 SetCursor( hOldCursor
);
662 DestroyCursor( hDragCursor
);
664 else if(!DragFullWindows
)
665 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
667 if (Style
& WS_CHILD
)
668 ReleaseDC( hWndParent
, hdc
);
674 DeleteObject(DesktopRgn
);
678 if (ISITHOOKED(WH_CBT
))
681 NtUserMessageCall( hwnd
, WM_CBT
, HCBT_MOVESIZE
, (LPARAM
)&sizingRect
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
682 if (lResult
) moved
= FALSE
;
685 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
686 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
687 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
689 /* window moved or resized */
692 /* if the moving/resizing isn't canceled call SetWindowPos
693 * with the new position or the new size of the window
695 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
697 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
699 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
700 sizingRect
.right
- sizingRect
.left
,
701 sizingRect
.bottom
- sizingRect
.top
,
702 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
704 else { /* restore previous size/position */
706 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
707 origRect
.right
- origRect
.left
,
708 origRect
.bottom
- origRect
.top
,
709 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
714 if( Style
& WS_MINIMIZE
)
716 /* Single click brings up the system menu when iconized */
720 if( Style
& WS_SYSMENU
)
721 SendMessageA( hwnd
, WM_SYSCOMMAND
,
722 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
728 /***********************************************************************
729 * DefWndTrackScrollBar
731 * Track a mouse button press on the horizontal or vertical scroll-bar.
734 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
738 if (SC_HSCROLL
== (wParam
& 0xfff0))
740 if (HTHSCROLL
!= (wParam
& 0x0f))
746 else /* SC_VSCROLL */
748 if (HTVSCROLL
!= (wParam
& 0x0f))
754 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
759 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
764 if (!IsWindowEnabled( hWnd
)) return 0;
766 if (ISITHOOKED(WH_CBT
))
769 NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
770 if (lResult
) return 0;
773 switch (wParam
& 0xfff0)
777 DefWndDoSizeMove(hWnd
, wParam
);
780 wp
.length
= sizeof(WINDOWPLACEMENT
);
781 if(GetWindowPlacement(hWnd
, &wp
))
783 wp
.showCmd
= SW_MINIMIZE
;
784 SetWindowPlacement(hWnd
, &wp
);
788 wp
.length
= sizeof(WINDOWPLACEMENT
);
789 if(GetWindowPlacement(hWnd
, &wp
))
791 wp
.showCmd
= SW_MAXIMIZE
;
792 SetWindowPlacement(hWnd
, &wp
);
796 wp
.length
= sizeof(WINDOWPLACEMENT
);
797 if(GetWindowPlacement(hWnd
, &wp
))
799 wp
.showCmd
= SW_RESTORE
;
800 SetWindowPlacement(hWnd
, &wp
);
804 return SendMessageW(hWnd
, WM_CLOSE
, 0, 0);
808 Pt
.x
= (short)LOWORD(lParam
);
809 Pt
.y
= (short)HIWORD(lParam
);
810 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
814 MenuTrackKbdMenuBar(hWnd
, wParam
, (WCHAR
)lParam
);
819 Pt
.x
= (short)LOWORD(lParam
);
820 Pt
.y
= (short)HIWORD(lParam
);
821 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
826 /* FIXME: Implement */
835 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
837 POINT maxTrack
, minTrack
;
838 LONG style
= GetWindowLongPtrA(hWnd
, GWL_STYLE
);
840 if (Pos
->flags
& SWP_NOSIZE
) return 0;
841 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
843 WinPosGetMinMaxInfo(hWnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
844 Pos
->cx
= min(Pos
->cx
, maxTrack
.x
);
845 Pos
->cy
= min(Pos
->cy
, maxTrack
.y
);
846 if (!(style
& WS_MINIMIZE
))
848 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
849 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
854 Pos
->cx
= max(Pos
->cx
, 0);
855 Pos
->cy
= max(Pos
->cy
, 0);
861 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
865 GetClientRect(hWnd
, &Rect
);
866 MapWindowPoints(hWnd
, (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
?
867 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
869 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
871 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
874 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
876 WPARAM wp
= SIZE_RESTORED
;
881 else if (IsIconic(hWnd
))
885 SendMessageW(hWnd
, WM_SIZE
, wp
,
886 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
892 /***********************************************************************
895 * Default colors for control painting.
898 DefWndControlColor(HDC hDC
, UINT ctlType
)
900 if (CTLCOLOR_SCROLLBAR
== ctlType
)
902 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
903 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
904 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
907 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
908 * we better use 0x55aa bitmap brush to make scrollbar's background
909 * look different from the window background.
911 if (bk
== GetSysColor(COLOR_WINDOW
))
913 static const WORD wPattern55AA
[] =
915 0x5555, 0xaaaa, 0x5555, 0xaaaa,
916 0x5555, 0xaaaa, 0x5555, 0xaaaa
918 static HBITMAP hPattern55AABitmap
= NULL
;
919 static HBRUSH hPattern55AABrush
= NULL
;
920 if (hPattern55AABrush
== NULL
)
922 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
923 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
925 return hPattern55AABrush
;
931 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
933 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
935 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
939 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
940 return GetSysColorBrush(COLOR_3DFACE
);
943 return GetSysColorBrush(COLOR_WINDOW
);
946 static void DefWndPrint( HWND hwnd
, HDC hdc
, ULONG uFlags
)
951 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
952 !IsWindowVisible(hwnd
) )
956 * Unimplemented flags.
958 if ( (uFlags
& PRF_CHILDREN
) ||
959 (uFlags
& PRF_OWNED
) ||
960 (uFlags
& PRF_NONCLIENT
) )
962 FIXME("WM_PRINT message with unsupported flags\n");
968 if ( uFlags
& PRF_ERASEBKGND
)
969 SendMessageW(hwnd
, WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
974 if ( uFlags
& PRF_CLIENT
)
975 SendMessageW(hwnd
, WM_PRINTCLIENT
, (WPARAM
)hdc
, uFlags
);
979 UserSendUiUpdateMsg(HWND hwnd
, LPARAM lParam
)
981 SendMessageW(hwnd
, WM_UPDATEUISTATE
, (WPARAM
)lParam
, 0);
987 DefWndScreenshot(HWND hWnd
)
999 hdc
= GetWindowDC(hWnd
);
1000 GetWindowRect(hWnd
, &rect
);
1001 w
= rect
.right
- rect
.left
;
1002 h
= rect
.bottom
- rect
.top
;
1004 hbitmap
= CreateCompatibleBitmap(hdc
, w
, h
);
1005 hdc2
= CreateCompatibleDC(hdc
);
1006 SelectObject(hdc2
, hbitmap
);
1008 BitBlt(hdc2
, 0, 0, w
, h
,
1012 SetClipboardData(CF_BITMAP
, hbitmap
);
1014 ReleaseDC(hWnd
, hdc
);
1015 ReleaseDC(hWnd
, hdc2
);
1024 User32DefWindowProc(HWND hWnd
,
1034 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
1039 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
1042 case WM_POPUPSYSTEMMENU
:
1044 /* This is an undocumented message used by the windows taskbar to
1045 display the system menu of windows that belong to other processes. */
1046 HMENU menu
= GetSystemMenu(hWnd
, FALSE
);
1049 TrackPopupMenu(menu
, TPM_LEFTBUTTON
|TPM_RIGHTBUTTON
,
1050 LOWORD(lParam
), HIWORD(lParam
), 0, hWnd
, NULL
);
1056 return DefWndNCActivate(hWnd
, wParam
);
1062 Point
.x
= GET_X_LPARAM(lParam
);
1063 Point
.y
= GET_Y_LPARAM(lParam
);
1064 return (DefWndNCHitTest(hWnd
, Point
));
1067 case WM_LBUTTONDOWN
:
1068 case WM_RBUTTONDOWN
:
1069 case WM_MBUTTONDOWN
:
1070 iF10Key
= iMenuSysKey
= 0;
1073 case WM_NCLBUTTONDOWN
:
1075 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
1078 case WM_LBUTTONDBLCLK
:
1079 return (DefWndNCLButtonDblClk(hWnd
, HTCLIENT
, lParam
));
1081 case WM_NCLBUTTONDBLCLK
:
1083 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
1086 case WM_WINDOWPOSCHANGING
:
1088 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1091 case WM_WINDOWPOSCHANGED
:
1093 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
1096 case WM_NCRBUTTONDOWN
:
1098 /* in Windows, capture is taken when right-clicking on the caption bar */
1099 if (wParam
== HTCAPTION
)
1109 if (hWnd
== GetCapture())
1113 Pt
.x
= GET_X_LPARAM(lParam
);
1114 Pt
.y
= GET_Y_LPARAM(lParam
);
1115 ClientToScreen(hWnd
, &Pt
);
1116 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1119 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1123 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1128 case WM_NCRBUTTONUP
:
1130 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1131 * in Windows), but what _should_ we do? According to MSDN :
1132 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1133 * message to the window". When is it appropriate?
1137 case WM_CONTEXTMENU
:
1139 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1143 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1147 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1156 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1158 Pt
.x
= GET_X_LPARAM(lParam
);
1159 Pt
.y
= GET_Y_LPARAM(lParam
);
1160 if (Style
& WS_CHILD
)
1162 ScreenToClient(GetParent(hWnd
), &Pt
);
1165 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1167 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1172 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1174 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongPtrW(hWnd
, GWL_STYLE
),
1175 GetClassLongPtrW(hWnd
, GCL_STYLE
), HitCode
);
1177 if(HitCode
== HTCAPTION
)
1178 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1180 Flags
= TPM_LEFTBUTTON
;
1182 TrackPopupMenu(SystemMenu
, Flags
,
1183 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1192 DefWndPrint(hWnd
, (HDC
)wParam
, lParam
);
1196 case WM_SYSCOLORCHANGE
:
1198 /* force to redraw non-client area */
1199 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1200 /* Use InvalidateRect to redraw client area, enable
1201 * erase to redraw all subcontrols otherwise send the
1202 * WM_SYSCOLORCHANGE to child windows/controls is required
1204 InvalidateRect(hWnd
,NULL
,TRUE
);
1212 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1217 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1218 (hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
)) != NULL
)
1222 GetClientRect(hWnd
, &ClientRect
);
1223 x
= (ClientRect
.right
- ClientRect
.left
-
1224 GetSystemMetrics(SM_CXICON
)) / 2;
1225 y
= (ClientRect
.bottom
- ClientRect
.top
-
1226 GetSystemMetrics(SM_CYICON
)) / 2;
1227 DrawIcon(hDC
, x
, y
, hIcon
);
1229 EndPaint(hWnd
, &Ps
);
1237 hRgn
= CreateRectRgn(0, 0, 0, 0);
1238 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1240 RedrawWindow(hWnd
, NULL
, hRgn
,
1241 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1250 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1251 if (wParam
) SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
| WS_VISIBLE
);
1254 RedrawWindow(hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
1255 Style
&= ~WS_VISIBLE
;
1256 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
);
1263 DestroyWindow(hWnd
);
1267 case WM_MOUSEACTIVATE
:
1269 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1274 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1279 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1287 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1292 /* Check if the window is minimized. */
1293 if (LOWORD(wParam
) != WA_INACTIVE
&&
1294 !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1303 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1307 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1312 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1320 case WM_ICONERASEBKGND
:
1323 HBRUSH hBrush
= (HBRUSH
)GetClassLongPtrW(hWnd
, GCL_HBRBACKGROUND
);
1329 if (GetClassLongPtrW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1331 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1332 GetClientRect(hWnd
, &Rect
);
1333 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1337 GetClipBox((HDC
)wParam
, &Rect
);
1339 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1343 case WM_CTLCOLORMSGBOX
:
1344 case WM_CTLCOLOREDIT
:
1345 case WM_CTLCOLORLISTBOX
:
1346 case WM_CTLCOLORBTN
:
1347 case WM_CTLCOLORDLG
:
1348 case WM_CTLCOLORSTATIC
:
1349 case WM_CTLCOLORSCROLLBAR
:
1350 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1353 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
1357 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1359 if (Style
& WS_CHILD
)
1361 /* with the exception of the border around a resizable wnd,
1362 * give the parent first chance to set the cursor */
1363 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1365 HWND parent
= GetParent( hWnd
);
1368 if (parent
!= GetDesktopWindow() &&
1369 SendMessageW( parent
, WM_SETCURSOR
, wParam
, lParam
))
1374 if (parent
!= GetDesktopWindow() &&
1375 SendMessageA( parent
, WM_SETCURSOR
, wParam
, lParam
))
1380 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1384 return (DefWndHandleSysCommand(hWnd
, wParam
, lParam
));
1387 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
1390 /* FIXME: This is also incomplete. */
1393 if (HIWORD(lParam
) & KEYDATA_ALT
)
1395 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1396 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
1397 if ( (wParam
== VK_MENU
|| wParam
== VK_LMENU
1398 || wParam
== VK_RMENU
) && !iMenuSysKey
)
1405 if (wParam
== VK_F4
) /* Try to close the window */
1407 if (!(GetClassLongPtrW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1410 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1412 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1415 else if (wParam
== VK_SNAPSHOT
)
1418 while (GetParent(hwnd
) != NULL
)
1420 hwnd
= GetParent(hwnd
);
1422 DefWndScreenshot(hwnd
);
1425 else if( wParam
== VK_F10
)
1427 if (GetKeyState(VK_SHIFT
) & 0x8000)
1428 SendMessageW( hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, MAKELPARAM(-1, -1) );
1431 else if( wParam
== VK_ESCAPE
&& (GetKeyState(VK_SHIFT
) & 0x8000))
1432 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, ' ' );
1439 /* Press and release F10 or ALT */
1440 if (((wParam
== VK_MENU
|| wParam
== VK_LMENU
|| wParam
== VK_RMENU
)
1441 && iMenuSysKey
) || ((wParam
== VK_F10
) && iF10Key
))
1442 SendMessageW( GetAncestor( hWnd
, GA_ROOT
), WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1443 iMenuSysKey
= iF10Key
= 0;
1450 if (wParam
== '\r' && IsIconic(hWnd
))
1452 PostMessageW( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0L );
1455 if ((HIWORD(lParam
) & KEYDATA_ALT
) && wParam
)
1457 if (wParam
== '\t' || wParam
== '\x1b') break;
1458 if (wParam
== ' ' && (GetWindowLongPtrW( hWnd
, GWL_STYLE
) & WS_CHILD
))
1459 SendMessageW( GetParent(hWnd
), Msg
, wParam
, lParam
);
1461 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, wParam
);
1463 else /* check for Ctrl-Esc */
1464 if (wParam
!= '\x1b') MessageBeep(0);
1470 if (lParam
) // Call when it is necessary.
1471 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, 0, FNID_DEFWINDOWPROC
, FALSE
);
1475 case WM_CLIENTSHUTDOWN
:
1478 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
1485 /* FIXME: Check for a desktop. */
1486 //if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
1487 MENU_EndMenu( hWnd
);
1488 if (GetCapture() == hWnd
)
1502 case WM_QUERYDROPOBJECT
:
1504 if (GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1511 case WM_QUERYDRAGICON
:
1516 hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
);
1519 return ((LRESULT
)hIcon
);
1521 for (Len
= 1; Len
< 64; Len
++)
1523 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1525 return((LRESULT
)hIcon
);
1528 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1531 case WM_ISACTIVEICON
:
1535 pWnd
= ValidateHwnd(hWnd
);
1536 if (!pWnd
) return 0;
1537 isai
= (pWnd
->state
& WNDS_ACTIVEFRAME
) != 0;
1541 case WM_NOTIFYFORMAT
:
1543 if (lParam
== NF_QUERY
)
1544 return IsWindowUnicode(hWnd
) ? NFR_UNICODE
: NFR_ANSI
;
1550 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1551 HICON hOldIcon
= (HICON
)GetClassLongPtrW(hWnd
, Index
);
1552 SetClassLongPtrW(hWnd
, Index
, lParam
);
1553 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1554 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1555 SWP_NOACTIVATE
| SWP_NOZORDER
);
1556 return ((LRESULT
)hOldIcon
);
1561 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1562 return (GetClassLongPtrW(hWnd
, Index
));
1569 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1573 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1580 THRDCARETINFO CaretInfo
;
1583 case 0xffff: /* Caret timer */
1584 /* switch showing byte in win32k and get information about the caret */
1585 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1587 DrawCaret(hWnd
, &CaretInfo
);
1595 case WM_QUERYENDSESSION
:
1600 case WM_INPUTLANGCHANGEREQUEST
:
1604 if(wParam
& INPUTLANGCHANGE_BACKWARD
1605 && wParam
& INPUTLANGCHANGE_FORWARD
)
1610 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1612 if(wParam
& INPUTLANGCHANGE_BACKWARD
) NewHkl
= (HKL
) HKL_PREV
;
1613 else if(wParam
& INPUTLANGCHANGE_FORWARD
) NewHkl
= (HKL
) HKL_NEXT
;
1614 else NewHkl
= (HKL
) lParam
;
1616 NtUserActivateKeyboardLayout(NewHkl
, 0);
1621 case WM_INPUTLANGCHANGE
:
1624 HWND
*win_array
= WIN_ListChildren( hWnd
);
1628 while (win_array
[count
])
1629 SendMessageW( win_array
[count
++], WM_INPUTLANGCHANGE
, wParam
, lParam
);
1630 HeapFree(GetProcessHeap(),0,win_array
);
1634 case WM_QUERYUISTATE
:
1637 PWND Wnd
= ValidateHwnd(hWnd
);
1641 Ret
|= UISF_HIDEFOCUS
;
1643 Ret
|= UISF_HIDEACCEL
;
1648 case WM_CHANGEUISTATE
:
1650 BOOL AlwaysShowCues
= FALSE
;
1651 WORD Action
= LOWORD(wParam
);
1652 WORD Flags
= HIWORD(wParam
);
1655 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1659 Wnd
= ValidateHwnd(hWnd
);
1660 if (!Wnd
|| lParam
!= 0)
1663 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1666 if (Flags
& UISF_ACTIVE
)
1668 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1671 if (Action
== UIS_INITIALIZE
)
1673 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1677 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1678 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1680 /* We need to update wParam in case we need to send out messages */
1681 wParam
= MAKEWPARAM(Action
, Flags
);
1687 /* See if we actually need to change something */
1688 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1690 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1693 /* Don't need to do anything... */
1697 /* See if we actually need to change something */
1698 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1700 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1703 /* Don't need to do anything... */
1707 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1711 if ((Wnd
->style
& WS_CHILD
) && Wnd
->spwndParent
!= NULL
)
1713 /* We're a child window and we need to pass this message down until
1714 we reach the root */
1715 hWnd
= UserHMGetHandle((PWND
)DesktopPtrToUser(Wnd
->spwndParent
));
1719 /* We're a top level window, we need to change the UI state */
1720 Msg
= WM_UPDATEUISTATE
;
1724 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1726 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1729 case WM_UPDATEUISTATE
:
1732 BOOL AlwaysShowCues
= FALSE
;
1733 WORD Action
= LOWORD(wParam
);
1734 WORD Flags
= HIWORD(wParam
);
1737 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1741 Wnd
= ValidateHwnd(hWnd
);
1742 if (!Wnd
|| lParam
!= 0)
1745 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1748 if (Flags
& UISF_ACTIVE
)
1750 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1753 if (Action
== UIS_INITIALIZE
)
1755 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1759 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1760 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1762 /* We need to update wParam for broadcasting the update */
1763 wParam
= MAKEWPARAM(Action
, Flags
);
1769 /* See if we actually need to change something */
1770 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1772 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1775 /* Don't need to do anything... */
1780 /* See if we actually need to change something */
1781 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1783 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1786 /* Don't need to do anything... */
1791 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1795 /* Pack the information and call win32k */
1798 if (!NtUserCallTwoParam((DWORD_PTR
)hWnd
, (DWORD_PTR
)Flags
| ((DWORD_PTR
)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE
))
1802 /* Always broadcast the update to all children */
1803 EnumChildWindows(hWnd
,
1804 UserSendUiUpdateMsg
,
1816 * helpers for calling IMM32 (from Wine 10/22/2008)
1818 * WM_IME_* messages are generated only by IMM32,
1819 * so I assume imm32 is already LoadLibrary-ed.
1822 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1824 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1825 HWND (WINAPI
*pFunc
)(HWND
);
1830 ERR("cannot get IMM32 handle\n");
1834 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1836 hwndRet
= (*pFunc
)(hwnd
);
1843 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1845 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1846 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1851 ERR("cannot get IMM32 handle\n");
1855 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1857 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1864 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1866 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1867 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1872 ERR("cannot get IMM32 handle\n");
1876 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1878 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1885 RealDefWindowProcA(HWND hWnd
,
1893 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1900 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1901 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1902 * may have child window IDs instead of window name */
1903 if (HIWORD(cs
->lpszName
))
1905 DefSetText(hWnd
, (PCWSTR
)cs
->lpszName
, TRUE
);
1912 case WM_GETTEXTLENGTH
:
1917 Wnd
= ValidateHwnd(hWnd
);
1918 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
1920 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1922 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1924 Wnd
->strName
.Length
)))
1926 Result
= (LRESULT
) len
;
1937 PSTR outbuf
= (PSTR
)lParam
;
1940 Wnd
= ValidateHwnd(hWnd
);
1941 if (Wnd
!= NULL
&& wParam
!= 0)
1943 if (Wnd
->strName
.Buffer
!= NULL
)
1944 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1950 if (Wnd
->strName
.Length
!= 0)
1952 copy
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1953 Result
= WideCharToMultiByte(CP_ACP
,
1961 outbuf
[Result
] = '\0';
1972 DefSetText(hWnd
, (PCWSTR
)lParam
, TRUE
);
1974 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1976 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1982 case WM_IME_KEYDOWN
:
1984 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
1990 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
1997 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
1998 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
2002 case WM_IME_STARTCOMPOSITION
:
2003 case WM_IME_COMPOSITION
:
2004 case WM_IME_ENDCOMPOSITION
:
2010 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2012 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
2016 case WM_IME_SETCONTEXT
:
2020 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2022 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
2028 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2031 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2037 RealDefWindowProcW(HWND hWnd
,
2045 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
2052 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
2053 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2054 * may have child window IDs instead of window name */
2055 if (HIWORD(cs
->lpszName
))
2057 DefSetText(hWnd
, cs
->lpszName
, FALSE
);
2064 case WM_GETTEXTLENGTH
:
2069 Wnd
= ValidateHwnd(hWnd
);
2070 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
2072 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2074 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
2076 Wnd
->strName
.Length
)))
2078 Result
= (LRESULT
) (Wnd
->strName
.Length
/ sizeof(WCHAR
));
2089 PWSTR outbuf
= (PWSTR
)lParam
;
2091 Wnd
= ValidateHwnd(hWnd
);
2092 if (Wnd
!= NULL
&& wParam
!= 0)
2094 if (Wnd
->strName
.Buffer
!= NULL
)
2095 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2101 if (Wnd
->strName
.Length
!= 0)
2103 Result
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
2104 RtlCopyMemory(outbuf
,
2106 Result
* sizeof(WCHAR
));
2107 outbuf
[Result
] = L
'\0';
2118 DefSetText(hWnd
, (PCWSTR
)lParam
, FALSE
);
2120 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2122 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
2130 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
2135 case WM_IME_KEYDOWN
:
2137 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2143 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
2147 case WM_IME_STARTCOMPOSITION
:
2148 case WM_IME_COMPOSITION
:
2149 case WM_IME_ENDCOMPOSITION
:
2155 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2157 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
2161 case WM_IME_SETCONTEXT
:
2165 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2167 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
2172 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
2174 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2180 DefWindowProcA(HWND hWnd
,
2185 BOOL Hook
, msgOverride
= FALSE
;
2190 Hook
= BeginIfHookedUserApiHook();
2192 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2194 /* Bypass SEH and go direct. */
2195 if (!Hook
|| !msgOverride
)
2196 return RealDefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2200 Result
= guah
.DefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2202 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2213 DefWindowProcW(HWND hWnd
,
2218 BOOL Hook
, msgOverride
= FALSE
;
2223 Hook
= BeginIfHookedUserApiHook();
2225 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2227 /* Bypass SEH and go direct. */
2228 if (!Hook
|| !msgOverride
)
2229 return RealDefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2233 Result
= guah
.DefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2235 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)