2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Miscellaneous User functions
5 * FILE: win32ss/user/ntuser/defwnd.c
12 DBG_DEFAULT_CHANNEL(UserDefwnd
);
16 DefWndControlColor(HDC hDC
, UINT ctlType
)
18 if (ctlType
== CTLCOLOR_SCROLLBAR
)
20 HBRUSH hb
= IntGetSysColorBrush(COLOR_SCROLLBAR
);
21 COLORREF bk
= IntGetSysColor(COLOR_3DHILIGHT
);
22 IntGdiSetTextColor(hDC
, IntGetSysColor(COLOR_3DFACE
));
23 IntGdiSetBkColor(hDC
, bk
);
25 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
26 * we better use 0x55aa bitmap brush to make scrollbar's background
27 * look different from the window background.
29 if ( bk
== IntGetSysColor(COLOR_WINDOW
))
32 NtGdiUnrealizeObject( hb
);
36 IntGdiSetTextColor(hDC
, IntGetSysColor(COLOR_WINDOWTEXT
));
38 if ((ctlType
== CTLCOLOR_EDIT
) || (ctlType
== CTLCOLOR_LISTBOX
))
40 IntGdiSetBkColor(hDC
, IntGetSysColor(COLOR_WINDOW
));
44 IntGdiSetBkColor(hDC
, IntGetSysColor(COLOR_3DFACE
));
45 return IntGetSysColorBrush(COLOR_3DFACE
);
48 return IntGetSysColorBrush(COLOR_WINDOW
);
52 DefWndHandleWindowPosChanging(PWND pWnd
, WINDOWPOS
* Pos
)
54 POINT maxTrack
, minTrack
;
55 LONG style
= pWnd
->style
;
57 if (Pos
->flags
& SWP_NOSIZE
) return 0;
58 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
60 co_WinPosGetMinMaxInfo(pWnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
61 Pos
->cx
= min(Pos
->cx
, maxTrack
.x
);
62 Pos
->cy
= min(Pos
->cy
, maxTrack
.y
);
63 if (!(style
& WS_MINIMIZE
))
65 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
66 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
71 Pos
->cx
= max(Pos
->cx
, 0);
72 Pos
->cy
= max(Pos
->cy
, 0);
78 DefWndHandleWindowPosChanged(PWND pWnd
, WINDOWPOS
* Pos
)
81 LONG style
= pWnd
->style
;
83 IntGetClientRect(pWnd
, &Rect
);
84 IntMapWindowPoints(pWnd
, (style
& WS_CHILD
? IntGetParent(pWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
86 if (!(Pos
->flags
& SWP_NOCLIENTMOVE
))
88 co_IntSendMessage(UserHMGetHandle(pWnd
), WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
91 if (!(Pos
->flags
& SWP_NOCLIENTSIZE
) || (Pos
->flags
& SWP_STATECHANGED
))
93 if (style
& WS_MINIMIZE
) co_IntSendMessage(UserHMGetHandle(pWnd
), WM_SIZE
, SIZE_MINIMIZED
, 0 );
96 WPARAM wp
= (style
& WS_MAXIMIZE
) ? SIZE_MAXIMIZED
: SIZE_RESTORED
;
97 co_IntSendMessage(UserHMGetHandle(pWnd
), WM_SIZE
, wp
, MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
104 // Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
107 DefWndHandleSysCommand(PWND pWnd
, WPARAM wParam
, LPARAM lParam
)
112 if (ISITHOOKED(WH_CBT
) || (pWnd
->head
.rpdesk
->pDeskInfo
->fsHooks
& HOOKID_TO_FLAG(WH_CBT
)))
115 lResult
= co_HOOK_CallHooks(WH_CBT
, HCBT_SYSCOMMAND
, wParam
, lParam
);
117 if (lResult
) return lResult
;
120 switch (wParam
& 0xfff0)
124 DefWndDoSizeMove(pWnd
, wParam
);
128 if (UserHMGetHandle(pWnd
) == UserGetActiveWindow())
129 IntShowOwnedPopups(pWnd
,FALSE
); // This is done in ShowWindow! Need to retest!
130 co_WinPosShowWindow( pWnd
, SW_MINIMIZE
);
134 if (((pWnd
->style
& WS_MINIMIZE
) != 0) && UserHMGetHandle(pWnd
) == UserGetActiveWindow())
135 IntShowOwnedPopups(pWnd
,TRUE
);
136 co_WinPosShowWindow( pWnd
, SW_MAXIMIZE
);
140 if (((pWnd
->style
& WS_MINIMIZE
) != 0) && UserHMGetHandle(pWnd
) == UserGetActiveWindow())
141 IntShowOwnedPopups(pWnd
,TRUE
);
142 co_WinPosShowWindow( pWnd
, SW_RESTORE
);
146 return co_IntSendMessage(UserHMGetHandle(pWnd
), WM_CLOSE
, 0, 0);
149 ERR("Screensaver Called!\n");
150 UserPostMessage(hwndSAS
, WM_LOGONNOTIFY
, LN_START_SCREENSAVE
, 0); // always lParam 0 == not Secure
155 USER_REFERENCE_ENTRY Ref
;
157 pWnd
= ValidateHwndNoErr((HWND
)lParam
);
160 if (pWnd
->spwndLastActive
)
162 pWnd
= pWnd
->spwndLastActive
;
164 UserRefObjectCo(pWnd
, &Ref
);
165 co_IntSetForegroundWindow(pWnd
);
166 UserDerefObjectCo(pWnd
);
167 if (pWnd
->style
& WS_MINIMIZE
)
169 UserPostMessage(UserHMGetHandle(pWnd
), WM_SYSCOMMAND
, SC_RESTORE
, 0);
177 // We do not support anything else here so we should return normal even when sending a hook.
181 return(Hook
? 1 : 0); // Don't call us again from user space.
185 co_IntFindChildWindowToOwner(PWND Root
, PWND Owner
)
188 PWND Child
, OwnerWnd
;
190 for(Child
= Root
->spwndChild
; Child
; Child
= Child
->spwndNext
)
192 OwnerWnd
= Child
->spwndOwner
;
196 if (!(Child
->style
& WS_POPUP
) ||
197 !(Child
->style
& WS_VISIBLE
) ||
198 /* Fixes CMD pop up properties window from having foreground. */
199 Owner
->head
.pti
->MessageQueue
!= Child
->head
.pti
->MessageQueue
)
202 if(OwnerWnd
== Owner
)
212 DefWndHandleSetCursor(PWND pWnd
, WPARAM wParam
, LPARAM lParam
)
214 PWND pwndPopUP
= NULL
;
215 WORD Msg
= HIWORD(lParam
);
217 /* Not for child windows. */
218 if (UserHMGetHandle(pWnd
) != (HWND
)wParam
)
223 switch((short)LOWORD(lParam
))
227 //// This is the real fix for CORE-6129! This was a "Code hole".
228 USER_REFERENCE_ENTRY Ref
;
230 if (Msg
== WM_LBUTTONDOWN
)
232 // Find a pop up window to bring active.
233 pwndPopUP
= co_IntFindChildWindowToOwner(UserGetDesktopWindow(), pWnd
);
236 // Not a child pop up from desktop.
237 if ( pwndPopUP
!= UserGetDesktopWindow()->spwndChild
)
239 // Get original active window.
240 PWND pwndOrigActive
= gpqForeground
->spwndActive
;
242 co_WinPosSetWindowPos(pWnd
, NULL
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
244 UserRefObjectCo(pwndPopUP
, &Ref
);
245 //UserSetActiveWindow(pwndPopUP);
246 co_IntSetForegroundWindow(pwndPopUP
); // HACK
247 UserDerefObjectCo(pwndPopUP
);
249 // If the change was made, break out.
250 if (pwndOrigActive
!= gpqForeground
->spwndActive
)
256 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
257 Msg
== WM_RBUTTONDOWN
|| Msg
== WM_XBUTTONDOWN
)
263 UserHMGetHandle(pwndPopUP
),
265 gspv
.dwForegroundFlashCount
,
266 (gpsi
->dtCaretBlink
>> 3)};
268 // Now shake that window!
269 IntFlashWindowEx(pwndPopUP
, &fwi
);
271 UserPostMessage(hwndSAS
, WM_LOGONNOTIFY
, LN_MESSAGE_BEEP
, 0);
278 if (pWnd
->pcls
->spcur
)
280 UserSetCursor(pWnd
->pcls
->spcur
, FALSE
);
288 if (pWnd
->style
& WS_MAXIMIZE
)
292 UserSetCursor(SYSTEMCUR(SIZEWE
), FALSE
);
299 if (pWnd
->style
& WS_MAXIMIZE
)
303 UserSetCursor(SYSTEMCUR(SIZENS
), FALSE
);
310 if (pWnd
->style
& WS_MAXIMIZE
)
314 UserSetCursor(SYSTEMCUR(SIZENWSE
), FALSE
);
321 if (pWnd
->style
& WS_MAXIMIZE
)
325 UserSetCursor(SYSTEMCUR(SIZENESW
), FALSE
);
329 UserSetCursor(SYSTEMCUR(ARROW
), FALSE
);
333 VOID FASTCALL
DefWndPrint( PWND pwnd
, HDC hdc
, ULONG uFlags
)
338 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
339 !IntIsWindowVisible(pwnd
) )
343 * Unimplemented flags.
345 if ( (uFlags
& PRF_CHILDREN
) ||
346 (uFlags
& PRF_OWNED
) ||
347 (uFlags
& PRF_NONCLIENT
) )
349 FIXME("WM_PRINT message with unsupported flags\n");
355 if ( uFlags
& PRF_ERASEBKGND
)
356 co_IntSendMessage(UserHMGetHandle(pwnd
), WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
361 if ( uFlags
& PRF_CLIENT
)
362 co_IntSendMessage(UserHMGetHandle(pwnd
), WM_PRINTCLIENT
, (WPARAM
)hdc
, uFlags
);
367 Win32k counterpart of User DefWindowProc
378 USER_REFERENCE_ENTRY Ref
;
380 if (Msg
> WM_USER
) return 0;
386 ERR("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd
->head
.h
, wParam
, lParam
);
387 lResult
= DefWndHandleSysCommand(Wnd
, wParam
, lParam
);
392 if ((Wnd
->style
& WS_VISIBLE
) && wParam
) break;
393 if (!(Wnd
->style
& WS_VISIBLE
) && !wParam
) break;
394 if (!Wnd
->spwndOwner
) break;
399 if (!(Wnd
->state
& WNDS_HIDDENPOPUP
)) break;
400 Wnd
->state
&= ~WNDS_HIDDENPOPUP
;
403 Wnd
->state
|= WNDS_HIDDENPOPUP
;
405 co_WinPosShowWindow(Wnd
, wParam
? SW_SHOWNOACTIVATE
: SW_HIDE
);
410 case WM_CLIENTSHUTDOWN
:
411 return IntClientShutdown(Wnd
, wParam
, lParam
);
414 ERR("WM_APPCOMMAND\n");
415 if ( (Wnd
->style
& (WS_POPUP
|WS_CHILD
)) != WS_CHILD
&&
416 Wnd
!= co_GetDesktopWindow(Wnd
) )
418 if (!co_HOOK_CallHooks(WH_SHELL
, HSHELL_APPCOMMAND
, wParam
, lParam
))
419 co_IntShellHookNotify(HSHELL_APPCOMMAND
, wParam
, lParam
);
422 UserRefObjectCo(Wnd
->spwndParent
, &Ref
);
423 lResult
= co_IntSendMessage(UserHMGetHandle(Wnd
->spwndParent
), WM_APPCOMMAND
, wParam
, lParam
);
424 UserDerefObjectCo(Wnd
->spwndParent
);
428 co_UserDestroyWindow(Wnd
);
431 case WM_CTLCOLORMSGBOX
:
432 case WM_CTLCOLOREDIT
:
433 case WM_CTLCOLORLISTBOX
:
436 case WM_CTLCOLORSTATIC
:
437 case WM_CTLCOLORSCROLLBAR
:
438 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
441 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
445 if (Wnd
->style
& WS_CHILD
)
447 /* with the exception of the border around a resizable wnd,
448 * give the parent first chance to set the cursor */
449 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
451 PWND parent
= Wnd
->spwndParent
;//IntGetParent( Wnd );
452 if (parent
!= UserGetDesktopWindow() &&
453 co_IntSendMessage( UserHMGetHandle(parent
), WM_SETCURSOR
, wParam
, lParam
))
457 return DefWndHandleSetCursor(Wnd
, wParam
, lParam
);
461 /* The default action in Windows is to set the keyboard focus to
462 * the window, if it's being activated and not minimized */
463 if (LOWORD(wParam
) != WA_INACTIVE
&&
464 !(Wnd
->style
& WS_MINIMIZE
))
466 //ERR("WM_ACTIVATE %p\n",hWnd);
467 co_UserSetFocus(Wnd
);
472 if (Wnd
->style
& WS_CHILD
)
475 PWND pwndParent
= IntGetParent(Wnd
);
476 hwndParent
= pwndParent
? UserHMGetHandle(pwndParent
) : NULL
;
477 return co_IntSendMessage( hwndParent
, WM_MOUSEWHEEL
, wParam
, lParam
);
482 case WM_ICONERASEBKGND
:
485 HBRUSH hBrush
= Wnd
->pcls
->hbrBackground
;
486 if (!hBrush
) return 0;
487 if (hBrush
<= (HBRUSH
)COLOR_MENUBAR
)
489 hBrush
= IntGetSysColorBrush((INT
)hBrush
);
491 if (Wnd
->pcls
->style
& CS_PARENTDC
)
493 /* can't use GetClipBox with a parent DC or we fill the whole parent */
494 IntGetClientRect(Wnd
, &Rect
);
495 GreDPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
499 GdiGetClipBox((HDC
)wParam
, &Rect
);
501 FillRect((HDC
)wParam
, &Rect
, hBrush
);
506 //ERR("WM_GETHOTKEY\n");
507 return DefWndGetHotKey(Wnd
);
509 //ERR("WM_SETHOTKEY\n");
510 return DefWndSetHotKey(Wnd
, wParam
);
515 Point
.x
= GET_X_LPARAM(lParam
);
516 Point
.y
= GET_Y_LPARAM(lParam
);
517 return GetNCHitEx(Wnd
, Point
);
522 DefWndPrint(Wnd
, (HDC
)wParam
, lParam
);
532 /* If already in Paint and Client area is not empty just return. */
533 if (Wnd
->state2
& WNDS2_STARTPAINT
&& !RECTL_bIsEmptyRect(&Wnd
->rcClient
))
535 ERR("In Paint and Client area is not empty!\n");
539 hDC
= IntBeginPaint(Wnd
, &Ps
);
542 if (((Wnd
->style
& WS_MINIMIZE
) != 0) && (Wnd
->pcls
->spicn
))
547 ERR("Doing Paint and Client area is empty!\n");
548 IntGetClientRect(Wnd
, &ClientRect
);
549 x
= (ClientRect
.right
- ClientRect
.left
- UserGetSystemMetrics(SM_CXICON
)) / 2;
550 y
= (ClientRect
.bottom
- ClientRect
.top
- UserGetSystemMetrics(SM_CYICON
)) / 2;
551 UserDrawIconEx(hDC
, x
, y
, Wnd
->pcls
->spicn
, 0, 0, 0, 0, DI_NORMAL
| DI_COMPAT
| DI_DEFAULTSIZE
);
554 IntEndPaint(Wnd
, &Ps
);
562 Wnd
->state
&= ~WNDS_SYNCPAINTPENDING
;
563 TRACE("WM_SYNCPAINT\n");
564 hRgn
= NtGdiCreateRectRgn(0, 0, 0, 0);
567 if (co_UserGetUpdateRgn(Wnd
, hRgn
, FALSE
) != NULLREGION
)
569 PREGION pRgn
= REGION_LockRgn(hRgn
);
570 if (pRgn
) REGION_UnlockRgn(pRgn
);
572 wParam
= (RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
573 co_UserRedrawWindow(Wnd
, NULL
, pRgn
, wParam
);
575 GreDeleteObject(hRgn
);
581 ERR("WM_SETREDRAW\n");
584 if (!(Wnd
->style
& WS_VISIBLE
))
586 IntSetStyle( Wnd
, WS_VISIBLE
, 0 );
587 Wnd
->state
|= WNDS_SENDNCPAINT
;
592 if (Wnd
->style
& WS_VISIBLE
)
594 co_UserRedrawWindow( Wnd
, NULL
, NULL
, RDW_ALLCHILDREN
| RDW_VALIDATE
);
595 IntSetStyle( Wnd
, 0, WS_VISIBLE
);
600 case WM_WINDOWPOSCHANGING
:
602 return (DefWndHandleWindowPosChanging(Wnd
, (WINDOWPOS
*)lParam
));
605 case WM_WINDOWPOSCHANGED
:
607 return (DefWndHandleWindowPosChanged(Wnd
, (WINDOWPOS
*)lParam
));
623 ProbeForRead((PVOID
)lParam
,
631 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
638 lResult
= co_HOOK_CallHooks(WH_CBT
, HCBT_MOVESIZE
, (WPARAM
)Wnd
->head
.h
, lParam
? (LPARAM
)&rt
: 0);