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
;
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
176 if (Msg
> WM_USER
) return 0;
182 ERR("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd
->head
.h
, wParam
, lParam
);
183 lResult
= DefWndHandleSysCommand(Wnd
, wParam
, lParam
);
188 if ((Wnd
->style
& WS_VISIBLE
) && wParam
) break;
189 if (!(Wnd
->style
& WS_VISIBLE
) && !wParam
) break;
190 if (!Wnd
->spwndOwner
) break;
195 if (!(Wnd
->state
& WNDS_HIDDENPOPUP
)) break;
196 Wnd
->state
&= ~WNDS_HIDDENPOPUP
;
199 Wnd
->state
|= WNDS_HIDDENPOPUP
;
201 co_WinPosShowWindow(Wnd
, wParam
? SW_SHOWNOACTIVATE
: SW_HIDE
);
205 case WM_CLIENTSHUTDOWN
:
206 return IntClientShutdown(Wnd
, wParam
, lParam
);
208 case WM_CTLCOLORMSGBOX
:
209 case WM_CTLCOLOREDIT
:
210 case WM_CTLCOLORLISTBOX
:
213 case WM_CTLCOLORSTATIC
:
214 case WM_CTLCOLORSCROLLBAR
:
215 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
218 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
221 return DefWndGetHotKey(UserHMGetHandle(Wnd
));
223 return DefWndSetHotKey(Wnd
, wParam
);
228 Point
.x
= GET_X_LPARAM(lParam
);
229 Point
.y
= GET_Y_LPARAM(lParam
);
230 return GetNCHitEx(Wnd
, Point
);
246 ProbeForRead((PVOID
)lParam
,
254 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
261 lResult
= co_HOOK_CallHooks(WH_CBT
, HCBT_MOVESIZE
, (WPARAM
)Wnd
->head
.h
, lParam
? (LPARAM
)&rt
: 0);
272 static HICON
NC_IconForWindow( PWND pWnd
)
276 if (!pWnd
->pcls
|| pWnd
->fnid
== FNID_DESKTOP
) return hIcon
;
277 if (!hIcon
) hIcon
= pWnd
->pcls
->hIconSm
;
278 if (!hIcon
) hIcon
= pWnd
->pcls
->hIcon
;
280 if (!hIcon
&& pWnd
->style
& DS_MODALFRAME
)
281 { // Fake it out for now, we use it as a test.
283 /* FIXME: Need to setup Registry System Cursor & Icons via Callbacks at init time! */
284 if (!hIcon
) hIcon
= gpsi
->hIconSmWindows
; // Both are IDI_WINLOGO Small
285 if (!hIcon
) hIcon
= gpsi
->hIcoWindows
; // Reg size.
291 GetNCHitEx(PWND pWnd
, POINT pt
)
293 RECT rcWindow
, rcClient
;
294 DWORD Style
, ExStyle
;
296 if (!pWnd
) return HTNOWHERE
;
298 if (pWnd
== UserGetDesktopWindow()) // pWnd->fnid == FNID_DESKTOP)
300 rcClient
.left
= rcClient
.top
= rcWindow
.left
= rcWindow
.top
= 0;
301 rcWindow
.right
= UserGetSystemMetrics(SM_CXSCREEN
);
302 rcWindow
.bottom
= UserGetSystemMetrics(SM_CYSCREEN
);
303 rcClient
.right
= UserGetSystemMetrics(SM_CXSCREEN
);
304 rcClient
.bottom
= UserGetSystemMetrics(SM_CYSCREEN
);
308 rcClient
= pWnd
->rcClient
;
309 rcWindow
= pWnd
->rcWindow
;
312 if (!RECTL_bPointInRect(&rcWindow
, pt
.x
, pt
.y
)) return HTNOWHERE
;
315 ExStyle
= pWnd
->ExStyle
;
317 if (Style
& WS_MINIMIZE
) return HTCAPTION
;
319 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
)) return HTCLIENT
;
322 if (HAS_THICKFRAME( Style
, ExStyle
))
324 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXFRAME
), -UserGetSystemMetrics(SM_CYFRAME
) );
325 if (!RECTL_bPointInRect(&rcWindow
, pt
.x
, pt
.y
))
327 /* Check top sizing border */
328 if (pt
.y
< rcWindow
.top
)
330 if (pt
.x
< rcWindow
.left
+UserGetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
331 if (pt
.x
>= rcWindow
.right
-UserGetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
334 /* Check bottom sizing border */
335 if (pt
.y
>= rcWindow
.bottom
)
337 if (pt
.x
< rcWindow
.left
+UserGetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
338 if (pt
.x
>= rcWindow
.right
-UserGetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
341 /* Check left sizing border */
342 if (pt
.x
< rcWindow
.left
)
344 if (pt
.y
< rcWindow
.top
+UserGetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
345 if (pt
.y
>= rcWindow
.bottom
-UserGetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
348 /* Check right sizing border */
349 if (pt
.x
>= rcWindow
.right
)
351 if (pt
.y
< rcWindow
.top
+UserGetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
352 if (pt
.y
>= rcWindow
.bottom
-UserGetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
357 else /* No thick frame */
359 if (HAS_DLGFRAME( Style
, ExStyle
))
360 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXDLGFRAME
), -UserGetSystemMetrics(SM_CYDLGFRAME
));
361 else if (HAS_THINFRAME( Style
, ExStyle
))
362 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXBORDER
), -UserGetSystemMetrics(SM_CYBORDER
));
363 if (!RECTL_bPointInRect( &rcWindow
, pt
.x
, pt
.y
)) return HTBORDER
;
368 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
370 if (ExStyle
& WS_EX_TOOLWINDOW
)
371 rcWindow
.top
+= UserGetSystemMetrics(SM_CYSMCAPTION
) - 1;
373 rcWindow
.top
+= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
374 if (!RECTL_bPointInRect( &rcWindow
, pt
.x
, pt
.y
))
376 BOOL min_or_max_box
= (Style
& WS_MAXIMIZEBOX
) ||
377 (Style
& WS_MINIMIZEBOX
);
378 if (ExStyle
& WS_EX_LAYOUTRTL
)
380 /* Check system menu */
381 if ((Style
& WS_SYSMENU
) && !(ExStyle
& WS_EX_TOOLWINDOW
) && NC_IconForWindow(pWnd
))
383 rcWindow
.right
-= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
384 if (pt
.x
> rcWindow
.right
) return HTSYSMENU
;
387 /* Check close button */
388 if (Style
& WS_SYSMENU
)
390 rcWindow
.left
+= UserGetSystemMetrics(SM_CYCAPTION
);
391 if (pt
.x
< rcWindow
.left
) return HTCLOSE
;
394 /* Check maximize box */
395 /* In Win95 there is automatically a Maximize button when there is a minimize one */
396 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
398 rcWindow
.left
+= UserGetSystemMetrics(SM_CXSIZE
);
399 if (pt
.x
< rcWindow
.left
) return HTMAXBUTTON
;
402 /* Check minimize box */
403 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
405 rcWindow
.left
+= UserGetSystemMetrics(SM_CXSIZE
);
406 if (pt
.x
< rcWindow
.left
) return HTMINBUTTON
;
411 /* Check system menu */
412 if ((Style
& WS_SYSMENU
) && !(ExStyle
& WS_EX_TOOLWINDOW
) && NC_IconForWindow(pWnd
))
414 rcWindow
.left
+= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
415 if (pt
.x
< rcWindow
.left
) return HTSYSMENU
;
418 /* Check close button */
419 if (Style
& WS_SYSMENU
)
421 rcWindow
.right
-= UserGetSystemMetrics(SM_CYCAPTION
);
422 if (pt
.x
> rcWindow
.right
) return HTCLOSE
;
425 /* Check maximize box */
426 /* In Win95 there is automatically a Maximize button when there is a minimize one */
427 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
429 rcWindow
.right
-= UserGetSystemMetrics(SM_CXSIZE
);
430 if (pt
.x
> rcWindow
.right
) return HTMAXBUTTON
;
433 /* Check minimize box */
434 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
436 rcWindow
.right
-= UserGetSystemMetrics(SM_CXSIZE
);
437 if (pt
.x
> rcWindow
.right
) return HTMINBUTTON
;
446 if (HAS_MENU( pWnd
, Style
) && (pt
.y
< rcClient
.top
) &&
447 (pt
.x
>= rcClient
.left
) && (pt
.x
< rcClient
.right
))
450 /* Check vertical scroll bar */
452 if (ExStyle
& WS_EX_LAYOUTRTL
) ExStyle
^= WS_EX_LEFTSCROLLBAR
;
453 if (Style
& WS_VSCROLL
)
455 if((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
456 rcClient
.left
-= UserGetSystemMetrics(SM_CXVSCROLL
);
458 rcClient
.right
+= UserGetSystemMetrics(SM_CXVSCROLL
);
459 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
)) return HTVSCROLL
;
462 /* Check horizontal scroll bar */
464 if (Style
& WS_HSCROLL
)
466 rcClient
.bottom
+= UserGetSystemMetrics(SM_CYHSCROLL
);
467 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
))
470 if ((Style
& WS_VSCROLL
) &&
471 ((((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0) && (pt
.x
<= rcClient
.left
+ UserGetSystemMetrics(SM_CXVSCROLL
))) ||
472 (((ExStyle
& WS_EX_LEFTSCROLLBAR
) == 0) && (pt
.x
>= rcClient
.right
- UserGetSystemMetrics(SM_CXVSCROLL
)))))
478 /* Has to return HTNOWHERE if nothing was found
479 Could happen when a window has a customized non client area */