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 static short iF10Key
= 0;
31 static short iMenuSysKey
= 0;
33 /* FUNCTIONS *****************************************************************/
36 InitStockObjects(void)
38 /* FIXME - Instead of copying the stuff to usermode we should map the tables to
39 userland. The current implementation has one big flaw: the system color
40 table doesn't get updated when another process changes them. That's why
41 we should rather map the table into usermode. But it only affects the
42 SysColors table - the pens, brushes and stock objects are not affected
43 as their handles never change. But it'd be faster to map them, too. */
52 GetSysColor(int nIndex
)
54 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
56 return gpsi
->argbSystem
[nIndex
];
59 SetLastError(ERROR_INVALID_PARAMETER
);
67 GetSysColorBrush(int nIndex
)
69 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
71 return gpsi
->ahbrSystem
[nIndex
];
74 SetLastError(ERROR_INVALID_PARAMETER
);
85 CONST INT
*lpaElements
,
86 CONST COLORREF
*lpaRgbValues
)
88 return NtUserSetSysColors(cElements
, lpaElements
, lpaRgbValues
, 0);
93 DefSetText(HWND hWnd
, PCWSTR String
, BOOL Ansi
)
96 LARGE_STRING lsString
;
101 RtlInitLargeAnsiString((PLARGE_ANSI_STRING
)&lsString
, (PCSZ
)String
, 0);
103 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING
)&lsString
, String
, 0);
105 Ret
= NtUserDefSetText(hWnd
, (String
? &lsString
: NULL
));
108 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE
, hWnd
, OBJID_WINDOW
, CHILDID_SELF
, 0);
114 UserGetInsideRectNC(PWND Wnd
, RECT
*rect
)
120 ExStyle
= Wnd
->ExStyle
;
122 rect
->top
= rect
->left
= 0;
123 rect
->right
= Wnd
->rcWindow
.right
- Wnd
->rcWindow
.left
;
124 rect
->bottom
= Wnd
->rcWindow
.bottom
- Wnd
->rcWindow
.top
;
126 if (Style
& WS_ICONIC
)
131 /* Remove frame from rectangle */
132 if (UserHasThickFrameStyle(Style
, ExStyle
))
134 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
135 -GetSystemMetrics(SM_CYFRAME
));
139 if (UserHasDlgFrameStyle(Style
, ExStyle
))
141 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
142 -GetSystemMetrics(SM_CYDLGFRAME
));
143 /* FIXME: this isn't in NC_AdjustRect? why not? */
144 if (ExStyle
& WS_EX_DLGMODALFRAME
)
145 InflateRect( rect
, -1, 0 );
149 if (UserHasThinFrameStyle(Style
, ExStyle
))
151 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
152 -GetSystemMetrics(SM_CYBORDER
));
160 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
162 LONG Style
= GetWindowLongPtr(hWnd
, GWL_STYLE
);
163 /* Content can be redrawn after a change. */
166 if (!(Style
& WS_VISIBLE
)) /* Not Visible */
168 SetWindowLongPtr(hWnd
, GWL_STYLE
, WS_VISIBLE
);
171 else /* Content cannot be redrawn after a change. */
173 if (Style
& WS_VISIBLE
) /* Visible */
175 RedrawWindow( hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
176 Style
&= ~WS_VISIBLE
;
177 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
); /* clear bits */
185 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
187 /* Not for child windows. */
188 if (hWnd
!= (HWND
)wParam
)
193 switch((INT_PTR
) LOWORD(lParam
))
197 WORD Msg
= HIWORD(lParam
);
198 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
199 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
208 HICON hCursor
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HCURSOR
);
220 if (Style
& WS_MAXIMIZE
)
224 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
230 if (Style
& WS_MAXIMIZE
)
234 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
240 if (Style
& WS_MAXIMIZE
)
244 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
250 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
254 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
257 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
261 DefWndStartSizeMove(HWND hWnd
, PWND Wnd
, WPARAM wParam
, POINT
*capturePoint
)
267 ULONG Style
= Wnd
->style
;
269 rectWindow
= Wnd
->rcWindow
;
271 if ((wParam
& 0xfff0) == SC_MOVE
)
273 /* Move pointer at the center of the caption */
275 UserGetInsideRectNC(Wnd
, &rect
);
276 if (Style
& WS_SYSMENU
)
277 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
278 if (Style
& WS_MINIMIZEBOX
)
279 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
280 if (Style
& WS_MAXIMIZEBOX
)
281 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
282 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
283 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
292 if (!GetMessageW(&msg
, NULL
, 0, 0)) break; //return 0;
293 if (CallMsgFilterW( &msg
, MSGF_SIZE
)) continue;
298 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
299 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
311 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
312 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
316 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
317 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
321 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
322 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
326 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
327 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
334 TranslateMessage( &msg
);
335 DispatchMessageW( &msg
);
341 SetCursorPos( pt
.x
, pt
.y
);
342 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
346 #define ON_LEFT_BORDER(hit) \
347 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
348 #define ON_RIGHT_BORDER(hit) \
349 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
350 #define ON_TOP_BORDER(hit) \
351 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
352 #define ON_BOTTOM_BORDER(hit) \
353 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
356 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
357 ULONG width
, ULONG height
)
359 static HBRUSH hDraggingRectBrush
= NULL
;
362 if(!hDraggingRectBrush
)
364 static HBITMAP hDraggingPattern
= NULL
;
365 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
367 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
368 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
371 hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
372 PatBlt( hdc
, rect
->left
, rect
->top
,
373 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
374 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
375 rect
->bottom
- rect
->top
- height
, PATINVERT
);
376 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
377 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
378 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
379 rect
->bottom
- rect
->top
- height
, PATINVERT
);
380 SelectObject( hdc
, hbrush
);
384 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
388 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
));
392 UserDrawWindowFrame(hdc
, rect
, 1, 1);
397 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
401 RECT sizingRect
, mouseRect
, origRect
, clipRect
, unmodRect
;
403 LONG hittest
= (LONG
)(wParam
& 0x0f);
404 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
405 POINT minTrack
, maxTrack
;
406 POINT capturePoint
, pt
;
407 ULONG Style
, ExStyle
;
411 DWORD dwPoint
= GetMessagePos();
412 BOOL DragFullWindows
= FALSE
;
413 HWND hWndParent
= NULL
;
416 Wnd
= ValidateHwnd(hwnd
);
421 ExStyle
= Wnd
->ExStyle
;
422 iconic
= (Style
& WS_MINIMIZE
) != 0;
424 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
426 pt
.x
= GET_X_LPARAM(dwPoint
);
427 pt
.y
= GET_Y_LPARAM(dwPoint
);
430 if ((Style
& WS_MAXIMIZE
) || !IsWindowVisible(hwnd
))
435 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
436 if ((wParam
& 0xfff0) == SC_MOVE
)
440 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
453 if (hittest
&& ((wParam
& 0xfff0) != SC_MOUSEMENU
))
455 hittest
+= (HTLEFT
- WMSZ_LEFT
);
460 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
469 /* Get min/max info */
471 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
472 sizingRect
= Wnd
->rcWindow
;
473 if (Style
& WS_CHILD
)
475 hWndParent
= GetParent(hwnd
);
476 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
477 unmodRect
= sizingRect
;
478 GetClientRect(hWndParent
, &mouseRect
);
479 clipRect
= mouseRect
;
480 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
484 if(!(ExStyle
& WS_EX_TOPMOST
))
486 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
487 mouseRect
= clipRect
;
491 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
492 clipRect
= mouseRect
;
494 unmodRect
= sizingRect
;
496 ClipCursor(&clipRect
);
498 origRect
= sizingRect
;
499 if (ON_LEFT_BORDER(hittest
))
501 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
502 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
504 else if (ON_RIGHT_BORDER(hittest
))
506 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
507 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
509 if (ON_TOP_BORDER(hittest
))
511 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
512 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
514 else if (ON_BOTTOM_BORDER(hittest
))
516 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
517 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
519 if (Style
& WS_CHILD
)
521 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
524 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
525 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
526 if (GetCapture() != hwnd
) SetCapture( hwnd
);
528 if (Style
& WS_CHILD
)
530 /* Retrieve a default cache DC (without using the window style) */
531 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
537 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
540 SelectObject(hdc
, DesktopRgn
);
542 if( iconic
) /* create a cursor for dragging */
544 HICON hIcon
= (HICON
)GetClassLongPtrW(hwnd
, GCL_HICON
);
545 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
546 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
547 if( !hDragCursor
) iconic
= FALSE
;
550 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
551 if( !iconic
&& !DragFullWindows
)
553 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
560 if (!GetMessageW(&msg
, 0, 0, 0)) break;
561 if (CallMsgFilterW( &msg
, MSGF_SIZE
)) continue;
563 /* Exit on button-up, Return, or Esc */
564 if ((msg
.message
== WM_LBUTTONUP
) ||
565 ((msg
.message
== WM_KEYDOWN
) &&
566 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
568 if (msg
.message
== WM_PAINT
)
570 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
571 UpdateWindow( msg
.hwnd
);
572 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
576 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
578 TranslateMessage( &msg
);
579 DispatchMessageW( &msg
);
580 continue; /* We are not interested in other messages */
585 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
587 case VK_UP
: pt
.y
-= 8; break;
588 case VK_DOWN
: pt
.y
+= 8; break;
589 case VK_LEFT
: pt
.x
-= 8; break;
590 case VK_RIGHT
: pt
.x
+= 8; break;
593 pt
.x
= max( pt
.x
, mouseRect
.left
);
594 pt
.x
= min( pt
.x
, mouseRect
.right
);
595 pt
.y
= max( pt
.y
, mouseRect
.top
);
596 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
598 dx
= pt
.x
- capturePoint
.x
;
599 dy
= pt
.y
- capturePoint
.y
;
607 if( iconic
) /* ok, no system popup tracking */
609 hOldCursor
= SetCursor(hDragCursor
);
614 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
617 RECT newRect
= unmodRect
;
618 WPARAM wpSizingHit
= 0;
620 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
621 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
622 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
623 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
624 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
625 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
628 /* determine the hit location */
629 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
630 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
632 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
637 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
639 /* To avoid any deadlocks, all the locks on the windows
640 structures must be suspended before the SetWindowPos */
641 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
642 newRect
.right
- newRect
.left
,
643 newRect
.bottom
- newRect
.top
,
644 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
647 sizingRect
= newRect
;
656 if( moved
) /* restore cursors, show icon title later on */
659 SetCursor( hOldCursor
);
661 DestroyCursor( hDragCursor
);
663 else if(!DragFullWindows
)
664 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
666 if (Style
& WS_CHILD
)
667 ReleaseDC( hWndParent
, hdc
);
673 DeleteObject(DesktopRgn
);
677 if (ISITHOOKED(WH_CBT
))
680 NtUserMessageCall( hwnd
, WM_CBT
, HCBT_MOVESIZE
, (LPARAM
)&sizingRect
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
681 if (lResult
) moved
= FALSE
;
684 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
685 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
686 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
688 /* window moved or resized */
691 /* if the moving/resizing isn't canceled call SetWindowPos
692 * with the new position or the new size of the window
694 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
696 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
698 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
699 sizingRect
.right
- sizingRect
.left
,
700 sizingRect
.bottom
- sizingRect
.top
,
701 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
703 else { /* restore previous size/position */
705 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
706 origRect
.right
- origRect
.left
,
707 origRect
.bottom
- origRect
.top
,
708 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
713 if( Style
& WS_MINIMIZE
)
715 /* Single click brings up the system menu when iconized */
719 if( Style
& WS_SYSMENU
)
720 SendMessageA( hwnd
, WM_SYSCOMMAND
,
721 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
727 /***********************************************************************
728 * DefWndTrackScrollBar
730 * Track a mouse button press on the horizontal or vertical scroll-bar.
733 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
737 if (SC_HSCROLL
== (wParam
& 0xfff0))
739 if (HTHSCROLL
!= (wParam
& 0x0f))
745 else /* SC_VSCROLL */
747 if (HTVSCROLL
!= (wParam
& 0x0f))
753 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
756 LRESULT WINAPI
DoAppSwitch( WPARAM wParam
, LPARAM lParam
);
759 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
765 if (!IsWindowEnabled( hWnd
)) return 0;
767 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 NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
831 DoAppSwitch( wParam
, lParam
);
836 HWND hwnd
, hWndLastActive
;
840 pWnd
= ValidateHwnd(hwnd
);
843 hWndLastActive
= GetLastActivePopup(hwnd
);
846 hwnd
= hWndLastActive
;
847 pWnd
= ValidateHwnd(hwnd
);
849 SetForegroundWindow(hwnd
);
850 if (pWnd
->style
& WS_MINIMIZE
)
852 PostMessage(hwnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
859 FIXME("Unimplemented DefWndHandleSysCommand wParam 0x%x\n",wParam
);
867 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
869 POINT maxTrack
, minTrack
;
870 LONG style
= GetWindowLongPtrA(hWnd
, GWL_STYLE
);
872 if (Pos
->flags
& SWP_NOSIZE
) return 0;
873 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
875 WinPosGetMinMaxInfo(hWnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
876 Pos
->cx
= min(Pos
->cx
, maxTrack
.x
);
877 Pos
->cy
= min(Pos
->cy
, maxTrack
.y
);
878 if (!(style
& WS_MINIMIZE
))
880 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
881 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
886 Pos
->cx
= max(Pos
->cx
, 0);
887 Pos
->cy
= max(Pos
->cy
, 0);
893 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
897 GetClientRect(hWnd
, &Rect
);
898 MapWindowPoints(hWnd
, (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
?
899 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
901 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
903 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
906 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
908 WPARAM wp
= SIZE_RESTORED
;
913 else if (IsIconic(hWnd
))
917 SendMessageW(hWnd
, WM_SIZE
, wp
,
918 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
924 /***********************************************************************
927 * Default colors for control painting.
930 DefWndControlColor(HDC hDC
, UINT ctlType
)
932 if (ctlType
== CTLCOLOR_SCROLLBAR
)
934 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
935 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
936 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
939 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
940 * we better use 0x55aa bitmap brush to make scrollbar's background
941 * look different from the window background.
943 if ( bk
== GetSysColor(COLOR_WINDOW
))
944 return gpsi
->hbrGray
;
946 UnrealizeObject( hb
);
950 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
952 if ((ctlType
== CTLCOLOR_EDIT
) || (ctlType
== CTLCOLOR_LISTBOX
))
954 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
958 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
959 return GetSysColorBrush(COLOR_3DFACE
);
962 return GetSysColorBrush(COLOR_WINDOW
);
965 static void DefWndPrint( HWND hwnd
, HDC hdc
, ULONG uFlags
)
970 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
971 !IsWindowVisible(hwnd
) )
975 * Unimplemented flags.
977 if ( (uFlags
& PRF_CHILDREN
) ||
978 (uFlags
& PRF_OWNED
) ||
979 (uFlags
& PRF_NONCLIENT
) )
981 FIXME("WM_PRINT message with unsupported flags\n");
987 if ( uFlags
& PRF_ERASEBKGND
)
988 SendMessageW(hwnd
, WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
993 if ( uFlags
& PRF_CLIENT
)
994 SendMessageW(hwnd
, WM_PRINTCLIENT
, (WPARAM
)hdc
, uFlags
);
998 UserSendUiUpdateMsg(HWND hwnd
, LPARAM lParam
)
1000 SendMessageW(hwnd
, WM_UPDATEUISTATE
, (WPARAM
)lParam
, 0);
1006 DefWndScreenshot(HWND hWnd
)
1015 OpenClipboard(hWnd
);
1018 hdc
= GetWindowDC(hWnd
);
1019 GetWindowRect(hWnd
, &rect
);
1020 w
= rect
.right
- rect
.left
;
1021 h
= rect
.bottom
- rect
.top
;
1023 hbitmap
= CreateCompatibleBitmap(hdc
, w
, h
);
1024 hdc2
= CreateCompatibleDC(hdc
);
1025 SelectObject(hdc2
, hbitmap
);
1027 BitBlt(hdc2
, 0, 0, w
, h
,
1031 SetClipboardData(CF_BITMAP
, hbitmap
);
1033 ReleaseDC(hWnd
, hdc
);
1034 ReleaseDC(hWnd
, hdc2
);
1043 User32DefWindowProc(HWND hWnd
,
1053 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
1058 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
1061 case WM_POPUPSYSTEMMENU
:
1063 /* This is an undocumented message used by the windows taskbar to
1064 display the system menu of windows that belong to other processes. */
1065 HMENU menu
= GetSystemMenu(hWnd
, FALSE
);
1068 TrackPopupMenu(menu
, TPM_LEFTBUTTON
|TPM_RIGHTBUTTON
,
1069 LOWORD(lParam
), HIWORD(lParam
), 0, hWnd
, NULL
);
1075 return DefWndNCActivate(hWnd
, wParam
);
1081 Point
.x
= GET_X_LPARAM(lParam
);
1082 Point
.y
= GET_Y_LPARAM(lParam
);
1083 return (DefWndNCHitTest(hWnd
, Point
));
1086 case WM_LBUTTONDOWN
:
1087 case WM_RBUTTONDOWN
:
1088 case WM_MBUTTONDOWN
:
1089 iF10Key
= iMenuSysKey
= 0;
1092 case WM_NCLBUTTONDOWN
:
1094 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
1097 case WM_LBUTTONDBLCLK
:
1098 return (DefWndNCLButtonDblClk(hWnd
, HTCLIENT
, lParam
));
1100 case WM_NCLBUTTONDBLCLK
:
1102 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
1105 case WM_WINDOWPOSCHANGING
:
1107 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1110 case WM_WINDOWPOSCHANGED
:
1112 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
1115 case WM_NCRBUTTONDOWN
:
1117 /* in Windows, capture is taken when right-clicking on the caption bar */
1118 if (wParam
== HTCAPTION
)
1128 if (hWnd
== GetCapture())
1132 Pt
.x
= GET_X_LPARAM(lParam
);
1133 Pt
.y
= GET_Y_LPARAM(lParam
);
1134 ClientToScreen(hWnd
, &Pt
);
1135 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1138 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1142 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1147 case WM_NCRBUTTONUP
:
1149 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1150 * in Windows), but what _should_ we do? According to MSDN :
1151 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1152 * message to the window". When is it appropriate?
1156 case WM_CONTEXTMENU
:
1158 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1162 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1166 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1175 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1177 Pt
.x
= GET_X_LPARAM(lParam
);
1178 Pt
.y
= GET_Y_LPARAM(lParam
);
1179 if (Style
& WS_CHILD
)
1181 ScreenToClient(GetParent(hWnd
), &Pt
);
1184 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1186 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1191 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1193 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongPtrW(hWnd
, GWL_STYLE
),
1194 GetClassLongPtrW(hWnd
, GCL_STYLE
), HitCode
);
1196 if(HitCode
== HTCAPTION
)
1197 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1199 Flags
= TPM_LEFTBUTTON
;
1201 TrackPopupMenu(SystemMenu
, Flags
,
1202 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1211 DefWndPrint(hWnd
, (HDC
)wParam
, lParam
);
1215 case WM_SYSCOLORCHANGE
:
1217 /* force to redraw non-client area */
1218 DefWndNCPaint(hWnd
, HRGN_WINDOW
, -1);
1219 /* Use InvalidateRect to redraw client area, enable
1220 * erase to redraw all subcontrols otherwise send the
1221 * WM_SYSCOLORCHANGE to child windows/controls is required
1223 InvalidateRect(hWnd
,NULL
,TRUE
);
1231 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1236 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1237 (hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
)) != NULL
)
1241 GetClientRect(hWnd
, &ClientRect
);
1242 x
= (ClientRect
.right
- ClientRect
.left
-
1243 GetSystemMetrics(SM_CXICON
)) / 2;
1244 y
= (ClientRect
.bottom
- ClientRect
.top
-
1245 GetSystemMetrics(SM_CYICON
)) / 2;
1246 DrawIcon(hDC
, x
, y
, hIcon
);
1248 EndPaint(hWnd
, &Ps
);
1256 hRgn
= CreateRectRgn(0, 0, 0, 0);
1257 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1259 RedrawWindow(hWnd
, NULL
, hRgn
,
1260 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1269 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1270 if (wParam
) SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
| WS_VISIBLE
);
1273 RedrawWindow(hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
1274 Style
&= ~WS_VISIBLE
;
1275 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
);
1282 DestroyWindow(hWnd
);
1286 case WM_MOUSEACTIVATE
:
1288 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1293 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1298 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1306 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1311 /* Check if the window is minimized. */
1312 if (LOWORD(wParam
) != WA_INACTIVE
&&
1313 !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1322 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1326 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1331 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1339 case WM_ICONERASEBKGND
:
1342 HBRUSH hBrush
= (HBRUSH
)GetClassLongPtrW(hWnd
, GCL_HBRBACKGROUND
);
1348 if (GetClassLongPtrW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1350 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1351 GetClientRect(hWnd
, &Rect
);
1352 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1356 GetClipBox((HDC
)wParam
, &Rect
);
1358 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1362 case WM_CTLCOLORMSGBOX
:
1363 case WM_CTLCOLOREDIT
:
1364 case WM_CTLCOLORLISTBOX
:
1365 case WM_CTLCOLORBTN
:
1366 case WM_CTLCOLORDLG
:
1367 case WM_CTLCOLORSTATIC
:
1368 case WM_CTLCOLORSCROLLBAR
:
1369 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1372 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
1376 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1378 if (Style
& WS_CHILD
)
1380 /* with the exception of the border around a resizable wnd,
1381 * give the parent first chance to set the cursor */
1382 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1384 HWND parent
= GetParent( hWnd
);
1387 if (parent
!= GetDesktopWindow() &&
1388 SendMessageW( parent
, WM_SETCURSOR
, wParam
, lParam
))
1393 if (parent
!= GetDesktopWindow() &&
1394 SendMessageA( parent
, WM_SETCURSOR
, wParam
, lParam
))
1399 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1403 return (DefWndHandleSysCommand(hWnd
, wParam
, lParam
));
1406 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
1411 if (HIWORD(lParam
) & KF_ALTDOWN
)
1412 { /* Previous state, if the key was down before this message,
1413 this is a cheap way to ignore autorepeat keys. */
1414 if ( !(HIWORD(lParam
) & KF_REPEAT
) )
1416 if ( ( wParam
== VK_MENU
||
1417 wParam
== VK_LMENU
||
1418 wParam
== VK_RMENU
) && !iMenuSysKey
)
1426 if (wParam
== VK_F4
) /* Try to close the window */
1428 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1429 if (!(GetClassLongPtrW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1430 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1432 else if (wParam
== VK_SNAPSHOT
) // Alt-VK_SNAPSHOT?
1435 while (GetParent(hwnd
) != NULL
)
1437 hwnd
= GetParent(hwnd
);
1439 DefWndScreenshot(hwnd
);
1441 else if ( wParam
== VK_ESCAPE
|| wParam
== VK_TAB
) // Alt-Tab/ESC Alt-Shift-Tab/ESC
1444 HWND Active
= GetActiveWindow(); // Noticed MDI problem.
1447 FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n");
1450 wParamTmp
= GetKeyState(VK_SHIFT
) & 0x8000 ? SC_PREVWINDOW
: SC_NEXTWINDOW
;
1451 SendMessageW( Active
, WM_SYSCOMMAND
, wParamTmp
, wParam
);
1454 else if( wParam
== VK_F10
)
1456 if (GetKeyState(VK_SHIFT
) & 0x8000)
1457 SendMessageW( hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, MAKELPARAM(-1, -1) );
1466 /* Press and release F10 or ALT */
1467 if (((wParam
== VK_MENU
|| wParam
== VK_LMENU
|| wParam
== VK_RMENU
)
1468 && iMenuSysKey
) || ((wParam
== VK_F10
) && iF10Key
))
1469 SendMessageW( GetAncestor( hWnd
, GA_ROOT
), WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1470 iMenuSysKey
= iF10Key
= 0;
1477 if (wParam
== VK_RETURN
&& IsIconic(hWnd
))
1479 PostMessageW( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0L );
1482 if ((HIWORD(lParam
) & KF_ALTDOWN
) && wParam
)
1484 if (wParam
== VK_TAB
|| wParam
== VK_ESCAPE
) break;
1485 if (wParam
== VK_SPACE
&& (GetWindowLongPtrW( hWnd
, GWL_STYLE
) & WS_CHILD
))
1486 SendMessageW( GetParent(hWnd
), Msg
, wParam
, lParam
);
1488 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, wParam
);
1490 else /* check for Ctrl-Esc */
1491 if (wParam
!= VK_ESCAPE
) MessageBeep(0);
1498 /* FIXME: Check for a desktop. */
1499 //if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
1500 MENU_EndMenu( hWnd
);
1501 if (GetCapture() == hWnd
)
1515 case WM_QUERYDROPOBJECT
:
1517 if (GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1524 case WM_QUERYDRAGICON
:
1529 hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
);
1532 return ((LRESULT
)hIcon
);
1534 for (Len
= 1; Len
< 64; Len
++)
1536 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1538 return((LRESULT
)hIcon
);
1541 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1544 case WM_ISACTIVEICON
:
1548 pWnd
= ValidateHwnd(hWnd
);
1549 if (!pWnd
) return 0;
1550 isai
= (pWnd
->state
& WNDS_ACTIVEFRAME
) != 0;
1554 case WM_NOTIFYFORMAT
:
1556 if (lParam
== NF_QUERY
)
1557 return IsWindowUnicode(hWnd
) ? NFR_UNICODE
: NFR_ANSI
;
1563 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1564 HICON hOldIcon
= (HICON
)GetClassLongPtrW(hWnd
, Index
);
1565 SetClassLongPtrW(hWnd
, Index
, lParam
);
1566 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1567 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1568 SWP_NOACTIVATE
| SWP_NOZORDER
);
1569 return ((LRESULT
)hOldIcon
);
1574 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1575 return (GetClassLongPtrW(hWnd
, Index
));
1582 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1586 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1593 THRDCARETINFO CaretInfo
;
1596 case 0xffff: /* Caret timer */
1597 /* switch showing byte in win32k and get information about the caret */
1598 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1600 DrawCaret(hWnd
, &CaretInfo
);
1608 case WM_QUERYENDSESSION
:
1613 case WM_INPUTLANGCHANGEREQUEST
:
1617 if(wParam
& INPUTLANGCHANGE_BACKWARD
1618 && wParam
& INPUTLANGCHANGE_FORWARD
)
1623 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1625 if(wParam
& INPUTLANGCHANGE_BACKWARD
) NewHkl
= (HKL
) HKL_PREV
;
1626 else if(wParam
& INPUTLANGCHANGE_FORWARD
) NewHkl
= (HKL
) HKL_NEXT
;
1627 else NewHkl
= (HKL
) lParam
;
1629 NtUserActivateKeyboardLayout(NewHkl
, 0);
1634 case WM_INPUTLANGCHANGE
:
1637 HWND
*win_array
= WIN_ListChildren( hWnd
);
1641 while (win_array
[count
])
1642 SendMessageW( win_array
[count
++], WM_INPUTLANGCHANGE
, wParam
, lParam
);
1643 HeapFree(GetProcessHeap(),0,win_array
);
1647 case WM_QUERYUISTATE
:
1650 PWND Wnd
= ValidateHwnd(hWnd
);
1654 Ret
|= UISF_HIDEFOCUS
;
1656 Ret
|= UISF_HIDEACCEL
;
1661 case WM_CHANGEUISTATE
:
1663 BOOL AlwaysShowCues
= FALSE
;
1664 WORD Action
= LOWORD(wParam
);
1665 WORD Flags
= HIWORD(wParam
);
1668 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1672 Wnd
= ValidateHwnd(hWnd
);
1673 if (!Wnd
|| lParam
!= 0)
1676 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1679 if (Flags
& UISF_ACTIVE
)
1681 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1684 if (Action
== UIS_INITIALIZE
)
1686 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1690 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1691 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1693 /* We need to update wParam in case we need to send out messages */
1694 wParam
= MAKEWPARAM(Action
, Flags
);
1700 /* See if we actually need to change something */
1701 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1703 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1706 /* Don't need to do anything... */
1710 /* See if we actually need to change something */
1711 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1713 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1716 /* Don't need to do anything... */
1720 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1724 if ((Wnd
->style
& WS_CHILD
) && Wnd
->spwndParent
!= NULL
)
1726 /* We're a child window and we need to pass this message down until
1727 we reach the root */
1728 hWnd
= UserHMGetHandle((PWND
)DesktopPtrToUser(Wnd
->spwndParent
));
1732 /* We're a top level window, we need to change the UI state */
1733 Msg
= WM_UPDATEUISTATE
;
1737 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1739 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1742 case WM_UPDATEUISTATE
:
1745 BOOL AlwaysShowCues
= FALSE
;
1746 WORD Action
= LOWORD(wParam
);
1747 WORD Flags
= HIWORD(wParam
);
1750 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1754 Wnd
= ValidateHwnd(hWnd
);
1755 if (!Wnd
|| lParam
!= 0)
1758 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1761 if (Flags
& UISF_ACTIVE
)
1763 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1766 if (Action
== UIS_INITIALIZE
)
1768 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1772 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1773 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1775 /* We need to update wParam for broadcasting the update */
1776 wParam
= MAKEWPARAM(Action
, Flags
);
1782 /* See if we actually need to change something */
1783 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1785 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1788 /* Don't need to do anything... */
1793 /* See if we actually need to change something */
1794 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1796 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1799 /* Don't need to do anything... */
1804 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1808 /* Pack the information and call win32k */
1811 if (!NtUserCallTwoParam((DWORD_PTR
)hWnd
, (DWORD_PTR
)Flags
| ((DWORD_PTR
)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE
))
1815 /* Always broadcast the update to all children */
1816 EnumChildWindows(hWnd
,
1817 UserSendUiUpdateMsg
,
1823 /* Move to win32k !*/
1825 if (!lParam
) break; // Call when it is necessary.
1826 case WM_CLIENTSHUTDOWN
:
1831 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, !bUnicode
);
1840 * helpers for calling IMM32 (from Wine 10/22/2008)
1842 * WM_IME_* messages are generated only by IMM32,
1843 * so I assume imm32 is already LoadLibrary-ed.
1846 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1848 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1849 HWND (WINAPI
*pFunc
)(HWND
);
1854 ERR("cannot get IMM32 handle\n");
1858 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1860 hwndRet
= (*pFunc
)(hwnd
);
1867 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1869 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1870 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1875 ERR("cannot get IMM32 handle\n");
1879 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1881 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1888 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1890 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1891 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1896 ERR("cannot get IMM32 handle\n");
1900 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1902 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1909 RealDefWindowProcA(HWND hWnd
,
1917 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1924 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1925 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1926 * may have child window IDs instead of window name */
1927 if (HIWORD(cs
->lpszName
))
1929 DefSetText(hWnd
, (PCWSTR
)cs
->lpszName
, TRUE
);
1936 case WM_GETTEXTLENGTH
:
1941 Wnd
= ValidateHwnd(hWnd
);
1942 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
1944 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1946 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1948 Wnd
->strName
.Length
)))
1950 Result
= (LRESULT
) len
;
1961 PSTR outbuf
= (PSTR
)lParam
;
1964 Wnd
= ValidateHwnd(hWnd
);
1965 if (Wnd
!= NULL
&& wParam
!= 0)
1967 if (Wnd
->strName
.Buffer
!= NULL
)
1968 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1974 if (Wnd
->strName
.Length
!= 0)
1976 copy
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1977 Result
= WideCharToMultiByte(CP_ACP
,
1985 outbuf
[Result
] = '\0';
1996 DefSetText(hWnd
, (PCWSTR
)lParam
, TRUE
);
1998 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2000 DefWndNCPaint(hWnd
, HRGN_WINDOW
, -1);
2006 case WM_IME_KEYDOWN
:
2008 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2014 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
2021 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
2022 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
2026 case WM_IME_STARTCOMPOSITION
:
2027 case WM_IME_COMPOSITION
:
2028 case WM_IME_ENDCOMPOSITION
:
2034 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2036 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
2040 case WM_IME_SETCONTEXT
:
2044 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2046 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
2052 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2055 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2061 RealDefWindowProcW(HWND hWnd
,
2069 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
2076 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
2077 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2078 * may have child window IDs instead of window name */
2079 if (HIWORD(cs
->lpszName
))
2081 DefSetText(hWnd
, cs
->lpszName
, FALSE
);
2088 case WM_GETTEXTLENGTH
:
2093 Wnd
= ValidateHwnd(hWnd
);
2094 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
2096 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2098 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
2100 Wnd
->strName
.Length
)))
2102 Result
= (LRESULT
) (Wnd
->strName
.Length
/ sizeof(WCHAR
));
2113 PWSTR outbuf
= (PWSTR
)lParam
;
2115 Wnd
= ValidateHwnd(hWnd
);
2116 if (Wnd
!= NULL
&& wParam
!= 0)
2118 if (Wnd
->strName
.Buffer
!= NULL
)
2119 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2125 if (Wnd
->strName
.Length
!= 0)
2127 Result
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
2128 RtlCopyMemory(outbuf
,
2130 Result
* sizeof(WCHAR
));
2131 outbuf
[Result
] = L
'\0';
2142 DefSetText(hWnd
, (PCWSTR
)lParam
, FALSE
);
2144 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2146 DefWndNCPaint(hWnd
, HRGN_WINDOW
, -1);
2154 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
2159 case WM_IME_KEYDOWN
:
2161 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2167 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
2171 case WM_IME_STARTCOMPOSITION
:
2172 case WM_IME_COMPOSITION
:
2173 case WM_IME_ENDCOMPOSITION
:
2179 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2181 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
2185 case WM_IME_SETCONTEXT
:
2189 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2191 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
2196 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
2198 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2204 DefWindowProcA(HWND hWnd
,
2209 BOOL Hook
, msgOverride
= FALSE
;
2214 Hook
= BeginIfHookedUserApiHook();
2216 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2218 /* Bypass SEH and go direct. */
2219 if (!Hook
|| !msgOverride
)
2220 return RealDefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2224 Result
= guah
.DefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2226 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2237 DefWindowProcW(HWND hWnd
,
2242 BOOL Hook
, msgOverride
= FALSE
;
2247 Hook
= BeginIfHookedUserApiHook();
2249 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2251 /* Bypass SEH and go direct. */
2252 if (!Hook
|| !msgOverride
)
2253 return RealDefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2257 Result
= guah
.DefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2259 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)