3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/windows/window.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
);
34 /* GLOBALS *******************************************************************/
36 /* Bits in the dwKeyData */
37 #define KEYDATA_ALT 0x2000
38 #define KEYDATA_PREVSTATE 0x4000
40 static short iF10Key
= 0;
41 static short iMenuSysKey
= 0;
43 /* FUNCTIONS *****************************************************************/
46 InitStockObjects(void)
48 /* FIXME - Instead of copying the stuff to usermode we should map the tables to
49 userland. The current implementation has one big flaw: the system color
50 table doesn't get updated when another process changes them. That's why
51 we should rather map the table into usermode. But it only affects the
52 SysColors table - the pens, brushes and stock objects are not affected
53 as their handles never change. But it'd be faster to map them, too. */
62 GetSysColor(int nIndex
)
64 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
66 return g_psi
->SysColors
[nIndex
];
69 SetLastError(ERROR_INVALID_PARAMETER
);
77 GetSysColorPen(int nIndex
)
79 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
81 return g_psi
->SysColorPens
[nIndex
];
84 SetLastError(ERROR_INVALID_PARAMETER
);
92 GetSysColorBrush(int nIndex
)
94 if(nIndex
>= 0 && nIndex
< NUM_SYSCOLORS
)
96 return g_psi
->SysColorBrushes
[nIndex
];
99 SetLastError(ERROR_INVALID_PARAMETER
);
110 CONST INT
*lpaElements
,
111 CONST COLORREF
*lpaRgbValues
)
113 return NtUserSetSysColors(cElements
, lpaElements
, lpaRgbValues
, 0);
117 UserGetInsideRectNC(PWINDOW Wnd
, RECT
*rect
)
123 ExStyle
= Wnd
->ExStyle
;
125 rect
->top
= rect
->left
= 0;
126 rect
->right
= Wnd
->WindowRect
.right
- Wnd
->WindowRect
.left
;
127 rect
->bottom
= Wnd
->WindowRect
.bottom
- Wnd
->WindowRect
.top
;
129 if (Style
& WS_ICONIC
)
134 /* Remove frame from rectangle */
135 if (UserHasThickFrameStyle(Style
, ExStyle
))
137 InflateRect(rect
, -GetSystemMetrics(SM_CXFRAME
),
138 -GetSystemMetrics(SM_CYFRAME
));
142 if (UserHasDlgFrameStyle(Style
, ExStyle
))
144 InflateRect(rect
, -GetSystemMetrics(SM_CXDLGFRAME
),
145 -GetSystemMetrics(SM_CYDLGFRAME
));
146 /* FIXME: this isn't in NC_AdjustRect? why not? */
147 if (ExStyle
& WS_EX_DLGMODALFRAME
)
148 InflateRect( rect
, -1, 0 );
152 if (UserHasThinFrameStyle(Style
, ExStyle
))
154 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
155 -GetSystemMetrics(SM_CYBORDER
));
163 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
165 LONG Style
= GetWindowLong(hWnd
, GWL_STYLE
);
166 /* Content can be redrawn after a change. */
169 if (!(Style
& WS_VISIBLE
)) /* Not Visible */
171 SetWindowLong(hWnd
, GWL_STYLE
, WS_VISIBLE
);
174 else /* Content cannot be redrawn after a change. */
176 if (Style
& WS_VISIBLE
) /* Visible */
178 RedrawWindow( hWnd
, NULL
, 0, RDW_ALLCHILDREN
| RDW_VALIDATE
);
179 Style
&= ~WS_VISIBLE
;
180 SetWindowLong(hWnd
, GWL_STYLE
, Style
); /* clear bits */
188 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
, ULONG Style
)
190 /* Not for child windows. */
191 if (hWnd
!= (HWND
)wParam
)
196 switch((INT_PTR
) LOWORD(lParam
))
200 WORD Msg
= HIWORD(lParam
);
201 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
202 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
211 HICON hCursor
= (HICON
)GetClassLongW(hWnd
, GCL_HCURSOR
);
223 if (Style
& WS_MAXIMIZE
)
227 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
233 if (Style
& WS_MAXIMIZE
)
237 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
243 if (Style
& WS_MAXIMIZE
)
247 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
253 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
)
257 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
260 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
264 DefWndStartSizeMove(HWND hWnd
, PWINDOW Wnd
, WPARAM wParam
, POINT
*capturePoint
)
270 ULONG Style
= Wnd
->Style
;
272 rectWindow
= Wnd
->WindowRect
;
274 if ((wParam
& 0xfff0) == SC_MOVE
)
276 /* Move pointer at the center of the caption */
278 UserGetInsideRectNC(Wnd
, &rect
);
279 if (Style
& WS_SYSMENU
)
280 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
281 if (Style
& WS_MINIMIZEBOX
)
282 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
283 if (Style
& WS_MAXIMIZEBOX
)
284 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
285 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
286 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
295 if (GetMessageW(&msg
, NULL
, 0, 0) <= 0)
300 hittest
= DefWndNCHitTest(hWnd
, msg
.pt
);
301 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
313 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
314 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
318 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
319 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
323 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
324 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
328 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
329 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
332 case VK_ESCAPE
: return 0;
338 SetCursorPos( pt
.x
, pt
.y
);
339 DefWndHandleSetCursor(hWnd
, (WPARAM
)hWnd
, MAKELONG(hittest
, WM_MOUSEMOVE
), Style
);
343 #define ON_LEFT_BORDER(hit) \
344 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
345 #define ON_RIGHT_BORDER(hit) \
346 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
347 #define ON_TOP_BORDER(hit) \
348 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
349 #define ON_BOTTOM_BORDER(hit) \
350 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
353 UserDrawWindowFrame(HDC hdc
, const RECT
*rect
,
354 ULONG width
, ULONG height
)
356 static HBRUSH hDraggingRectBrush
= NULL
;
359 if(!hDraggingRectBrush
)
361 static HBITMAP hDraggingPattern
= NULL
;
362 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
364 hDraggingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
365 hDraggingRectBrush
= CreatePatternBrush(hDraggingPattern
);
368 hbrush
= SelectObject( hdc
, hDraggingRectBrush
);
369 PatBlt( hdc
, rect
->left
, rect
->top
,
370 rect
->right
- rect
->left
- width
, height
, PATINVERT
);
371 PatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
,
372 rect
->bottom
- rect
->top
- height
, PATINVERT
);
373 PatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1,
374 rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
375 PatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
,
376 rect
->bottom
- rect
->top
- height
, PATINVERT
);
377 SelectObject( hdc
, hbrush
);
381 UserDrawMovingFrame(HDC hdc
, RECT
*rect
, BOOL thickframe
)
385 UserDrawWindowFrame(hdc
, rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
));
389 UserDrawWindowFrame(hdc
, rect
, 1, 1);
394 DefWndDoSizeMove(HWND hwnd
, WORD wParam
)
398 RECT sizingRect
, mouseRect
, origRect
, clipRect
, unmodRect
;
400 LONG hittest
= (LONG
)(wParam
& 0x0f);
401 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
402 POINT minTrack
, maxTrack
;
403 POINT capturePoint
, pt
;
404 ULONG Style
, ExStyle
;
408 DWORD dwPoint
= GetMessagePos();
409 BOOL DragFullWindows
= FALSE
;
410 HWND hWndParent
= NULL
;
413 Wnd
= ValidateHwnd(hwnd
);
418 ExStyle
= Wnd
->ExStyle
;
419 iconic
= (Style
& WS_MINIMIZE
) != 0;
421 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
423 pt
.x
= GET_X_LPARAM(dwPoint
);
424 pt
.y
= GET_Y_LPARAM(dwPoint
);
427 if ((Style
& WS_MAXIMIZE
) || !IsWindowVisible(hwnd
))
432 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !(Style
& WS_MINIMIZE
);
433 if ((wParam
& 0xfff0) == SC_MOVE
)
437 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
450 if (hittest
&& ((wParam
& 0xfff0) != SC_MOUSEMENU
))
452 hittest
+= (HTLEFT
- WMSZ_LEFT
);
457 hittest
= DefWndStartSizeMove(hwnd
, Wnd
, wParam
, &capturePoint
);
466 /* Get min/max info */
468 WinPosGetMinMaxInfo(hwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
469 sizingRect
= Wnd
->WindowRect
;
470 if (Style
& WS_CHILD
)
472 hWndParent
= GetParent(hwnd
);
473 MapWindowPoints( 0, hWndParent
, (LPPOINT
)&sizingRect
, 2 );
474 unmodRect
= sizingRect
;
475 GetClientRect(hWndParent
, &mouseRect
);
476 clipRect
= mouseRect
;
477 MapWindowPoints(hWndParent
, HWND_DESKTOP
, (LPPOINT
)&clipRect
, 2);
481 if(!(ExStyle
& WS_EX_TOPMOST
))
483 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &clipRect
, 0);
484 mouseRect
= clipRect
;
488 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
489 clipRect
= mouseRect
;
491 unmodRect
= sizingRect
;
493 ClipCursor(&clipRect
);
495 origRect
= sizingRect
;
496 if (ON_LEFT_BORDER(hittest
))
498 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
499 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
501 else if (ON_RIGHT_BORDER(hittest
))
503 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
504 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
506 if (ON_TOP_BORDER(hittest
))
508 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
509 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
511 else if (ON_BOTTOM_BORDER(hittest
))
513 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
514 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
516 if (Style
& WS_CHILD
)
518 MapWindowPoints( hWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
521 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
522 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, hwnd
);
523 if (GetCapture() != hwnd
) SetCapture( hwnd
);
525 if (Style
& WS_CHILD
)
527 /* Retrieve a default cache DC (without using the window style) */
528 hdc
= GetDCEx(hWndParent
, 0, DCX_CACHE
);
534 DesktopRgn
= CreateRectRgnIndirect(&clipRect
);
537 SelectObject(hdc
, DesktopRgn
);
539 if( iconic
) /* create a cursor for dragging */
541 HICON hIcon
= (HICON
)GetClassLongW(hwnd
, GCL_HICON
);
542 if(!hIcon
) hIcon
= (HICON
)SendMessageW( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
543 if( hIcon
) hDragCursor
= CursorIconToCursor( hIcon
, TRUE
);
544 if( !hDragCursor
) iconic
= FALSE
;
547 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
548 if( !iconic
&& !DragFullWindows
)
550 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
557 if (GetMessageW(&msg
, 0, 0, 0) <= 0)
560 /* Exit on button-up, Return, or Esc */
561 if ((msg
.message
== WM_LBUTTONUP
) ||
562 ((msg
.message
== WM_KEYDOWN
) &&
563 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
565 if (msg
.message
== WM_PAINT
)
567 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
568 UpdateWindow( msg
.hwnd
);
569 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
573 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
574 continue; /* We are not interested in other messages */
578 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
580 case VK_UP
: pt
.y
-= 8; break;
581 case VK_DOWN
: pt
.y
+= 8; break;
582 case VK_LEFT
: pt
.x
-= 8; break;
583 case VK_RIGHT
: pt
.x
+= 8; break;
586 pt
.x
= max( pt
.x
, mouseRect
.left
);
587 pt
.x
= min( pt
.x
, mouseRect
.right
);
588 pt
.y
= max( pt
.y
, mouseRect
.top
);
589 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
591 dx
= pt
.x
- capturePoint
.x
;
592 dy
= pt
.y
- capturePoint
.y
;
600 if( iconic
) /* ok, no system popup tracking */
602 hOldCursor
= SetCursor(hDragCursor
);
607 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
610 RECT newRect
= unmodRect
;
611 WPARAM wpSizingHit
= 0;
613 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
614 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
615 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
616 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
617 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
618 if(!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
621 /* determine the hit location */
622 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
623 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
625 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
630 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
632 /* To avoid any deadlocks, all the locks on the windows
633 structures must be suspended before the SetWindowPos */
634 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
635 newRect
.right
- newRect
.left
,
636 newRect
.bottom
- newRect
.top
,
637 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
640 sizingRect
= newRect
;
649 if( moved
) /* restore cursors, show icon title later on */
652 SetCursor( hOldCursor
);
654 DestroyCursor( hDragCursor
);
656 else if(!DragFullWindows
)
657 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
659 if (Style
& WS_CHILD
)
660 ReleaseDC( hWndParent
, hdc
);
666 DeleteObject(DesktopRgn
);
670 if (ISITHOOKED(WH_CBT
))
672 if (NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, (LPARAM
)&sizingRect
, 0, FNID_DEFWINDOWPROC
, FALSE
))
676 (void)NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE
, NULL
);
677 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
678 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic(hwnd
), 0L);
680 /* window moved or resized */
683 /* if the moving/resizing isn't canceled call SetWindowPos
684 * with the new position or the new size of the window
686 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
688 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
690 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
691 sizingRect
.right
- sizingRect
.left
,
692 sizingRect
.bottom
- sizingRect
.top
,
693 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
695 else { /* restore previous size/position */
697 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
698 origRect
.right
- origRect
.left
,
699 origRect
.bottom
- origRect
.top
,
700 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
705 if( Style
& WS_MINIMIZE
)
707 /* Single click brings up the system menu when iconized */
711 if( Style
& WS_SYSMENU
)
712 SendMessageA( hwnd
, WM_SYSCOMMAND
,
713 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
719 /***********************************************************************
720 * DefWndTrackScrollBar
722 * Track a mouse button press on the horizontal or vertical scroll-bar.
725 DefWndTrackScrollBar(HWND Wnd
, WPARAM wParam
, POINT Pt
)
729 if (SC_HSCROLL
== (wParam
& 0xfff0))
731 if (HTHSCROLL
!= (wParam
& 0x0f))
737 else /* SC_VSCROLL */
739 if (HTVSCROLL
!= (wParam
& 0x0f))
745 ScrollTrackScrollBar(Wnd
, ScrollBar
, Pt
);
750 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
756 if (ISITHOOKED(WH_CBT
))
758 if (NtUserMessageCall( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
, 0, FNID_DEFWINDOWPROC
, FALSE
))
762 switch (wParam
& 0xfff0)
766 DefWndDoSizeMove(hWnd
, wParam
);
769 wp
.length
= sizeof(WINDOWPLACEMENT
);
770 if(GetWindowPlacement(hWnd
, &wp
))
772 wp
.showCmd
= SW_MINIMIZE
;
773 SetWindowPlacement(hWnd
, &wp
);
777 wp
.length
= sizeof(WINDOWPLACEMENT
);
778 if(GetWindowPlacement(hWnd
, &wp
))
780 wp
.showCmd
= SW_MAXIMIZE
;
781 SetWindowPlacement(hWnd
, &wp
);
785 wp
.length
= sizeof(WINDOWPLACEMENT
);
786 if(GetWindowPlacement(hWnd
, &wp
))
788 wp
.showCmd
= SW_RESTORE
;
789 SetWindowPlacement(hWnd
, &wp
);
793 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
797 Pt
.x
= (short)LOWORD(lParam
);
798 Pt
.y
= (short)HIWORD(lParam
);
799 MenuTrackMouseMenuBar(hWnd
, wParam
& 0x000f, Pt
);
803 MenuTrackKbdMenuBar(hWnd
, wParam
, (WCHAR
)lParam
);
808 Pt
.x
= (short)LOWORD(lParam
);
809 Pt
.y
= (short)HIWORD(lParam
);
810 DefWndTrackScrollBar(hWnd
, wParam
, Pt
);
815 /* FIXME: Implement */
824 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
826 POINT maxTrack
, minTrack
;
827 LONG style
= GetWindowLongA(hWnd
, GWL_STYLE
);
829 if (Pos
->flags
& SWP_NOSIZE
) return 0;
830 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
832 WinPosGetMinMaxInfo(hWnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
833 Pos
->cx
= min(Pos
->cx
, maxTrack
.x
);
834 Pos
->cy
= min(Pos
->cy
, maxTrack
.y
);
835 if (!(style
& WS_MINIMIZE
))
837 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
838 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
843 Pos
->cx
= max(Pos
->cx
, 0);
844 Pos
->cy
= max(Pos
->cy
, 0);
849 /* Undocumented flags. */
850 #define SWP_NOCLIENTMOVE 0x0800
851 #define SWP_NOCLIENTSIZE 0x1000
854 DefWndHandleWindowPosChanged(HWND hWnd
, WINDOWPOS
* Pos
)
858 GetClientRect(hWnd
, &Rect
);
859 MapWindowPoints(hWnd
, (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
?
860 GetParent(hWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
862 if (! (Pos
->flags
& SWP_NOCLIENTMOVE
))
864 SendMessageW(hWnd
, WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
867 if (! (Pos
->flags
& SWP_NOCLIENTSIZE
))
869 WPARAM wp
= SIZE_RESTORED
;
874 else if (IsIconic(hWnd
))
878 SendMessageW(hWnd
, WM_SIZE
, wp
,
879 MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
885 /***********************************************************************
888 * Default colors for control painting.
891 DefWndControlColor(HDC hDC
, UINT ctlType
)
893 if (CTLCOLOR_SCROLLBAR
== ctlType
)
895 HBRUSH hb
= GetSysColorBrush(COLOR_SCROLLBAR
);
896 COLORREF bk
= GetSysColor(COLOR_3DHILIGHT
);
897 SetTextColor(hDC
, GetSysColor(COLOR_3DFACE
));
900 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
901 * we better use 0x55aa bitmap brush to make scrollbar's background
902 * look different from the window background.
904 if (bk
== GetSysColor(COLOR_WINDOW
))
906 static const WORD wPattern55AA
[] =
908 0x5555, 0xaaaa, 0x5555, 0xaaaa,
909 0x5555, 0xaaaa, 0x5555, 0xaaaa
911 static HBITMAP hPattern55AABitmap
= NULL
;
912 static HBRUSH hPattern55AABrush
= NULL
;
913 if (hPattern55AABrush
== NULL
)
915 hPattern55AABitmap
= CreateBitmap(8, 8, 1, 1, wPattern55AA
);
916 hPattern55AABrush
= CreatePatternBrush(hPattern55AABitmap
);
918 return hPattern55AABrush
;
924 SetTextColor(hDC
, GetSysColor(COLOR_WINDOWTEXT
));
926 if ((CTLCOLOR_EDIT
== ctlType
) || (CTLCOLOR_LISTBOX
== ctlType
))
928 SetBkColor(hDC
, GetSysColor(COLOR_WINDOW
));
932 SetBkColor(hDC
, GetSysColor(COLOR_3DFACE
));
933 return GetSysColorBrush(COLOR_3DFACE
);
936 return GetSysColorBrush(COLOR_WINDOW
);
939 static void DefWndPrint( HWND hwnd
, HDC hdc
, ULONG uFlags
)
944 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
945 !IsWindowVisible(hwnd
) )
949 * Unimplemented flags.
951 if ( (uFlags
& PRF_CHILDREN
) ||
952 (uFlags
& PRF_OWNED
) ||
953 (uFlags
& PRF_NONCLIENT
) )
955 FIXME("WM_PRINT message with unsupported flags\n");
961 if ( uFlags
& PRF_ERASEBKGND
)
962 SendMessageW(hwnd
, WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
967 if ( uFlags
& PRF_CLIENT
)
968 SendMessageW(hwnd
, WM_PRINTCLIENT
, (WPARAM
)hdc
, PRF_CLIENT
);
972 UserSendUiUpdateMsg(HWND hwnd
, LPARAM lParam
)
974 SendMessageW(hwnd
, WM_UPDATEUISTATE
, (WPARAM
)lParam
, 0);
980 DefWndScreenshot(HWND hWnd
)
992 hdc
= GetWindowDC(hWnd
);
993 GetWindowRect(hWnd
, &rect
);
994 w
= rect
.right
- rect
.left
;
995 h
= rect
.bottom
- rect
.top
;
997 hbitmap
= CreateCompatibleBitmap(hdc
, w
, h
);
998 hdc2
= CreateCompatibleDC(hdc
);
999 SelectObject(hdc2
, hbitmap
);
1001 BitBlt(hdc2
, 0, 0, w
, h
,
1005 SetClipboardData(CF_BITMAP
, hbitmap
);
1007 ReleaseDC(hWnd
, hdc
);
1008 ReleaseDC(hWnd
, hdc2
);
1017 User32DefWindowProc(HWND hWnd
,
1027 return DefWndNCPaint(hWnd
, (HRGN
)wParam
, -1);
1032 return DefWndNCCalcSize(hWnd
, (BOOL
)wParam
, (RECT
*)lParam
);
1035 case WM_POPUPSYSTEMMENU
:
1037 /* This is an undocumented message used by the windows taskbar to
1038 display the system menu of windows that belong to other processes. */
1039 HMENU menu
= GetSystemMenu(hWnd
, FALSE
);
1042 TrackPopupMenu(menu
, TPM_LEFTBUTTON
|TPM_RIGHTBUTTON
,
1043 LOWORD(lParam
), HIWORD(lParam
), 0, hWnd
, NULL
);
1049 return DefWndNCActivate(hWnd
, wParam
);
1055 Point
.x
= GET_X_LPARAM(lParam
);
1056 Point
.y
= GET_Y_LPARAM(lParam
);
1057 return (DefWndNCHitTest(hWnd
, Point
));
1060 case WM_LBUTTONDOWN
:
1061 case WM_RBUTTONDOWN
:
1062 case WM_MBUTTONDOWN
:
1063 iF10Key
= iMenuSysKey
= 0;
1066 case WM_NCLBUTTONDOWN
:
1068 return (DefWndNCLButtonDown(hWnd
, wParam
, lParam
));
1071 case WM_LBUTTONDBLCLK
:
1072 return (DefWndNCLButtonDblClk(hWnd
, HTCLIENT
, lParam
));
1074 case WM_NCLBUTTONDBLCLK
:
1076 return (DefWndNCLButtonDblClk(hWnd
, wParam
, lParam
));
1079 case WM_WINDOWPOSCHANGING
:
1081 return (DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1084 case WM_WINDOWPOSCHANGED
:
1086 return (DefWndHandleWindowPosChanged(hWnd
, (WINDOWPOS
*)lParam
));
1089 case WM_NCRBUTTONDOWN
:
1091 /* in Windows, capture is taken when right-clicking on the caption bar */
1092 if (wParam
== HTCAPTION
)
1102 if (hWnd
== GetCapture())
1106 Pt
.x
= GET_X_LPARAM(lParam
);
1107 Pt
.y
= GET_Y_LPARAM(lParam
);
1108 ClientToScreen(hWnd
, &Pt
);
1109 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1112 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1116 SendMessageA(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1121 case WM_NCRBUTTONUP
:
1123 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1124 * in Windows), but what _should_ we do? According to MSDN :
1125 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1126 * message to the window". When is it appropriate?
1130 case WM_CONTEXTMENU
:
1132 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1136 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1140 SendMessageA(GetParent(hWnd
), WM_CONTEXTMENU
, wParam
, lParam
);
1149 Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1151 Pt
.x
= GET_X_LPARAM(lParam
);
1152 Pt
.y
= GET_Y_LPARAM(lParam
);
1153 if (Style
& WS_CHILD
)
1155 ScreenToClient(GetParent(hWnd
), &Pt
);
1158 HitCode
= DefWndNCHitTest(hWnd
, Pt
);
1160 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1165 if((SystemMenu
= GetSystemMenu(hWnd
, FALSE
)))
1167 MenuInitSysMenuPopup(SystemMenu
, GetWindowLongW(hWnd
, GWL_STYLE
),
1168 GetClassLongW(hWnd
, GCL_STYLE
), HitCode
);
1170 if(HitCode
== HTCAPTION
)
1171 Flags
= TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
;
1173 Flags
= TPM_LEFTBUTTON
;
1175 TrackPopupMenu(SystemMenu
, Flags
,
1176 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1185 DefWndPrint(hWnd
, (HDC
)wParam
, lParam
);
1193 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1198 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1199 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1203 GetClientRect(hWnd
, &ClientRect
);
1204 x
= (ClientRect
.right
- ClientRect
.left
-
1205 GetSystemMetrics(SM_CXICON
)) / 2;
1206 y
= (ClientRect
.bottom
- ClientRect
.top
-
1207 GetSystemMetrics(SM_CYICON
)) / 2;
1208 DrawIcon(hDC
, x
, y
, hIcon
);
1210 EndPaint(hWnd
, &Ps
);
1218 hRgn
= CreateRectRgn(0, 0, 0, 0);
1219 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1221 RedrawWindow(hWnd
, NULL
, hRgn
,
1222 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1231 DefWndSetRedraw(hWnd
, wParam
);
1237 DestroyWindow(hWnd
);
1241 case WM_MOUSEACTIVATE
:
1243 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1248 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1253 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1261 return ((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1266 /* Check if the window is minimized. */
1267 if (LOWORD(wParam
) != WA_INACTIVE
&&
1268 !(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1277 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CHILD
)
1281 return (SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1286 return (SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1294 case WM_ICONERASEBKGND
:
1297 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1303 if (GetClassLongW(hWnd
, GCL_STYLE
) & CS_PARENTDC
)
1305 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1306 GetClientRect(hWnd
, &Rect
);
1307 DPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
1311 GetClipBox((HDC
)wParam
, &Rect
);
1313 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1317 case WM_CTLCOLORMSGBOX
:
1318 case WM_CTLCOLOREDIT
:
1319 case WM_CTLCOLORLISTBOX
:
1320 case WM_CTLCOLORBTN
:
1321 case WM_CTLCOLORDLG
:
1322 case WM_CTLCOLORSTATIC
:
1323 case WM_CTLCOLORSCROLLBAR
:
1324 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
1327 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
1331 ULONG Style
= GetWindowLongW(hWnd
, GWL_STYLE
);
1333 if (Style
& WS_CHILD
)
1335 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1340 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1345 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1354 return (DefWndHandleSetCursor(hWnd
, wParam
, lParam
, Style
));
1358 return (DefWndHandleSysCommand(hWnd
, wParam
, lParam
));
1361 if(wParam
== VK_F10
) iF10Key
= VK_F10
;
1364 /* FIXME: This is also incomplete. */
1367 if (HIWORD(lParam
) & KEYDATA_ALT
)
1369 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
1370 if ( (wParam
== VK_MENU
|| wParam
== VK_LMENU
1371 || wParam
== VK_RMENU
) && !iMenuSysKey
)
1378 if (wParam
== VK_F4
) /* Try to close the window */
1380 HWND top
= GetAncestor(hWnd
, GA_ROOT
);
1381 if (!(GetClassLongW(top
, GCL_STYLE
) & CS_NOCLOSE
))
1384 PostMessageW(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1386 PostMessageA(top
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1389 else if (wParam
== VK_SNAPSHOT
)
1392 while (GetParent(hwnd
) != NULL
)
1394 hwnd
= GetParent(hwnd
);
1396 DefWndScreenshot(hwnd
);
1399 else if( wParam
== VK_F10
)
1401 else if( wParam
== VK_ESCAPE
&& (GetKeyState(VK_SHIFT
) & 0x8000))
1402 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, ' ' );
1409 /* Press and release F10 or ALT */
1410 if (((wParam
== VK_MENU
|| wParam
== VK_LMENU
|| wParam
== VK_RMENU
)
1411 && iMenuSysKey
) || ((wParam
== VK_F10
) && iF10Key
))
1412 SendMessageW( GetAncestor( hWnd
, GA_ROOT
), WM_SYSCOMMAND
, SC_KEYMENU
, 0L );
1413 iMenuSysKey
= iF10Key
= 0;
1420 if (wParam
== '\r' && IsIconic(hWnd
))
1422 PostMessageW( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, 0L );
1425 if ((HIWORD(lParam
) & KEYDATA_ALT
) && wParam
)
1427 if (wParam
== '\t' || wParam
== '\x1b') break;
1428 if (wParam
== ' ' && (GetWindowLongW( hWnd
, GWL_STYLE
) & WS_CHILD
))
1429 SendMessageW( GetParent(hWnd
), Msg
, wParam
, lParam
);
1431 SendMessageW( hWnd
, WM_SYSCOMMAND
, SC_KEYMENU
, wParam
);
1433 else /* check for Ctrl-Esc */
1434 if (wParam
!= '\x1b') MessageBeep(0);
1440 if (lParam
) // Call when it is necessary.
1441 NtUserMessageCall( hWnd
, Msg
, wParam
, lParam
, 0, FNID_DEFWINDOWPROC
, FALSE
);
1448 /* FIXME: Check for a desktop. */
1449 if (!(GetWindowLongW( hWnd
, GWL_STYLE
) & WS_CHILD
)) EndMenu();
1450 if (GetCapture() == hWnd
)
1464 case WM_QUERYDROPOBJECT
:
1466 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1473 case WM_QUERYDRAGICON
:
1478 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1481 return ((LRESULT
)hIcon
);
1483 for (Len
= 1; Len
< 64; Len
++)
1485 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(Len
))) != NULL
)
1487 return((LRESULT
)hIcon
);
1490 return ((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1493 /* FIXME: WM_ISACTIVEICON */
1495 case WM_NOTIFYFORMAT
:
1497 if (lParam
== NF_QUERY
)
1498 return IsWindowUnicode(hWnd
) ? NFR_UNICODE
: NFR_ANSI
;
1504 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1505 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1506 SetClassLongW(hWnd
, Index
, lParam
);
1507 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1508 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1509 SWP_NOACTIVATE
| SWP_NOZORDER
);
1510 return ((LRESULT
)hOldIcon
);
1515 INT Index
= (wParam
== ICON_BIG
) ? GCL_HICON
: GCL_HICONSM
;
1516 return (GetClassLongW(hWnd
, Index
));
1523 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1527 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1534 THRDCARETINFO CaretInfo
;
1537 case 0xffff: /* Caret timer */
1538 /* switch showing byte in win32k and get information about the caret */
1539 if(NtUserSwitchCaretShowing(&CaretInfo
) && (CaretInfo
.hWnd
== hWnd
))
1541 DrawCaret(hWnd
, &CaretInfo
);
1549 case WM_QUERYENDSESSION
:
1554 case WM_INPUTLANGCHANGEREQUEST
:
1558 if(wParam
& INPUTLANGCHANGE_BACKWARD
1559 && wParam
& INPUTLANGCHANGE_FORWARD
)
1564 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1566 if(wParam
& INPUTLANGCHANGE_BACKWARD
) NewHkl
= (HKL
) HKL_PREV
;
1567 else if(wParam
& INPUTLANGCHANGE_FORWARD
) NewHkl
= (HKL
) HKL_NEXT
;
1568 else NewHkl
= (HKL
) lParam
;
1570 NtUserActivateKeyboardLayout(NewHkl
, 0);
1575 case WM_INPUTLANGCHANGE
:
1578 HWND
*win_array
= WIN_ListChildren( hWnd
);
1582 while (win_array
[count
])
1583 SendMessageW( win_array
[count
++], WM_INPUTLANGCHANGE
, wParam
, lParam
);
1584 HeapFree(GetProcessHeap(),0,win_array
);
1589 if (wParam
) PostQuitMessage(0);
1592 case WM_QUERYUISTATE
:
1595 PWINDOW Wnd
= ValidateHwnd(hWnd
);
1599 Ret
|= UISF_HIDEFOCUS
;
1601 Ret
|= UISF_HIDEACCEL
;
1606 case WM_CHANGEUISTATE
:
1608 BOOL AlwaysShowCues
= TRUE
;
1609 WORD Action
= LOWORD(wParam
);
1610 WORD Flags
= HIWORD(wParam
);
1613 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1617 Wnd
= ValidateHwnd(hWnd
);
1618 if (!Wnd
|| lParam
!= 0)
1621 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1624 if (Flags
& UISF_ACTIVE
)
1626 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1629 if (Action
== UIS_INITIALIZE
)
1631 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1635 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1636 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1638 /* We need to update wParam in case we need to send out messages */
1639 wParam
= MAKEWPARAM(Action
, Flags
);
1645 /* See if we actually need to change something */
1646 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1648 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1651 /* Don't need to do anything... */
1655 /* See if we actually need to change something */
1656 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1658 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1661 /* Don't need to do anything... */
1665 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1669 if ((Wnd
->Style
& WS_CHILD
) && Wnd
->Parent
!= NULL
)
1671 /* We're a child window and we need to pass this message down until
1672 we reach the root */
1673 hWnd
= UserHMGetHandle((PWINDOW
)DesktopPtrToUser(Wnd
->Parent
));
1677 /* We're a top level window, we need to change the UI state */
1678 Msg
= WM_UPDATEUISTATE
;
1682 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1684 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1687 case WM_UPDATEUISTATE
:
1690 BOOL AlwaysShowCues
= TRUE
;
1691 WORD Action
= LOWORD(wParam
);
1692 WORD Flags
= HIWORD(wParam
);
1695 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1699 Wnd
= ValidateHwnd(hWnd
);
1700 if (!Wnd
|| lParam
!= 0)
1703 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1706 if (Flags
& UISF_ACTIVE
)
1708 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1711 if (Action
== UIS_INITIALIZE
)
1713 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1717 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1718 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1720 /* We need to update wParam for broadcasting the update */
1721 wParam
= MAKEWPARAM(Action
, Flags
);
1727 /* See if we actually need to change something */
1728 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1730 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1733 /* Don't need to do anything... */
1738 /* See if we actually need to change something */
1739 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1741 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1744 /* Don't need to do anything... */
1749 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1753 /* Pack the information and call win32k */
1756 if (!NtUserCallTwoParam((DWORD
)hWnd
, (DWORD
)Flags
| ((DWORD
)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE
))
1760 /* Always broadcast the update to all children */
1761 EnumChildWindows(hWnd
,
1762 UserSendUiUpdateMsg
,
1774 * helpers for calling IMM32 (from Wine 10/22/2008)
1776 * WM_IME_* messages are generated only by IMM32,
1777 * so I assume imm32 is already LoadLibrary-ed.
1780 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1782 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1783 HWND (WINAPI
*pFunc
)(HWND
);
1788 ERR("cannot get IMM32 handle\n");
1792 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1794 hwndRet
= (*pFunc
)(hwnd
);
1801 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1803 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1804 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1809 ERR("cannot get IMM32 handle\n");
1813 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1815 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1822 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1824 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1825 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1830 ERR("cannot get IMM32 handle\n");
1834 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1836 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1843 DefWindowProcA(HWND hWnd
,
1851 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1856 ANSI_STRING AnsiString
;
1857 UNICODE_STRING UnicodeString
;
1858 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1859 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1860 * may have child window IDs instead of window name */
1864 RtlInitAnsiString(&AnsiString
, (LPSTR
)cs
->lpszName
);
1865 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
1866 NtUserDefSetText(hWnd
, &UnicodeString
);
1867 RtlFreeUnicodeString(&UnicodeString
);
1870 NtUserDefSetText(hWnd
, NULL
);
1876 case WM_GETTEXTLENGTH
:
1881 Wnd
= ValidateHwnd(hWnd
);
1882 if (Wnd
!= NULL
&& Wnd
->WindowName
.Length
!= 0)
1884 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
1886 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1888 Wnd
->WindowName
.Length
)))
1890 Result
= (LRESULT
) len
;
1901 PSTR outbuf
= (PSTR
)lParam
;
1904 Wnd
= ValidateHwnd(hWnd
);
1905 if (Wnd
!= NULL
&& wParam
!= 0)
1907 if (Wnd
->WindowName
.Buffer
!= NULL
)
1908 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
1914 if (Wnd
->WindowName
.Length
!= 0)
1916 copy
= min(Wnd
->WindowName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1917 Result
= WideCharToMultiByte(CP_ACP
,
1925 outbuf
[Result
] = '\0';
1936 ANSI_STRING AnsiString
;
1937 UNICODE_STRING UnicodeString
;
1941 RtlInitAnsiString(&AnsiString
, (LPSTR
)lParam
);
1942 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
1943 NtUserDefSetText(hWnd
, &UnicodeString
);
1944 RtlFreeUnicodeString(&UnicodeString
);
1947 NtUserDefSetText(hWnd
, NULL
);
1949 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1951 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1958 case WM_IME_KEYDOWN
:
1960 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
1966 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
1973 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
1974 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
1978 case WM_IME_STARTCOMPOSITION
:
1979 case WM_IME_COMPOSITION
:
1980 case WM_IME_ENDCOMPOSITION
:
1986 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
1988 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
1992 case WM_IME_SETCONTEXT
:
1996 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
1998 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
2004 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2007 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2013 DefWindowProcW(HWND hWnd
,
2021 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
2026 UNICODE_STRING UnicodeString
;
2027 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
2028 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2029 * may have child window IDs instead of window name */
2032 RtlInitUnicodeString(&UnicodeString
, (LPWSTR
)cs
->lpszName
);
2034 NtUserDefSetText(hWnd
, (cs
->lpszName
? &UnicodeString
: NULL
));
2039 case WM_GETTEXTLENGTH
:
2044 Wnd
= ValidateHwnd(hWnd
);
2045 if (Wnd
!= NULL
&& Wnd
->WindowName
.Length
!= 0)
2047 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
2049 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
2051 Wnd
->WindowName
.Length
)))
2053 Result
= (LRESULT
) (Wnd
->WindowName
.Length
/ sizeof(WCHAR
));
2064 PWSTR outbuf
= (PWSTR
)lParam
;
2066 Wnd
= ValidateHwnd(hWnd
);
2067 if (Wnd
!= NULL
&& wParam
!= 0)
2069 if (Wnd
->WindowName
.Buffer
!= NULL
)
2070 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
2076 if (Wnd
->WindowName
.Length
!= 0)
2078 Result
= min(Wnd
->WindowName
.Length
/ sizeof(WCHAR
), wParam
- 1);
2079 RtlCopyMemory(outbuf
,
2081 Result
* sizeof(WCHAR
));
2082 outbuf
[Result
] = L
'\0';
2093 UNICODE_STRING UnicodeString
;
2096 RtlInitUnicodeString(&UnicodeString
, (LPWSTR
)lParam
);
2098 NtUserDefSetText(hWnd
, (lParam
? &UnicodeString
: NULL
));
2100 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2102 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
2110 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
2115 case WM_IME_KEYDOWN
:
2117 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2123 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
2127 case WM_IME_STARTCOMPOSITION
:
2128 case WM_IME_COMPOSITION
:
2129 case WM_IME_ENDCOMPOSITION
:
2135 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2137 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
2141 case WM_IME_SETCONTEXT
:
2145 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2147 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
2152 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
2154 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);