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
)
106 LARGE_STRING lsString
;
111 RtlInitLargeAnsiString((PLARGE_ANSI_STRING
)&lsString
, (PCSZ
)String
, 0);
113 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING
)&lsString
, String
, 0);
115 return NtUserDefSetText(hWnd
, (String
? &lsString
: NULL
));
119 UserGetInsideRectNC(PWND Wnd
, RECT
*rect
)
125 ExStyle
= Wnd
->ExStyle
;
127 rect
->top
= rect
->left
= 0;
128 rect
->right
= Wnd
->rcWindow
.right
- Wnd
->rcWindow
.left
;
129 rect
->bottom
= Wnd
->rcWindow
.bottom
- Wnd
->rcWindow
.top
;
131 if (Style
& WS_ICONIC
)
136 /* Remove frame from rectangle */
137 if (UserHasThickFrameStyle(Style
, ExStyle
))
139 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
140 -GetSystemMetrics(SM_CYFRAME
));
144 if (UserHasDlgFrameStyle(Style
, ExStyle
))
146 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
147 -GetSystemMetrics(SM_CYDLGFRAME
));
148 /* FIXME: this isn't in NC_AdjustRect? why not? */
149 if (ExStyle
& WS_EX_DLGMODALFRAME
)
150 InflateRect( rect
, -1, 0 );
154 if (UserHasThinFrameStyle(Style
, ExStyle
))
156 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
157 -GetSystemMetrics(SM_CYBORDER
));
165 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
167 LONG Style
= GetWindowLongPtr(hWnd
, GWL_STYLE
);
168 /* Content can be redrawn after a change. */
171 if (!(Style
& WS_VISIBLE
)) /* Not Visible */
173 SetWindowLongPtr(hWnd
, GWL_STYLE
, WS_VISIBLE
);
176 else /* Content cannot be redrawn after a change. */
178 if (Style
& WS_VISIBLE
) /* Visible */
180 RedrawWindow( hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
181 Style
&= ~WS_VISIBLE
;
182 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
); /* clear bits */
190 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
192 /* Not for child windows. */
193 if (hWnd
!= (HWND
)wParam
)
198 switch((INT_PTR
) LOWORD(lParam
))
202 WORD Msg
= HIWORD(lParam
);
203 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
204 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
213 HICON hCursor
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HCURSOR
);
225 if (Style
& WS_MAXIMIZE
)
229 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
235 if (Style
& WS_MAXIMIZE
)
239 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
245 if (Style
& WS_MAXIMIZE
)
249 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
255 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
259 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
262 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
266 DefWndStartSizeMove(HWND hWnd
, PWND Wnd
, WPARAM wParam
, POINT
*capturePoint
)
272 ULONG Style
= Wnd
->style
;
274 rectWindow
= Wnd
->rcWindow
;
276 if ((wParam
& 0xfff0) == SC_MOVE
)
278 /* Move pointer at the center of the caption */
280 UserGetInsideRectNC(Wnd
, &rect
);
281 if (Style
& WS_SYSMENU
)
282 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
283 if (Style
& WS_MINIMIZEBOX
)
284 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
285 if (Style
& WS_MAXIMIZEBOX
)
286 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
287 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
288 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
297 if (GetMessageW(&msg
, NULL
, 0, 0) <= 0)
302 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
303 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
315 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
316 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
320 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
321 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
325 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
326 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
330 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
331 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
334 case VK_ESCAPE
: return 0;
340 SetCursorPos( pt
.x
, pt
.y
);
341 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
345 #define ON_LEFT_BORDER(hit) \
346 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
347 #define ON_RIGHT_BORDER(hit) \
348 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
349 #define ON_TOP_BORDER(hit) \
350 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
351 #define ON_BOTTOM_BORDER(hit) \
352 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
355 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
356 ULONG width
, ULONG height
)
358 static HBRUSH hDraggingRectBrush
= NULL
;
361 if(!hDraggingRectBrush
)
363 static HBITMAP hDraggingPattern
= NULL
;
364 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
366 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
367 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
370 hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
371 PatBlt( hdc
, rect
->left
, rect
->top
,
372 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
373 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
374 rect
->bottom
- rect
->top
- height
, PATINVERT
);
375 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
376 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
377 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
378 rect
->bottom
- rect
->top
- height
, PATINVERT
);
379 SelectObject( hdc
, hbrush
);
383 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
387 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
));
391 UserDrawWindowFrame(hdc
, rect
, 1, 1);
396 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
400 RECT sizingRect
, mouseRect
, origRect
, clipRect
, unmodRect
;
402 LONG hittest
= (LONG
)(wParam
& 0x0f);
403 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
404 POINT minTrack
, maxTrack
;
405 POINT capturePoint
, pt
;
406 ULONG Style
, ExStyle
;
410 DWORD dwPoint
= GetMessagePos();
411 BOOL DragFullWindows
= FALSE
;
412 HWND hWndParent
= NULL
;
415 Wnd
= ValidateHwnd(hwnd
);
420 ExStyle
= Wnd
->ExStyle
;
421 iconic
= (Style
& WS_MINIMIZE
) != 0;
423 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
425 pt
.x
= GET_X_LPARAM(dwPoint
);
426 pt
.y
= GET_Y_LPARAM(dwPoint
);
429 if ((Style
& WS_MAXIMIZE
) || !IsWindowVisible(hwnd
))
434 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
435 if ((wParam
& 0xfff0) == SC_MOVE
)
439 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
452 if (hittest
&& ((wParam
& 0xfff0) != SC_MOUSEMENU
))
454 hittest
+= (HTLEFT
- WMSZ_LEFT
);
459 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
468 /* Get min/max info */
470 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
471 sizingRect
= Wnd
->rcWindow
;
472 if (Style
& WS_CHILD
)
474 hWndParent
= GetParent(hwnd
);
475 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
476 unmodRect
= sizingRect
;
477 GetClientRect(hWndParent
, &mouseRect
);
478 clipRect
= mouseRect
;
479 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
483 if(!(ExStyle
& WS_EX_TOPMOST
))
485 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
486 mouseRect
= clipRect
;
490 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
491 clipRect
= mouseRect
;
493 unmodRect
= sizingRect
;
495 ClipCursor(&clipRect
);
497 origRect
= sizingRect
;
498 if (ON_LEFT_BORDER(hittest
))
500 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
501 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
503 else if (ON_RIGHT_BORDER(hittest
))
505 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
506 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
508 if (ON_TOP_BORDER(hittest
))
510 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
511 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
513 else if (ON_BOTTOM_BORDER(hittest
))
515 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
516 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
518 if (Style
& WS_CHILD
)
520 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
523 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
524 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
525 if (GetCapture() != hwnd
) SetCapture( hwnd
);
527 if (Style
& WS_CHILD
)
529 /* Retrieve a default cache DC (without using the window style) */
530 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
536 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
539 SelectObject(hdc
, DesktopRgn
);
541 if( iconic
) /* create a cursor for dragging */
543 HICON hIcon
= (HICON
)GetClassLongPtrW(hwnd
, GCL_HICON
);
544 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
545 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
546 if( !hDragCursor
) iconic
= FALSE
;
549 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
550 if( !iconic
&& !DragFullWindows
)
552 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
559 if (GetMessageW(&msg
, 0, 0, 0) <= 0)
562 /* Exit on button-up, Return, or Esc */
563 if ((msg
.message
== WM_LBUTTONUP
) ||
564 ((msg
.message
== WM_KEYDOWN
) &&
565 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
567 if (msg
.message
== WM_PAINT
)
569 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
570 UpdateWindow( msg
.hwnd
);
571 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
575 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
576 continue; /* We are not interested in other messages */
580 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
582 case VK_UP
: pt
.y
-= 8; break;
583 case VK_DOWN
: pt
.y
+= 8; break;
584 case VK_LEFT
: pt
.x
-= 8; break;
585 case VK_RIGHT
: pt
.x
+= 8; break;
588 pt
.x
= max( pt
.x
, mouseRect
.left
);
589 pt
.x
= min( pt
.x
, mouseRect
.right
);
590 pt
.y
= max( pt
.y
, mouseRect
.top
);
591 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
593 dx
= pt
.x
- capturePoint
.x
;
594 dy
= pt
.y
- capturePoint
.y
;
602 if( iconic
) /* ok, no system popup tracking */
604 hOldCursor
= SetCursor(hDragCursor
);
609 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
612 RECT newRect
= unmodRect
;
613 WPARAM wpSizingHit
= 0;
615 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
616 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
617 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
618 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
619 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
620 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
623 /* determine the hit location */
624 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
625 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
627 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
632 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
634 /* To avoid any deadlocks, all the locks on the windows
635 structures must be suspended before the SetWindowPos */
636 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
637 newRect
.right
- newRect
.left
,
638 newRect
.bottom
- newRect
.top
,
639 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
642 sizingRect
= newRect
;
651 if( moved
) /* restore cursors, show icon title later on */
654 SetCursor( hOldCursor
);
656 DestroyCursor( hDragCursor
);
658 else if(!DragFullWindows
)
659 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
661 if (Style
& WS_CHILD
)
662 ReleaseDC( hWndParent
, hdc
);
668 DeleteObject(DesktopRgn
);
672 if (ISITHOOKED(WH_CBT
))
675 NtUserMessageCall( hwnd
, WM_CBT
, HCBT_MOVESIZE
, (LPARAM
)&sizingRect
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
676 if (lResult
) moved
= FALSE
;
679 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
680 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
681 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
683 /* window moved or resized */
686 /* if the moving/resizing isn't canceled call SetWindowPos
687 * with the new position or the new size of the window
689 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
691 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
693 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
694 sizingRect
.right
- sizingRect
.left
,
695 sizingRect
.bottom
- sizingRect
.top
,
696 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
698 else { /* restore previous size/position */
700 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
701 origRect
.right
- origRect
.left
,
702 origRect
.bottom
- origRect
.top
,
703 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
708 if( Style
& WS_MINIMIZE
)
710 /* Single click brings up the system menu when iconized */
714 if( Style
& WS_SYSMENU
)
715 SendMessageA( hwnd
, WM_SYSCOMMAND
,
716 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
722 /***********************************************************************
723 * DefWndTrackScrollBar
725 * Track a mouse button press on the horizontal or vertical scroll-bar.
728 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
732 if (SC_HSCROLL
== (wParam
& 0xfff0))
734 if (HTHSCROLL
!= (wParam
& 0x0f))
740 else /* SC_VSCROLL */
742 if (HTVSCROLL
!= (wParam
& 0x0f))
748 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
753 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
758 if (!IsWindowEnabled( hWnd
)) return 0;
760 if (ISITHOOKED(WH_CBT
))
763 NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
764 if (lResult
) return 0;
767 switch (wParam
& 0xfff0)
771 DefWndDoSizeMove(hWnd
, wParam
);
774 wp
.length
= sizeof(WINDOWPLACEMENT
);
775 if(GetWindowPlacement(hWnd
, &wp
))
777 wp
.showCmd
= SW_MINIMIZE
;
778 SetWindowPlacement(hWnd
, &wp
);
782 wp
.length
= sizeof(WINDOWPLACEMENT
);
783 if(GetWindowPlacement(hWnd
, &wp
))
785 wp
.showCmd
= SW_MAXIMIZE
;
786 SetWindowPlacement(hWnd
, &wp
);
790 wp
.length
= sizeof(WINDOWPLACEMENT
);
791 if(GetWindowPlacement(hWnd
, &wp
))
793 wp
.showCmd
= SW_RESTORE
;
794 SetWindowPlacement(hWnd
, &wp
);
798 return SendMessageW(hWnd
, WM_CLOSE
, 0, 0);
802 Pt
.x
= (short)LOWORD(lParam
);
803 Pt
.y
= (short)HIWORD(lParam
);
804 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
808 MenuTrackKbdMenuBar(hWnd
, wParam
, (WCHAR
)lParam
);
813 Pt
.x
= (short)LOWORD(lParam
);
814 Pt
.y
= (short)HIWORD(lParam
);
815 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
820 /* FIXME: Implement */
829 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
831 POINT maxTrack
, minTrack
;
832 LONG style
= GetWindowLongPtrA(hWnd
, GWL_STYLE
);
834 if (Pos
->flags
& SWP_NOSIZE
) return 0;
835 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
837 WinPosGetMinMaxInfo(hWnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
838 Pos
->cx
= min(Pos
->cx
, maxTrack
.x
);
839 Pos
->cy
= min(Pos
->cy
, maxTrack
.y
);
840 if (!(style
& WS_MINIMIZE
))
842 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
843 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
848 Pos
->cx
= max(Pos
->cx
, 0);
849 Pos
->cy
= max(Pos
->cy
, 0);
854 /* Undocumented flags. */
855 #define SWP_NOCLIENTMOVE 0x0800
856 #define SWP_NOCLIENTSIZE 0x1000
859 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
863 GetClientRect(hWnd
, &Rect
);
864 MapWindowPoints(hWnd
, (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
?
865 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
867 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
869 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
872 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
874 WPARAM wp
= SIZE_RESTORED
;
879 else if (IsIconic(hWnd
))
883 SendMessageW(hWnd
, WM_SIZE
, wp
,
884 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
890 /***********************************************************************
893 * Default colors for control painting.
896 DefWndControlColor(HDC hDC
, UINT ctlType
)
898 if (CTLCOLOR_SCROLLBAR
== ctlType
)
900 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
901 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
902 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
905 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
906 * we better use 0x55aa bitmap brush to make scrollbar's background
907 * look different from the window background.
909 if (bk
== GetSysColor(COLOR_WINDOW
))
911 static const WORD wPattern55AA
[] =
913 0x5555, 0xaaaa, 0x5555, 0xaaaa,
914 0x5555, 0xaaaa, 0x5555, 0xaaaa
916 static HBITMAP hPattern55AABitmap
= NULL
;
917 static HBRUSH hPattern55AABrush
= NULL
;
918 if (hPattern55AABrush
== NULL
)
920 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
921 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
923 return hPattern55AABrush
;
929 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
931 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
933 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
937 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
938 return GetSysColorBrush(COLOR_3DFACE
);
941 return GetSysColorBrush(COLOR_WINDOW
);
944 static void DefWndPrint( HWND hwnd
, HDC hdc
, ULONG uFlags
)
949 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
950 !IsWindowVisible(hwnd
) )
954 * Unimplemented flags.
956 if ( (uFlags
& PRF_CHILDREN
) ||
957 (uFlags
& PRF_OWNED
) ||
958 (uFlags
& PRF_NONCLIENT
) )
960 FIXME("WM_PRINT message with unsupported flags\n");
966 if ( uFlags
& PRF_ERASEBKGND
)
967 SendMessageW(hwnd
, WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
972 if ( uFlags
& PRF_CLIENT
)
973 SendMessageW(hwnd
, WM_PRINTCLIENT
, (WPARAM
)hdc
, uFlags
);
977 UserSendUiUpdateMsg(HWND hwnd
, LPARAM lParam
)
979 SendMessageW(hwnd
, WM_UPDATEUISTATE
, (WPARAM
)lParam
, 0);
985 DefWndScreenshot(HWND hWnd
)
997 hdc
= GetWindowDC(hWnd
);
998 GetWindowRect(hWnd
, &rect
);
999 w
= rect
.right
- rect
.left
;
1000 h
= rect
.bottom
- rect
.top
;
1002 hbitmap
= CreateCompatibleBitmap(hdc
, w
, h
);
1003 hdc2
= CreateCompatibleDC(hdc
);
1004 SelectObject(hdc2
, hbitmap
);
1006 BitBlt(hdc2
, 0, 0, w
, h
,
1010 SetClipboardData(CF_BITMAP
, hbitmap
);
1012 ReleaseDC(hWnd
, hdc
);
1013 ReleaseDC(hWnd
, hdc2
);
1022 User32DefWindowProc(HWND hWnd
,
1032 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
1037 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
1040 case WM_POPUPSYSTEMMENU
:
1042 /* This is an undocumented message used by the windows taskbar to
1043 display the system menu of windows that belong to other processes. */
1044 HMENU menu
= GetSystemMenu(hWnd
, FALSE
);
1047 TrackPopupMenu(menu
, TPM_LEFTBUTTON
|TPM_RIGHTBUTTON
,
1048 LOWORD(lParam
), HIWORD(lParam
), 0, hWnd
, NULL
);
1054 return DefWndNCActivate(hWnd
, wParam
);
1060 Point
.x
= GET_X_LPARAM(lParam
);
1061 Point
.y
= GET_Y_LPARAM(lParam
);
1062 return (DefWndNCHitTest(hWnd
, Point
));
1065 case WM_LBUTTONDOWN
:
1066 case WM_RBUTTONDOWN
:
1067 case WM_MBUTTONDOWN
:
1068 iF10Key
= iMenuSysKey
= 0;
1071 case WM_NCLBUTTONDOWN
:
1073 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
1076 case WM_LBUTTONDBLCLK
:
1077 return (DefWndNCLButtonDblClk(hWnd
, HTCLIENT
, lParam
));
1079 case WM_NCLBUTTONDBLCLK
:
1081 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
1084 case WM_WINDOWPOSCHANGING
:
1086 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1089 case WM_WINDOWPOSCHANGED
:
1091 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
1094 case WM_NCRBUTTONDOWN
:
1096 /* in Windows, capture is taken when right-clicking on the caption bar */
1097 if (wParam
== HTCAPTION
)
1107 if (hWnd
== GetCapture())
1111 Pt
.x
= GET_X_LPARAM(lParam
);
1112 Pt
.y
= GET_Y_LPARAM(lParam
);
1113 ClientToScreen(hWnd
, &Pt
);
1114 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1117 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1121 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1126 case WM_NCRBUTTONUP
:
1128 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1129 * in Windows), but what _should_ we do? According to MSDN :
1130 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1131 * message to the window". When is it appropriate?
1135 case WM_CONTEXTMENU
:
1137 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1141 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1145 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1154 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1156 Pt
.x
= GET_X_LPARAM(lParam
);
1157 Pt
.y
= GET_Y_LPARAM(lParam
);
1158 if (Style
& WS_CHILD
)
1160 ScreenToClient(GetParent(hWnd
), &Pt
);
1163 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1165 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1170 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1172 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongPtrW(hWnd
, GWL_STYLE
),
1173 GetClassLongPtrW(hWnd
, GCL_STYLE
), HitCode
);
1175 if(HitCode
== HTCAPTION
)
1176 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1178 Flags
= TPM_LEFTBUTTON
;
1180 TrackPopupMenu(SystemMenu
, Flags
,
1181 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1190 DefWndPrint(hWnd
, (HDC
)wParam
, lParam
);
1194 case WM_SYSCOLORCHANGE
:
1196 /* force to redraw non-client area */
1197 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1198 /* Use InvalidateRect to redraw client area, enable
1199 * erase to redraw all subcontrols otherwise send the
1200 * WM_SYSCOLORCHANGE to child windows/controls is required
1202 InvalidateRect(hWnd
,NULL
,TRUE
);
1210 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1215 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1216 (hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
)) != NULL
)
1220 GetClientRect(hWnd
, &ClientRect
);
1221 x
= (ClientRect
.right
- ClientRect
.left
-
1222 GetSystemMetrics(SM_CXICON
)) / 2;
1223 y
= (ClientRect
.bottom
- ClientRect
.top
-
1224 GetSystemMetrics(SM_CYICON
)) / 2;
1225 DrawIcon(hDC
, x
, y
, hIcon
);
1227 EndPaint(hWnd
, &Ps
);
1235 hRgn
= CreateRectRgn(0, 0, 0, 0);
1236 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1238 RedrawWindow(hWnd
, NULL
, hRgn
,
1239 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1248 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1249 if (wParam
) SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
| WS_VISIBLE
);
1252 RedrawWindow(hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
1253 Style
&= ~WS_VISIBLE
;
1254 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
);
1261 DestroyWindow(hWnd
);
1265 case WM_MOUSEACTIVATE
:
1267 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1272 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1277 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1285 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1290 /* Check if the window is minimized. */
1291 if (LOWORD(wParam
) != WA_INACTIVE
&&
1292 !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1301 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1305 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1310 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1318 case WM_ICONERASEBKGND
:
1321 HBRUSH hBrush
= (HBRUSH
)GetClassLongPtrW(hWnd
, GCL_HBRBACKGROUND
);
1327 if (GetClassLongPtrW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1329 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1330 GetClientRect(hWnd
, &Rect
);
1331 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1335 GetClipBox((HDC
)wParam
, &Rect
);
1337 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1341 case WM_CTLCOLORMSGBOX
:
1342 case WM_CTLCOLOREDIT
:
1343 case WM_CTLCOLORLISTBOX
:
1344 case WM_CTLCOLORBTN
:
1345 case WM_CTLCOLORDLG
:
1346 case WM_CTLCOLORSTATIC
:
1347 case WM_CTLCOLORSCROLLBAR
:
1348 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1351 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
1355 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1357 if (Style
& WS_CHILD
)
1359 /* with the exception of the border around a resizable wnd,
1360 * give the parent first chance to set the cursor */
1361 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1363 HWND parent
= GetParent( hWnd
);
1366 if (parent
!= GetDesktopWindow() &&
1367 SendMessageW( parent
, WM_SETCURSOR
, wParam
, lParam
))
1372 if (parent
!= GetDesktopWindow() &&
1373 SendMessageA( parent
, WM_SETCURSOR
, wParam
, lParam
))
1378 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1382 return (DefWndHandleSysCommand(hWnd
, wParam
, lParam
));
1385 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
1388 /* FIXME: This is also incomplete. */
1391 if (HIWORD(lParam
) & KEYDATA_ALT
)
1393 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1394 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
1395 if ( (wParam
== VK_MENU
|| wParam
== VK_LMENU
1396 || wParam
== VK_RMENU
) && !iMenuSysKey
)
1403 if (wParam
== VK_F4
) /* Try to close the window */
1405 if (!(GetClassLongPtrW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1408 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1410 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1413 else if (wParam
== VK_SNAPSHOT
)
1416 while (GetParent(hwnd
) != NULL
)
1418 hwnd
= GetParent(hwnd
);
1420 DefWndScreenshot(hwnd
);
1423 else if( wParam
== VK_F10
)
1425 if (GetKeyState(VK_SHIFT
) & 0x8000)
1426 SendMessageW( hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, MAKELPARAM(-1, -1) );
1429 else if( wParam
== VK_ESCAPE
&& (GetKeyState(VK_SHIFT
) & 0x8000))
1430 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, ' ' );
1437 /* Press and release F10 or ALT */
1438 if (((wParam
== VK_MENU
|| wParam
== VK_LMENU
|| wParam
== VK_RMENU
)
1439 && iMenuSysKey
) || ((wParam
== VK_F10
) && iF10Key
))
1440 SendMessageW( GetAncestor( hWnd
, GA_ROOT
), WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1441 iMenuSysKey
= iF10Key
= 0;
1448 if (wParam
== '\r' && IsIconic(hWnd
))
1450 PostMessageW( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0L );
1453 if ((HIWORD(lParam
) & KEYDATA_ALT
) && wParam
)
1455 if (wParam
== '\t' || wParam
== '\x1b') break;
1456 if (wParam
== ' ' && (GetWindowLongPtrW( hWnd
, GWL_STYLE
) & WS_CHILD
))
1457 SendMessageW( GetParent(hWnd
), Msg
, wParam
, lParam
);
1459 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, wParam
);
1461 else /* check for Ctrl-Esc */
1462 if (wParam
!= '\x1b') MessageBeep(0);
1468 if (lParam
) // Call when it is necessary.
1469 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, 0, FNID_DEFWINDOWPROC
, FALSE
);
1473 case WM_CLIENTSHUTDOWN
:
1476 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
1483 /* FIXME: Check for a desktop. */
1484 //if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
1485 MENU_EndMenu( hWnd
);
1486 if (GetCapture() == hWnd
)
1500 case WM_QUERYDROPOBJECT
:
1502 if (GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1509 case WM_QUERYDRAGICON
:
1514 hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
);
1517 return ((LRESULT
)hIcon
);
1519 for (Len
= 1; Len
< 64; Len
++)
1521 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1523 return((LRESULT
)hIcon
);
1526 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1529 case WM_ISACTIVEICON
:
1533 pWnd
= ValidateHwnd(hWnd
);
1534 if (!pWnd
) return 0;
1535 isai
= (pWnd
->state
& WNDS_ACTIVEFRAME
) != 0;
1539 case WM_NOTIFYFORMAT
:
1541 if (lParam
== NF_QUERY
)
1542 return IsWindowUnicode(hWnd
) ? NFR_UNICODE
: NFR_ANSI
;
1548 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1549 HICON hOldIcon
= (HICON
)GetClassLongPtrW(hWnd
, Index
);
1550 SetClassLongPtrW(hWnd
, Index
, lParam
);
1551 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1552 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1553 SWP_NOACTIVATE
| SWP_NOZORDER
);
1554 return ((LRESULT
)hOldIcon
);
1559 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1560 return (GetClassLongPtrW(hWnd
, Index
));
1567 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1571 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1578 THRDCARETINFO CaretInfo
;
1581 case 0xffff: /* Caret timer */
1582 /* switch showing byte in win32k and get information about the caret */
1583 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1585 DrawCaret(hWnd
, &CaretInfo
);
1593 case WM_QUERYENDSESSION
:
1598 case WM_INPUTLANGCHANGEREQUEST
:
1602 if(wParam
& INPUTLANGCHANGE_BACKWARD
1603 && wParam
& INPUTLANGCHANGE_FORWARD
)
1608 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1610 if(wParam
& INPUTLANGCHANGE_BACKWARD
) NewHkl
= (HKL
) HKL_PREV
;
1611 else if(wParam
& INPUTLANGCHANGE_FORWARD
) NewHkl
= (HKL
) HKL_NEXT
;
1612 else NewHkl
= (HKL
) lParam
;
1614 NtUserActivateKeyboardLayout(NewHkl
, 0);
1619 case WM_INPUTLANGCHANGE
:
1622 HWND
*win_array
= WIN_ListChildren( hWnd
);
1626 while (win_array
[count
])
1627 SendMessageW( win_array
[count
++], WM_INPUTLANGCHANGE
, wParam
, lParam
);
1628 HeapFree(GetProcessHeap(),0,win_array
);
1632 case WM_QUERYUISTATE
:
1635 PWND Wnd
= ValidateHwnd(hWnd
);
1639 Ret
|= UISF_HIDEFOCUS
;
1641 Ret
|= UISF_HIDEACCEL
;
1646 case WM_CHANGEUISTATE
:
1648 BOOL AlwaysShowCues
= FALSE
;
1649 WORD Action
= LOWORD(wParam
);
1650 WORD Flags
= HIWORD(wParam
);
1653 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1657 Wnd
= ValidateHwnd(hWnd
);
1658 if (!Wnd
|| lParam
!= 0)
1661 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1664 if (Flags
& UISF_ACTIVE
)
1666 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1669 if (Action
== UIS_INITIALIZE
)
1671 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1675 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1676 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1678 /* We need to update wParam in case we need to send out messages */
1679 wParam
= MAKEWPARAM(Action
, Flags
);
1685 /* See if we actually need to change something */
1686 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1688 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1691 /* Don't need to do anything... */
1695 /* See if we actually need to change something */
1696 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1698 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1701 /* Don't need to do anything... */
1705 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1709 if ((Wnd
->style
& WS_CHILD
) && Wnd
->spwndParent
!= NULL
)
1711 /* We're a child window and we need to pass this message down until
1712 we reach the root */
1713 hWnd
= UserHMGetHandle((PWND
)DesktopPtrToUser(Wnd
->spwndParent
));
1717 /* We're a top level window, we need to change the UI state */
1718 Msg
= WM_UPDATEUISTATE
;
1722 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1724 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1727 case WM_UPDATEUISTATE
:
1730 BOOL AlwaysShowCues
= FALSE
;
1731 WORD Action
= LOWORD(wParam
);
1732 WORD Flags
= HIWORD(wParam
);
1735 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1739 Wnd
= ValidateHwnd(hWnd
);
1740 if (!Wnd
|| lParam
!= 0)
1743 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1746 if (Flags
& UISF_ACTIVE
)
1748 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1751 if (Action
== UIS_INITIALIZE
)
1753 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1757 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1758 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1760 /* We need to update wParam for broadcasting the update */
1761 wParam
= MAKEWPARAM(Action
, Flags
);
1767 /* See if we actually need to change something */
1768 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1770 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1773 /* Don't need to do anything... */
1778 /* See if we actually need to change something */
1779 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1781 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1784 /* Don't need to do anything... */
1789 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1793 /* Pack the information and call win32k */
1796 if (!NtUserCallTwoParam((DWORD_PTR
)hWnd
, (DWORD_PTR
)Flags
| ((DWORD_PTR
)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE
))
1800 /* Always broadcast the update to all children */
1801 EnumChildWindows(hWnd
,
1802 UserSendUiUpdateMsg
,
1814 * helpers for calling IMM32 (from Wine 10/22/2008)
1816 * WM_IME_* messages are generated only by IMM32,
1817 * so I assume imm32 is already LoadLibrary-ed.
1820 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1822 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1823 HWND (WINAPI
*pFunc
)(HWND
);
1828 ERR("cannot get IMM32 handle\n");
1832 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1834 hwndRet
= (*pFunc
)(hwnd
);
1841 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1843 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1844 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1849 ERR("cannot get IMM32 handle\n");
1853 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1855 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1862 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1864 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1865 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1870 ERR("cannot get IMM32 handle\n");
1874 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1876 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1883 RealDefWindowProcA(HWND hWnd
,
1891 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1898 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1899 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1900 * may have child window IDs instead of window name */
1901 if (HIWORD(cs
->lpszName
))
1903 DefSetText(hWnd
, (PCWSTR
)cs
->lpszName
, TRUE
);
1910 case WM_GETTEXTLENGTH
:
1915 Wnd
= ValidateHwnd(hWnd
);
1916 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
1918 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1920 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1922 Wnd
->strName
.Length
)))
1924 Result
= (LRESULT
) len
;
1935 PSTR outbuf
= (PSTR
)lParam
;
1938 Wnd
= ValidateHwnd(hWnd
);
1939 if (Wnd
!= NULL
&& wParam
!= 0)
1941 if (Wnd
->strName
.Buffer
!= NULL
)
1942 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1948 if (Wnd
->strName
.Length
!= 0)
1950 copy
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1951 Result
= WideCharToMultiByte(CP_ACP
,
1959 outbuf
[Result
] = '\0';
1970 DefSetText(hWnd
, (PCWSTR
)lParam
, TRUE
);
1972 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1974 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1981 case WM_IME_KEYDOWN
:
1983 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
1989 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
1996 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
1997 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
2001 case WM_IME_STARTCOMPOSITION
:
2002 case WM_IME_COMPOSITION
:
2003 case WM_IME_ENDCOMPOSITION
:
2009 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2011 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
2015 case WM_IME_SETCONTEXT
:
2019 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2021 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
2027 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2030 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2036 RealDefWindowProcW(HWND hWnd
,
2044 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
2051 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
2052 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2053 * may have child window IDs instead of window name */
2054 if (HIWORD(cs
->lpszName
))
2056 DefSetText(hWnd
, cs
->lpszName
, FALSE
);
2063 case WM_GETTEXTLENGTH
:
2068 Wnd
= ValidateHwnd(hWnd
);
2069 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
2071 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2073 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
2075 Wnd
->strName
.Length
)))
2077 Result
= (LRESULT
) (Wnd
->strName
.Length
/ sizeof(WCHAR
));
2088 PWSTR outbuf
= (PWSTR
)lParam
;
2090 Wnd
= ValidateHwnd(hWnd
);
2091 if (Wnd
!= NULL
&& wParam
!= 0)
2093 if (Wnd
->strName
.Buffer
!= NULL
)
2094 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2100 if (Wnd
->strName
.Length
!= 0)
2102 Result
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
2103 RtlCopyMemory(outbuf
,
2105 Result
* sizeof(WCHAR
));
2106 outbuf
[Result
] = L
'\0';
2117 DefSetText(hWnd
, (PCWSTR
)lParam
, FALSE
);
2119 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2121 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
2129 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
2134 case WM_IME_KEYDOWN
:
2136 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2142 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
2146 case WM_IME_STARTCOMPOSITION
:
2147 case WM_IME_COMPOSITION
:
2148 case WM_IME_ENDCOMPOSITION
:
2154 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2156 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
2160 case WM_IME_SETCONTEXT
:
2164 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2166 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
2171 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
2173 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2179 DefWindowProcA(HWND hWnd
,
2184 BOOL Hook
, msgOverride
= FALSE
;
2189 Hook
= BeginIfHookedUserApiHook();
2191 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2193 /* Bypass SEH and go direct. */
2194 if (!Hook
|| !msgOverride
)
2195 return RealDefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2199 Result
= guah
.DefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2201 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2212 DefWindowProcW(HWND hWnd
,
2217 BOOL Hook
, msgOverride
= FALSE
;
2222 Hook
= BeginIfHookedUserApiHook();
2224 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2226 /* Bypass SEH and go direct. */
2227 if (!Hook
|| !msgOverride
)
2228 return RealDefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2232 Result
= guah
.DefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2234 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)