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
:
1577 //FIXME: What to do?
1582 if (wParam
) PostQuitMessage(0);
1585 case WM_QUERYUISTATE
:
1588 PWINDOW Wnd
= ValidateHwnd(hWnd
);
1592 Ret
|= UISF_HIDEFOCUS
;
1594 Ret
|= UISF_HIDEACCEL
;
1599 case WM_CHANGEUISTATE
:
1601 BOOL AlwaysShowCues
= TRUE
;
1602 WORD Action
= LOWORD(wParam
);
1603 WORD Flags
= HIWORD(wParam
);
1606 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1610 Wnd
= ValidateHwnd(hWnd
);
1611 if (!Wnd
|| lParam
!= 0)
1614 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1617 if (Flags
& UISF_ACTIVE
)
1619 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1622 if (Action
== UIS_INITIALIZE
)
1624 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1628 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1629 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1631 /* We need to update wParam in case we need to send out messages */
1632 wParam
= MAKEWPARAM(Action
, Flags
);
1638 /* See if we actually need to change something */
1639 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1641 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1644 /* Don't need to do anything... */
1648 /* See if we actually need to change something */
1649 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1651 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1654 /* Don't need to do anything... */
1658 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action
);
1662 if ((Wnd
->Style
& WS_CHILD
) && Wnd
->Parent
!= NULL
)
1664 /* We're a child window and we need to pass this message down until
1665 we reach the root */
1666 hWnd
= UserHMGetHandle((PWINDOW
)DesktopPtrToUser(Wnd
->Parent
));
1670 /* We're a top level window, we need to change the UI state */
1671 Msg
= WM_UPDATEUISTATE
;
1675 return SendMessageW(hWnd
, Msg
, wParam
, lParam
);
1677 return SendMessageA(hWnd
, Msg
, wParam
, lParam
);
1680 case WM_UPDATEUISTATE
:
1683 BOOL AlwaysShowCues
= TRUE
;
1684 WORD Action
= LOWORD(wParam
);
1685 WORD Flags
= HIWORD(wParam
);
1688 SystemParametersInfoW(SPI_GETKEYBOARDCUES
, 0, &AlwaysShowCues
, 0);
1692 Wnd
= ValidateHwnd(hWnd
);
1693 if (!Wnd
|| lParam
!= 0)
1696 if (Flags
& ~(UISF_HIDEFOCUS
| UISF_HIDEACCEL
| UISF_ACTIVE
))
1699 if (Flags
& UISF_ACTIVE
)
1701 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1704 if (Action
== UIS_INITIALIZE
)
1706 PDESKTOPINFO Desk
= GetThreadDesktopInfo();
1710 Action
= Desk
->LastInputWasKbd
? UIS_CLEAR
: UIS_SET
;
1711 Flags
= UISF_HIDEFOCUS
| UISF_HIDEACCEL
;
1713 /* We need to update wParam for broadcasting the update */
1714 wParam
= MAKEWPARAM(Action
, Flags
);
1720 /* See if we actually need to change something */
1721 if ((Flags
& UISF_HIDEFOCUS
) && !Wnd
->HideFocus
)
1723 if ((Flags
& UISF_HIDEACCEL
) && !Wnd
->HideAccel
)
1726 /* Don't need to do anything... */
1731 /* See if we actually need to change something */
1732 if ((Flags
& UISF_HIDEFOCUS
) && Wnd
->HideFocus
)
1734 if ((Flags
& UISF_HIDEACCEL
) && Wnd
->HideAccel
)
1737 /* Don't need to do anything... */
1742 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action
);
1746 /* Pack the information and call win32k */
1749 if (!NtUserCallTwoParam((DWORD
)hWnd
, (DWORD
)Flags
| ((DWORD
)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE
))
1753 /* Always broadcast the update to all children */
1754 EnumChildWindows(hWnd
,
1755 UserSendUiUpdateMsg
,
1767 * helpers for calling IMM32 (from Wine 10/22/2008)
1769 * WM_IME_* messages are generated only by IMM32,
1770 * so I assume imm32 is already LoadLibrary-ed.
1773 DefWndImmGetDefaultIMEWnd(HWND hwnd
)
1775 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1776 HWND (WINAPI
*pFunc
)(HWND
);
1781 ERR("cannot get IMM32 handle\n");
1785 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmGetDefaultIMEWnd");
1787 hwndRet
= (*pFunc
)(hwnd
);
1794 DefWndImmIsUIMessageA(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1796 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1797 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1802 ERR("cannot get IMM32 handle\n");
1806 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageA");
1808 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1815 DefWndImmIsUIMessageW(HWND hwndIME
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1817 HINSTANCE hInstIMM
= GetModuleHandleW(L
"imm32\0");
1818 BOOL (WINAPI
*pFunc
)(HWND
,UINT
,WPARAM
,LPARAM
);
1823 ERR("cannot get IMM32 handle\n");
1827 pFunc
= (void*) GetProcAddress(hInstIMM
, "ImmIsUIMessageW");
1829 fRet
= (*pFunc
)(hwndIME
, msg
, wParam
, lParam
);
1836 DefWindowProcA(HWND hWnd
,
1844 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
1849 ANSI_STRING AnsiString
;
1850 UNICODE_STRING UnicodeString
;
1851 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
1852 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1853 * may have child window IDs instead of window name */
1857 RtlInitAnsiString(&AnsiString
, (LPSTR
)cs
->lpszName
);
1858 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
1859 NtUserDefSetText(hWnd
, &UnicodeString
);
1860 RtlFreeUnicodeString(&UnicodeString
);
1863 NtUserDefSetText(hWnd
, NULL
);
1869 case WM_GETTEXTLENGTH
:
1874 Wnd
= ValidateHwnd(hWnd
);
1875 if (Wnd
!= NULL
&& Wnd
->WindowName
.Length
!= 0)
1877 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
1879 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
1881 Wnd
->WindowName
.Length
)))
1883 Result
= (LRESULT
) len
;
1894 PSTR outbuf
= (PSTR
)lParam
;
1897 Wnd
= ValidateHwnd(hWnd
);
1898 if (Wnd
!= NULL
&& wParam
!= 0)
1900 if (Wnd
->WindowName
.Buffer
!= NULL
)
1901 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
1907 if (Wnd
->WindowName
.Length
!= 0)
1909 copy
= min(Wnd
->WindowName
.Length
/ sizeof(WCHAR
), wParam
- 1);
1910 Result
= WideCharToMultiByte(CP_ACP
,
1918 outbuf
[Result
] = '\0';
1929 ANSI_STRING AnsiString
;
1930 UNICODE_STRING UnicodeString
;
1934 RtlInitAnsiString(&AnsiString
, (LPSTR
)lParam
);
1935 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
1936 NtUserDefSetText(hWnd
, &UnicodeString
);
1937 RtlFreeUnicodeString(&UnicodeString
);
1940 NtUserDefSetText(hWnd
, NULL
);
1942 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1944 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1951 case WM_IME_KEYDOWN
:
1953 Result
= PostMessageA(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
1959 Result
= PostMessageA(hWnd
, WM_KEYUP
, wParam
, lParam
);
1966 PostMessageA(hWnd
, WM_CHAR
, HIBYTE(wParam
), lParam
);
1967 PostMessageA(hWnd
, WM_CHAR
, LOBYTE(wParam
), lParam
);
1971 case WM_IME_STARTCOMPOSITION
:
1972 case WM_IME_COMPOSITION
:
1973 case WM_IME_ENDCOMPOSITION
:
1979 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
1981 Result
= SendMessageA(hwndIME
, Msg
, wParam
, lParam
);
1985 case WM_IME_SETCONTEXT
:
1989 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
1991 Result
= DefWndImmIsUIMessageA(hwndIME
, Msg
, wParam
, lParam
);
1997 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
2000 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);
2006 DefWindowProcW(HWND hWnd
,
2014 SPY_EnterMessage(SPY_DEFWNDPROC
, hWnd
, Msg
, wParam
, lParam
);
2019 UNICODE_STRING UnicodeString
;
2020 LPCREATESTRUCTW cs
= (LPCREATESTRUCTW
)lParam
;
2021 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2022 * may have child window IDs instead of window name */
2025 RtlInitUnicodeString(&UnicodeString
, (LPWSTR
)cs
->lpszName
);
2027 NtUserDefSetText(hWnd
, (cs
->lpszName
? &UnicodeString
: NULL
));
2032 case WM_GETTEXTLENGTH
:
2037 Wnd
= ValidateHwnd(hWnd
);
2038 if (Wnd
!= NULL
&& Wnd
->WindowName
.Length
!= 0)
2040 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
2042 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len
,
2044 Wnd
->WindowName
.Length
)))
2046 Result
= (LRESULT
) (Wnd
->WindowName
.Length
/ sizeof(WCHAR
));
2057 PWSTR outbuf
= (PWSTR
)lParam
;
2059 Wnd
= ValidateHwnd(hWnd
);
2060 if (Wnd
!= NULL
&& wParam
!= 0)
2062 if (Wnd
->WindowName
.Buffer
!= NULL
)
2063 buf
= DesktopPtrToUser(Wnd
->WindowName
.Buffer
);
2069 if (Wnd
->WindowName
.Length
!= 0)
2071 Result
= min(Wnd
->WindowName
.Length
/ sizeof(WCHAR
), wParam
- 1);
2072 RtlCopyMemory(outbuf
,
2074 Result
* sizeof(WCHAR
));
2075 outbuf
[Result
] = L
'\0';
2086 UNICODE_STRING UnicodeString
;
2089 RtlInitUnicodeString(&UnicodeString
, (LPWSTR
)lParam
);
2091 NtUserDefSetText(hWnd
, (lParam
? &UnicodeString
: NULL
));
2093 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
2095 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
2103 PostMessageW(hWnd
, WM_CHAR
, wParam
, lParam
);
2108 case WM_IME_KEYDOWN
:
2110 Result
= PostMessageW(hWnd
, WM_KEYDOWN
, wParam
, lParam
);
2116 Result
= PostMessageW(hWnd
, WM_KEYUP
, wParam
, lParam
);
2120 case WM_IME_STARTCOMPOSITION
:
2121 case WM_IME_COMPOSITION
:
2122 case WM_IME_ENDCOMPOSITION
:
2128 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2130 Result
= SendMessageW(hwndIME
, Msg
, wParam
, lParam
);
2134 case WM_IME_SETCONTEXT
:
2138 hwndIME
= DefWndImmGetDefaultIMEWnd(hWnd
);
2140 Result
= DefWndImmIsUIMessageW(hwndIME
, Msg
, wParam
, lParam
);
2145 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);
2147 SPY_ExitMessage(SPY_RESULT_DEFWND
, hWnd
, Msg
, Result
, wParam
, lParam
);