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);
855 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
859 GetClientRect(hWnd
, &Rect
);
860 MapWindowPoints(hWnd
, (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
?
861 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
863 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
865 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
868 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
870 WPARAM wp
= SIZE_RESTORED
;
875 else if (IsIconic(hWnd
))
879 SendMessageW(hWnd
, WM_SIZE
, wp
,
880 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
886 /***********************************************************************
889 * Default colors for control painting.
892 DefWndControlColor(HDC hDC
, UINT ctlType
)
894 if (CTLCOLOR_SCROLLBAR
== ctlType
)
896 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
897 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
898 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
901 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
902 * we better use 0x55aa bitmap brush to make scrollbar's background
903 * look different from the window background.
905 if (bk
== GetSysColor(COLOR_WINDOW
))
907 static const WORD wPattern55AA
[] =
909 0x5555, 0xaaaa, 0x5555, 0xaaaa,
910 0x5555, 0xaaaa, 0x5555, 0xaaaa
912 static HBITMAP hPattern55AABitmap
= NULL
;
913 static HBRUSH hPattern55AABrush
= NULL
;
914 if (hPattern55AABrush
== NULL
)
916 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
917 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
919 return hPattern55AABrush
;
925 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
927 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
929 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
933 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
934 return GetSysColorBrush(COLOR_3DFACE
);
937 return GetSysColorBrush(COLOR_WINDOW
);
940 static void DefWndPrint( HWND hwnd
, HDC hdc
, ULONG uFlags
)
945 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
946 !IsWindowVisible(hwnd
) )
950 * Unimplemented flags.
952 if ( (uFlags
& PRF_CHILDREN
) ||
953 (uFlags
& PRF_OWNED
) ||
954 (uFlags
& PRF_NONCLIENT
) )
956 FIXME("WM_PRINT message with unsupported flags\n");
962 if ( uFlags
& PRF_ERASEBKGND
)
963 SendMessageW(hwnd
, WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
968 if ( uFlags
& PRF_CLIENT
)
969 SendMessageW(hwnd
, WM_PRINTCLIENT
, (WPARAM
)hdc
, uFlags
);
973 UserSendUiUpdateMsg(HWND hwnd
, LPARAM lParam
)
975 SendMessageW(hwnd
, WM_UPDATEUISTATE
, (WPARAM
)lParam
, 0);
981 DefWndScreenshot(HWND hWnd
)
993 hdc
= GetWindowDC(hWnd
);
994 GetWindowRect(hWnd
, &rect
);
995 w
= rect
.right
- rect
.left
;
996 h
= rect
.bottom
- rect
.top
;
998 hbitmap
= CreateCompatibleBitmap(hdc
, w
, h
);
999 hdc2
= CreateCompatibleDC(hdc
);
1000 SelectObject(hdc2
, hbitmap
);
1002 BitBlt(hdc2
, 0, 0, w
, h
,
1006 SetClipboardData(CF_BITMAP
, hbitmap
);
1008 ReleaseDC(hWnd
, hdc
);
1009 ReleaseDC(hWnd
, hdc2
);
1018 User32DefWindowProc(HWND hWnd
,
1028 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
1033 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
1036 case WM_POPUPSYSTEMMENU
:
1038 /* This is an undocumented message used by the windows taskbar to
1039 display the system menu of windows that belong to other processes. */
1040 HMENU menu
= GetSystemMenu(hWnd
, FALSE
);
1043 TrackPopupMenu(menu
, TPM_LEFTBUTTON
|TPM_RIGHTBUTTON
,
1044 LOWORD(lParam
), HIWORD(lParam
), 0, hWnd
, NULL
);
1050 return DefWndNCActivate(hWnd
, wParam
);
1056 Point
.x
= GET_X_LPARAM(lParam
);
1057 Point
.y
= GET_Y_LPARAM(lParam
);
1058 return (DefWndNCHitTest(hWnd
, Point
));
1061 case WM_LBUTTONDOWN
:
1062 case WM_RBUTTONDOWN
:
1063 case WM_MBUTTONDOWN
:
1064 iF10Key
= iMenuSysKey
= 0;
1067 case WM_NCLBUTTONDOWN
:
1069 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
1072 case WM_LBUTTONDBLCLK
:
1073 return (DefWndNCLButtonDblClk(hWnd
, HTCLIENT
, lParam
));
1075 case WM_NCLBUTTONDBLCLK
:
1077 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
1080 case WM_WINDOWPOSCHANGING
:
1082 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1085 case WM_WINDOWPOSCHANGED
:
1087 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
1090 case WM_NCRBUTTONDOWN
:
1092 /* in Windows, capture is taken when right-clicking on the caption bar */
1093 if (wParam
== HTCAPTION
)
1103 if (hWnd
== GetCapture())
1107 Pt
.x
= GET_X_LPARAM(lParam
);
1108 Pt
.y
= GET_Y_LPARAM(lParam
);
1109 ClientToScreen(hWnd
, &Pt
);
1110 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1113 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1117 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1122 case WM_NCRBUTTONUP
:
1124 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1125 * in Windows), but what _should_ we do? According to MSDN :
1126 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1127 * message to the window". When is it appropriate?
1131 case WM_CONTEXTMENU
:
1133 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1137 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1141 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1150 Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1152 Pt
.x
= GET_X_LPARAM(lParam
);
1153 Pt
.y
= GET_Y_LPARAM(lParam
);
1154 if (Style
& WS_CHILD
)
1156 ScreenToClient(GetParent(hWnd
), &Pt
);
1159 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1161 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1166 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1168 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongPtrW(hWnd
, GWL_STYLE
),
1169 GetClassLongPtrW(hWnd
, GCL_STYLE
), HitCode
);
1171 if(HitCode
== HTCAPTION
)
1172 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1174 Flags
= TPM_LEFTBUTTON
;
1176 TrackPopupMenu(SystemMenu
, Flags
,
1177 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1186 DefWndPrint(hWnd
, (HDC
)wParam
, lParam
);
1190 case WM_SYSCOLORCHANGE
:
1192 /* force to redraw non-client area */
1193 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1194 /* Use InvalidateRect to redraw client area, enable
1195 * erase to redraw all subcontrols otherwise send the
1196 * WM_SYSCOLORCHANGE to child windows/controls is required
1198 InvalidateRect(hWnd
,NULL
,TRUE
);
1206 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1211 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1212 (hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
)) != NULL
)
1216 GetClientRect(hWnd
, &ClientRect
);
1217 x
= (ClientRect
.right
- ClientRect
.left
-
1218 GetSystemMetrics(SM_CXICON
)) / 2;
1219 y
= (ClientRect
.bottom
- ClientRect
.top
-
1220 GetSystemMetrics(SM_CYICON
)) / 2;
1221 DrawIcon(hDC
, x
, y
, hIcon
);
1223 EndPaint(hWnd
, &Ps
);
1231 hRgn
= CreateRectRgn(0, 0, 0, 0);
1232 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1234 RedrawWindow(hWnd
, NULL
, hRgn
,
1235 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1244 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1245 if (wParam
) SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
| WS_VISIBLE
);
1248 RedrawWindow(hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
1249 Style
&= ~WS_VISIBLE
;
1250 SetWindowLongPtr(hWnd
, GWL_STYLE
, Style
);
1257 DestroyWindow(hWnd
);
1261 case WM_MOUSEACTIVATE
:
1263 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1268 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1273 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1281 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1286 /* Check if the window is minimized. */
1287 if (LOWORD(wParam
) != WA_INACTIVE
&&
1288 !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1297 if (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1301 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1306 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1314 case WM_ICONERASEBKGND
:
1317 HBRUSH hBrush
= (HBRUSH
)GetClassLongPtrW(hWnd
, GCL_HBRBACKGROUND
);
1323 if (GetClassLongPtrW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1325 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1326 GetClientRect(hWnd
, &Rect
);
1327 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1331 GetClipBox((HDC
)wParam
, &Rect
);
1333 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1337 case WM_CTLCOLORMSGBOX
:
1338 case WM_CTLCOLOREDIT
:
1339 case WM_CTLCOLORLISTBOX
:
1340 case WM_CTLCOLORBTN
:
1341 case WM_CTLCOLORDLG
:
1342 case WM_CTLCOLORSTATIC
:
1343 case WM_CTLCOLORSCROLLBAR
:
1344 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1347 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
1351 LONG_PTR Style
= GetWindowLongPtrW(hWnd
, GWL_STYLE
);
1353 if (Style
& WS_CHILD
)
1355 /* with the exception of the border around a resizable wnd,
1356 * give the parent first chance to set the cursor */
1357 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1359 HWND parent
= GetParent( hWnd
);
1362 if (parent
!= GetDesktopWindow() &&
1363 SendMessageW( parent
, WM_SETCURSOR
, wParam
, lParam
))
1368 if (parent
!= GetDesktopWindow() &&
1369 SendMessageA( parent
, WM_SETCURSOR
, wParam
, lParam
))
1374 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1378 return (DefWndHandleSysCommand(hWnd
, wParam
, lParam
));
1381 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
1384 /* FIXME: This is also incomplete. */
1387 if (HIWORD(lParam
) & KEYDATA_ALT
)
1389 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1390 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
1391 if ( (wParam
== VK_MENU
|| wParam
== VK_LMENU
1392 || wParam
== VK_RMENU
) && !iMenuSysKey
)
1399 if (wParam
== VK_F4
) /* Try to close the window */
1401 if (!(GetClassLongPtrW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1404 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1406 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1409 else if (wParam
== VK_SNAPSHOT
)
1412 while (GetParent(hwnd
) != NULL
)
1414 hwnd
= GetParent(hwnd
);
1416 DefWndScreenshot(hwnd
);
1419 else if( wParam
== VK_F10
)
1421 if (GetKeyState(VK_SHIFT
) & 0x8000)
1422 SendMessageW( hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, MAKELPARAM(-1, -1) );
1425 else if( wParam
== VK_ESCAPE
&& (GetKeyState(VK_SHIFT
) & 0x8000))
1426 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, ' ' );
1433 /* Press and release F10 or ALT */
1434 if (((wParam
== VK_MENU
|| wParam
== VK_LMENU
|| wParam
== VK_RMENU
)
1435 && iMenuSysKey
) || ((wParam
== VK_F10
) && iF10Key
))
1436 SendMessageW( GetAncestor( hWnd
, GA_ROOT
), WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1437 iMenuSysKey
= iF10Key
= 0;
1444 if (wParam
== '\r' && IsIconic(hWnd
))
1446 PostMessageW( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0L );
1449 if ((HIWORD(lParam
) & KEYDATA_ALT
) && wParam
)
1451 if (wParam
== '\t' || wParam
== '\x1b') break;
1452 if (wParam
== ' ' && (GetWindowLongPtrW( hWnd
, GWL_STYLE
) & WS_CHILD
))
1453 SendMessageW( GetParent(hWnd
), Msg
, wParam
, lParam
);
1455 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, wParam
);
1457 else /* check for Ctrl-Esc */
1458 if (wParam
!= '\x1b') MessageBeep(0);
1464 if (lParam
) // Call when it is necessary.
1465 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, 0, FNID_DEFWINDOWPROC
, FALSE
);
1469 case WM_CLIENTSHUTDOWN
:
1472 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&lResult
, FNID_DEFWINDOWPROC
, FALSE
);
1479 /* FIXME: Check for a desktop. */
1480 //if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
1481 MENU_EndMenu( hWnd
);
1482 if (GetCapture() == hWnd
)
1496 case WM_QUERYDROPOBJECT
:
1498 if (GetWindowLongPtrW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1505 case WM_QUERYDRAGICON
:
1510 hIcon
= (HICON
)GetClassLongPtrW(hWnd
, GCL_HICON
);
1513 return ((LRESULT
)hIcon
);
1515 for (Len
= 1; Len
< 64; Len
++)
1517 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1519 return((LRESULT
)hIcon
);
1522 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1525 case WM_ISACTIVEICON
:
1529 pWnd
= ValidateHwnd(hWnd
);
1530 if (!pWnd
) return 0;
1531 isai
= (pWnd
->state
& WNDS_ACTIVEFRAME
) != 0;
1535 case WM_NOTIFYFORMAT
:
1537 if (lParam
== NF_QUERY
)
1538 return IsWindowUnicode(hWnd
) ? NFR_UNICODE
: NFR_ANSI
;
1544 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1545 HICON hOldIcon
= (HICON
)GetClassLongPtrW(hWnd
, Index
);
1546 SetClassLongPtrW(hWnd
, Index
, lParam
);
1547 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1548 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1549 SWP_NOACTIVATE
| SWP_NOZORDER
);
1550 return ((LRESULT
)hOldIcon
);
1555 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1556 return (GetClassLongPtrW(hWnd
, Index
));
1563 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1567 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1574 THRDCARETINFO CaretInfo
;
1577 case 0xffff: /* Caret timer */
1578 /* switch showing byte in win32k and get information about the caret */
1579 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1581 DrawCaret(hWnd
, &CaretInfo
);
1589 case WM_QUERYENDSESSION
:
1594 case WM_INPUTLANGCHANGEREQUEST
:
1598 if(wParam
& INPUTLANGCHANGE_BACKWARD
1599 && wParam
& INPUTLANGCHANGE_FORWARD
)
1604 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1606 if(wParam
& INPUTLANGCHANGE_BACKWARD
) NewHkl
= (HKL
) HKL_PREV
;
1607 else if(wParam
& INPUTLANGCHANGE_FORWARD
) NewHkl
= (HKL
) HKL_NEXT
;
1608 else NewHkl
= (HKL
) lParam
;
1610 NtUserActivateKeyboardLayout(NewHkl
, 0);
1615 case WM_INPUTLANGCHANGE
:
1618 HWND
*win_array
= WIN_ListChildren( hWnd
);
1622 while (win_array
[count
])
1623 SendMessageW( win_array
[count
++], WM_INPUTLANGCHANGE
, wParam
, lParam
);
1624 HeapFree(GetProcessHeap(),0,win_array
);
1628 case WM_QUERYUISTATE
:
1631 PWND Wnd
= ValidateHwnd(hWnd
);
1635 Ret
|= UISF_HIDEFOCUS
;
1637 Ret
|= UISF_HIDEACCEL
;
1642 case WM_CHANGEUISTATE
:
1644 BOOL AlwaysShowCues
= FALSE
;
1645 WORD Action
= LOWORD(wParam
);
1646 WORD Flags
= HIWORD(wParam
);
1649 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1653 Wnd
= ValidateHwnd(hWnd
);
1654 if (!Wnd
|| lParam
!= 0)
1657 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1660 if (Flags
& UISF_ACTIVE
)
1662 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1665 if (Action
== UIS_INITIALIZE
)
1667 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1671 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1672 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1674 /* We need to update wParam in case we need to send out messages */
1675 wParam
= MAKEWPARAM(Action
, Flags
);
1681 /* See if we actually need to change something */
1682 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1684 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1687 /* Don't need to do anything... */
1691 /* See if we actually need to change something */
1692 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1694 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1697 /* Don't need to do anything... */
1701 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1705 if ((Wnd
->style
& WS_CHILD
) && Wnd
->spwndParent
!= NULL
)
1707 /* We're a child window and we need to pass this message down until
1708 we reach the root */
1709 hWnd
= UserHMGetHandle((PWND
)DesktopPtrToUser(Wnd
->spwndParent
));
1713 /* We're a top level window, we need to change the UI state */
1714 Msg
= WM_UPDATEUISTATE
;
1718 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1720 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1723 case WM_UPDATEUISTATE
:
1726 BOOL AlwaysShowCues
= FALSE
;
1727 WORD Action
= LOWORD(wParam
);
1728 WORD Flags
= HIWORD(wParam
);
1731 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1735 Wnd
= ValidateHwnd(hWnd
);
1736 if (!Wnd
|| lParam
!= 0)
1739 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1742 if (Flags
& UISF_ACTIVE
)
1744 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1747 if (Action
== UIS_INITIALIZE
)
1749 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1753 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1754 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1756 /* We need to update wParam for broadcasting the update */
1757 wParam
= MAKEWPARAM(Action
, Flags
);
1763 /* See if we actually need to change something */
1764 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1766 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1769 /* Don't need to do anything... */
1774 /* See if we actually need to change something */
1775 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1777 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1780 /* Don't need to do anything... */
1785 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1789 /* Pack the information and call win32k */
1792 if (!NtUserCallTwoParam((DWORD_PTR
)hWnd
, (DWORD_PTR
)Flags
| ((DWORD_PTR
)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE
))
1796 /* Always broadcast the update to all children */
1797 EnumChildWindows(hWnd
,
1798 UserSendUiUpdateMsg
,
1810 * helpers for calling IMM32 (from Wine 10/22/2008)
1812 * WM_IME_* messages are generated only by IMM32,
1813 * so I assume imm32 is already LoadLibrary-ed.
1816 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1818 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1819 HWND (WINAPI
*pFunc
)(HWND
);
1824 ERR("cannot get IMM32 handle\n");
1828 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1830 hwndRet
= (*pFunc
)(hwnd
);
1837 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1839 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1840 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1845 ERR("cannot get IMM32 handle\n");
1849 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1851 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1858 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1860 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1861 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1866 ERR("cannot get IMM32 handle\n");
1870 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1872 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1879 RealDefWindowProcA(HWND hWnd
,
1887 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1894 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1895 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1896 * may have child window IDs instead of window name */
1897 if (HIWORD(cs
->lpszName
))
1899 DefSetText(hWnd
, (PCWSTR
)cs
->lpszName
, TRUE
);
1906 case WM_GETTEXTLENGTH
:
1911 Wnd
= ValidateHwnd(hWnd
);
1912 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
1914 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1916 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1918 Wnd
->strName
.Length
)))
1920 Result
= (LRESULT
) len
;
1931 PSTR outbuf
= (PSTR
)lParam
;
1934 Wnd
= ValidateHwnd(hWnd
);
1935 if (Wnd
!= NULL
&& wParam
!= 0)
1937 if (Wnd
->strName
.Buffer
!= NULL
)
1938 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1944 if (Wnd
->strName
.Length
!= 0)
1946 copy
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1947 Result
= WideCharToMultiByte(CP_ACP
,
1955 outbuf
[Result
] = '\0';
1966 DefSetText(hWnd
, (PCWSTR
)lParam
, TRUE
);
1968 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1970 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1977 case WM_IME_KEYDOWN
:
1979 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
1985 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
1992 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
1993 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
1997 case WM_IME_STARTCOMPOSITION
:
1998 case WM_IME_COMPOSITION
:
1999 case WM_IME_ENDCOMPOSITION
:
2005 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2007 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
2011 case WM_IME_SETCONTEXT
:
2015 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2017 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
2023 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2026 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2032 RealDefWindowProcW(HWND hWnd
,
2040 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
2047 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
2048 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2049 * may have child window IDs instead of window name */
2050 if (HIWORD(cs
->lpszName
))
2052 DefSetText(hWnd
, cs
->lpszName
, FALSE
);
2059 case WM_GETTEXTLENGTH
:
2064 Wnd
= ValidateHwnd(hWnd
);
2065 if (Wnd
!= NULL
&& Wnd
->strName
.Length
!= 0)
2067 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2069 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
2071 Wnd
->strName
.Length
)))
2073 Result
= (LRESULT
) (Wnd
->strName
.Length
/ sizeof(WCHAR
));
2084 PWSTR outbuf
= (PWSTR
)lParam
;
2086 Wnd
= ValidateHwnd(hWnd
);
2087 if (Wnd
!= NULL
&& wParam
!= 0)
2089 if (Wnd
->strName
.Buffer
!= NULL
)
2090 buf
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
2096 if (Wnd
->strName
.Length
!= 0)
2098 Result
= min(Wnd
->strName
.Length
/ sizeof(WCHAR
), wParam
- 1);
2099 RtlCopyMemory(outbuf
,
2101 Result
* sizeof(WCHAR
));
2102 outbuf
[Result
] = L
'\0';
2113 DefSetText(hWnd
, (PCWSTR
)lParam
, FALSE
);
2115 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2117 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
2125 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
2130 case WM_IME_KEYDOWN
:
2132 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2138 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
2142 case WM_IME_STARTCOMPOSITION
:
2143 case WM_IME_COMPOSITION
:
2144 case WM_IME_ENDCOMPOSITION
:
2150 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2152 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
2156 case WM_IME_SETCONTEXT
:
2160 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2162 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
2167 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
2169 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2175 DefWindowProcA(HWND hWnd
,
2180 BOOL Hook
, msgOverride
= FALSE
;
2185 Hook
= BeginIfHookedUserApiHook();
2187 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2189 /* Bypass SEH and go direct. */
2190 if (!Hook
|| !msgOverride
)
2191 return RealDefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2195 Result
= guah
.DefWindowProcA(hWnd
, Msg
, wParam
, lParam
);
2197 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2208 DefWindowProcW(HWND hWnd
,
2213 BOOL Hook
, msgOverride
= FALSE
;
2218 Hook
= BeginIfHookedUserApiHook();
2220 msgOverride
= IsMsgOverride(Msg
, &guah
.DefWndProcArray
);
2222 /* Bypass SEH and go direct. */
2223 if (!Hook
|| !msgOverride
)
2224 return RealDefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2228 Result
= guah
.DefWindowProcW(hWnd
, Msg
, wParam
, lParam
);
2230 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)