2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Miscellaneous User functions
5 * FILE: subsystems/win32/win32k/ntuser/defwnd.c
10 DBG_DEFAULT_CHANNEL(UserDefwnd
);
12 // Client Shutdown messages
13 #define MCS_SHUTDOWNTIMERS 1
14 #define MCS_QUERYENDSESSION 2
15 // Client Shutdown returns
16 #define MCSR_GOODFORSHUTDOWN 1
17 #define MCSR_SHUTDOWNFINISHED 2
18 #define MCSR_DONOTSHUTDOWN 3
21 * Based on CSRSS and described in pages 1115 - 1118 "Windows Internals, Fifth Edition".
22 * Apparently CSRSS sends out messages to do this w/o going into win32k internals.
35 LRESULT lResult
= MCSR_GOODFORSHUTDOWN
;
38 lParams
= wParam
& (ENDSESSION_LOGOFF
|ENDSESSION_CRITICAL
|ENDSESSION_CLOSEAPP
);
39 KillTimers
= wParam
& MCS_SHUTDOWNTIMERS
? TRUE
: FALSE
;
41 First, send end sessions to children.
43 List
= IntWinListChildren(pWindow
);
47 for (i
= 0; List
[i
]; i
++)
51 if (!(WndChild
= UserGetWindowObject(List
[i
])))
54 if (wParam
& MCS_QUERYENDSESSION
)
56 if (!co_IntSendMessage(WndChild
->head
.h
, WM_QUERYENDSESSION
, 0, lParams
))
58 lResult
= MCSR_DONOTSHUTDOWN
;
64 co_IntSendMessage(WndChild
->head
.h
, WM_ENDSESSION
, KillTimers
, lParams
);
67 DestroyTimersForWindow(WndChild
->head
.pti
, WndChild
);
69 lResult
= MCSR_SHUTDOWNFINISHED
;
72 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
74 if (List
&& (lResult
== MCSR_DONOTSHUTDOWN
)) return lResult
;
78 if (wParam
& MCS_QUERYENDSESSION
)
80 if (!co_IntSendMessage(pWindow
->head
.h
, WM_QUERYENDSESSION
, 0, lParams
))
82 lResult
= MCSR_DONOTSHUTDOWN
;
87 co_IntSendMessage(pWindow
->head
.h
, WM_ENDSESSION
, KillTimers
, lParams
);
90 DestroyTimersForWindow(pWindow
->head
.pti
, pWindow
);
92 lResult
= MCSR_SHUTDOWNFINISHED
;
98 DefWndControlColor(HDC hDC
, UINT ctlType
)
100 if (ctlType
== CTLCOLOR_SCROLLBAR
)
102 HBRUSH hb
= IntGetSysColorBrush(COLOR_SCROLLBAR
);
103 COLORREF bk
= IntGetSysColor(COLOR_3DHILIGHT
);
104 IntGdiSetTextColor(hDC
, IntGetSysColor(COLOR_3DFACE
));
105 IntGdiSetBkColor(hDC
, bk
);
107 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
108 * we better use 0x55aa bitmap brush to make scrollbar's background
109 * look different from the window background.
111 if ( bk
== IntGetSysColor(COLOR_WINDOW
))
112 return gpsi
->hbrGray
;
114 NtGdiUnrealizeObject( hb
);
118 IntGdiSetTextColor(hDC
, IntGetSysColor(COLOR_WINDOWTEXT
));
120 if ((ctlType
== CTLCOLOR_EDIT
) || (ctlType
== CTLCOLOR_LISTBOX
))
122 IntGdiSetBkColor(hDC
, IntGetSysColor(COLOR_WINDOW
));
126 IntGdiSetBkColor(hDC
, IntGetSysColor(COLOR_3DFACE
));
127 return IntGetSysColorBrush(COLOR_3DFACE
);
130 return IntGetSysColorBrush(COLOR_WINDOW
);
135 DefWndHandleSysCommand(PWND pWnd
, WPARAM wParam
, LPARAM lParam
)
140 if (ISITHOOKED(WH_CBT
) || (pWnd
->head
.rpdesk
->pDeskInfo
->fsHooks
& HOOKID_TO_FLAG(WH_CBT
)))
143 lResult
= co_HOOK_CallHooks(WH_CBT
, HCBT_SYSCOMMAND
, wParam
, lParam
);
145 if (lResult
) return lResult
;
148 switch (wParam
& 0xfff0)
151 ERR("Screensaver Called!\n");
152 UserPostMessage(hwndSAS
, WM_LOGONNOTIFY
, LN_START_SCREENSAVE
, 0); // always lParam 0 == not Secure
156 // We do not support anything else here so we should return normal even when sending a hook.
160 return(Hook
? 1 : 0); // Don't call us again from user space.
164 Win32k counterpart of User DefWindowProc
175 USER_REFERENCE_ENTRY Ref
;
177 if (Msg
> WM_USER
) return 0;
183 ERR("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd
->head
.h
, wParam
, lParam
);
184 lResult
= DefWndHandleSysCommand(Wnd
, wParam
, lParam
);
189 if ((Wnd
->style
& WS_VISIBLE
) && wParam
) break;
190 if (!(Wnd
->style
& WS_VISIBLE
) && !wParam
) break;
191 if (!Wnd
->spwndOwner
) break;
196 if (!(Wnd
->state
& WNDS_HIDDENPOPUP
)) break;
197 Wnd
->state
&= ~WNDS_HIDDENPOPUP
;
200 Wnd
->state
|= WNDS_HIDDENPOPUP
;
202 co_WinPosShowWindow(Wnd
, wParam
? SW_SHOWNOACTIVATE
: SW_HIDE
);
206 case WM_CLIENTSHUTDOWN
:
207 return IntClientShutdown(Wnd
, wParam
, lParam
);
210 ERR("WM_APPCOMMAND\n");
211 if ( (Wnd
->style
& (WS_POPUP
|WS_CHILD
)) != WS_CHILD
&&
212 Wnd
!= co_GetDesktopWindow(Wnd
) )
214 if (!co_HOOK_CallHooks(WH_SHELL
, HSHELL_APPCOMMAND
, wParam
, lParam
))
215 co_IntShellHookNotify(HSHELL_APPCOMMAND
, wParam
, lParam
);
218 UserRefObjectCo(Wnd
->spwndParent
, &Ref
);
219 lResult
= co_IntSendMessage(UserHMGetHandle(Wnd
->spwndParent
), WM_APPCOMMAND
, wParam
, lParam
);
220 UserDerefObjectCo(Wnd
->spwndParent
);
223 case WM_CTLCOLORMSGBOX
:
224 case WM_CTLCOLOREDIT
:
225 case WM_CTLCOLORLISTBOX
:
228 case WM_CTLCOLORSTATIC
:
229 case WM_CTLCOLORSCROLLBAR
:
230 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
233 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
236 return DefWndGetHotKey(Wnd
);
238 return DefWndSetHotKey(Wnd
, wParam
);
243 Point
.x
= GET_X_LPARAM(lParam
);
244 Point
.y
= GET_Y_LPARAM(lParam
);
245 return GetNCHitEx(Wnd
, Point
);
251 Wnd
->state
&= ~WNDS_SYNCPAINTPENDING
;
252 ERR("WM_SYNCPAINT\n");
253 hRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
254 if (co_UserGetUpdateRgn(Wnd
, hRgn
, FALSE
) != NULLREGION
)
256 if (!wParam
) wParam
= (RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
257 co_UserRedrawWindow(Wnd
, NULL
, hRgn
, wParam
);
259 GreDeleteObject(hRgn
);
266 if (!(Wnd
->style
& WS_VISIBLE
))
268 IntSetStyle( Wnd
, WS_VISIBLE
, 0 );
269 Wnd
->state
|= WNDS_SENDNCPAINT
;
274 if (Wnd
->style
& WS_VISIBLE
)
276 co_UserRedrawWindow( Wnd
, NULL
, NULL
, RDW_ALLCHILDREN
| RDW_VALIDATE
);
277 IntSetStyle( Wnd
, 0, WS_VISIBLE
);
295 ProbeForRead((PVOID
)lParam
,
303 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
310 lResult
= co_HOOK_CallHooks(WH_CBT
, HCBT_MOVESIZE
, (WPARAM
)Wnd
->head
.h
, lParam
? (LPARAM
)&rt
: 0);
321 HICON FASTCALL
NC_IconForWindow( PWND pWnd
)
324 // First thing to do, init the Window Logo icons.
325 if (!gpsi
->hIconSmWindows
) co_IntSetWndIcons();
327 if (!hIcon
) hIcon
= UserGetProp(pWnd
, gpsi
->atomIconSmProp
);
328 if (!hIcon
) hIcon
= UserGetProp(pWnd
, gpsi
->atomIconProp
);
329 if (!hIcon
) hIcon
= pWnd
->pcls
->hIconSm
;
330 if (!hIcon
) hIcon
= pWnd
->pcls
->hIcon
;
332 if (!hIcon
&& pWnd
->style
& DS_MODALFRAME
)
334 if (!hIcon
) hIcon
= gpsi
->hIconSmWindows
; // Both are IDI_WINLOGO Small
335 if (!hIcon
) hIcon
= gpsi
->hIconWindows
; // Reg size.
342 GetNCHitEx(PWND pWnd
, POINT pt
)
344 RECT rcWindow
, rcClient
;
345 DWORD Style
, ExStyle
;
347 if (!pWnd
) return HTNOWHERE
;
349 if (pWnd
== UserGetDesktopWindow()) // pWnd->fnid == FNID_DESKTOP)
351 rcClient
.left
= rcClient
.top
= rcWindow
.left
= rcWindow
.top
= 0;
352 rcWindow
.right
= UserGetSystemMetrics(SM_CXSCREEN
);
353 rcWindow
.bottom
= UserGetSystemMetrics(SM_CYSCREEN
);
354 rcClient
.right
= UserGetSystemMetrics(SM_CXSCREEN
);
355 rcClient
.bottom
= UserGetSystemMetrics(SM_CYSCREEN
);
359 rcClient
= pWnd
->rcClient
;
360 rcWindow
= pWnd
->rcWindow
;
363 if (!RECTL_bPointInRect(&rcWindow
, pt
.x
, pt
.y
)) return HTNOWHERE
;
366 ExStyle
= pWnd
->ExStyle
;
368 if (Style
& WS_MINIMIZE
) return HTCAPTION
;
370 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
)) return HTCLIENT
;
373 if (HAS_THICKFRAME( Style
, ExStyle
))
375 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXFRAME
), -UserGetSystemMetrics(SM_CYFRAME
) );
376 if (!RECTL_bPointInRect(&rcWindow
, pt
.x
, pt
.y
))
378 /* Check top sizing border */
379 if (pt
.y
< rcWindow
.top
)
381 if (pt
.x
< rcWindow
.left
+UserGetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
382 if (pt
.x
>= rcWindow
.right
-UserGetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
385 /* Check bottom sizing border */
386 if (pt
.y
>= rcWindow
.bottom
)
388 if (pt
.x
< rcWindow
.left
+UserGetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
389 if (pt
.x
>= rcWindow
.right
-UserGetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
392 /* Check left sizing border */
393 if (pt
.x
< rcWindow
.left
)
395 if (pt
.y
< rcWindow
.top
+UserGetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
396 if (pt
.y
>= rcWindow
.bottom
-UserGetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
399 /* Check right sizing border */
400 if (pt
.x
>= rcWindow
.right
)
402 if (pt
.y
< rcWindow
.top
+UserGetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
403 if (pt
.y
>= rcWindow
.bottom
-UserGetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
408 else /* No thick frame */
410 if (HAS_DLGFRAME( Style
, ExStyle
))
411 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXDLGFRAME
), -UserGetSystemMetrics(SM_CYDLGFRAME
));
412 else if (HAS_THINFRAME( Style
, ExStyle
))
413 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXBORDER
), -UserGetSystemMetrics(SM_CYBORDER
));
414 if (!RECTL_bPointInRect( &rcWindow
, pt
.x
, pt
.y
)) return HTBORDER
;
419 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
421 if (ExStyle
& WS_EX_TOOLWINDOW
)
422 rcWindow
.top
+= UserGetSystemMetrics(SM_CYSMCAPTION
) - 1;
424 rcWindow
.top
+= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
425 if (!RECTL_bPointInRect( &rcWindow
, pt
.x
, pt
.y
))
427 BOOL min_or_max_box
= (Style
& WS_SYSMENU
) && (Style
& (WS_MINIMIZEBOX
|WS_MAXIMIZEBOX
));
428 if (ExStyle
& WS_EX_LAYOUTRTL
)
430 /* Check system menu */
431 if ((Style
& WS_SYSMENU
) && !(ExStyle
& WS_EX_TOOLWINDOW
) && NC_IconForWindow(pWnd
))
433 rcWindow
.right
-= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
434 if (pt
.x
> rcWindow
.right
) return HTSYSMENU
;
437 /* Check close button */
438 if (Style
& WS_SYSMENU
)
440 rcWindow
.left
+= UserGetSystemMetrics(SM_CYCAPTION
);
441 if (pt
.x
< rcWindow
.left
) return HTCLOSE
;
444 /* Check maximize box */
445 /* In Win95 there is automatically a Maximize button when there is a minimize one */
446 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
448 rcWindow
.left
+= UserGetSystemMetrics(SM_CXSIZE
);
449 if (pt
.x
< rcWindow
.left
) return HTMAXBUTTON
;
452 /* Check minimize box */
453 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
455 rcWindow
.left
+= UserGetSystemMetrics(SM_CXSIZE
);
456 if (pt
.x
< rcWindow
.left
) return HTMINBUTTON
;
461 /* Check system menu */
462 if ((Style
& WS_SYSMENU
) && !(ExStyle
& WS_EX_TOOLWINDOW
) && NC_IconForWindow(pWnd
))
464 rcWindow
.left
+= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
465 if (pt
.x
< rcWindow
.left
) return HTSYSMENU
;
468 /* Check close button */
469 if (Style
& WS_SYSMENU
)
471 rcWindow
.right
-= UserGetSystemMetrics(SM_CYCAPTION
);
472 if (pt
.x
> rcWindow
.right
) return HTCLOSE
;
475 /* Check maximize box */
476 /* In Win95 there is automatically a Maximize button when there is a minimize one */
477 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
479 rcWindow
.right
-= UserGetSystemMetrics(SM_CXSIZE
);
480 if (pt
.x
> rcWindow
.right
) return HTMAXBUTTON
;
483 /* Check minimize box */
484 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
486 rcWindow
.right
-= UserGetSystemMetrics(SM_CXSIZE
);
487 if (pt
.x
> rcWindow
.right
) return HTMINBUTTON
;
496 if (HAS_MENU( pWnd
, Style
) && (pt
.y
< rcClient
.top
) &&
497 (pt
.x
>= rcClient
.left
) && (pt
.x
< rcClient
.right
))
500 /* Check vertical scroll bar */
502 if (ExStyle
& WS_EX_LAYOUTRTL
) ExStyle
^= WS_EX_LEFTSCROLLBAR
;
503 if (Style
& WS_VSCROLL
)
505 if((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
506 rcClient
.left
-= UserGetSystemMetrics(SM_CXVSCROLL
);
508 rcClient
.right
+= UserGetSystemMetrics(SM_CXVSCROLL
);
509 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
)) return HTVSCROLL
;
512 /* Check horizontal scroll bar */
514 if (Style
& WS_HSCROLL
)
516 rcClient
.bottom
+= UserGetSystemMetrics(SM_CYHSCROLL
);
517 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
))
520 if ((Style
& WS_VSCROLL
) &&
521 ((((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0) && (pt
.x
<= rcClient
.left
+ UserGetSystemMetrics(SM_CXVSCROLL
))) ||
522 (((ExStyle
& WS_EX_LEFTSCROLLBAR
) == 0) && (pt
.x
>= rcClient
.right
- UserGetSystemMetrics(SM_CXVSCROLL
)))))
528 /* Has to return HTNOWHERE if nothing was found
529 Could happen when a window has a customized non client area */