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
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
);
236 Wnd
->state
&= ~WNDS_SYNCPAINTPENDING
;
237 ERR("WM_SYNCPAINT\n");
238 hRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
239 if (co_UserGetUpdateRgn(Wnd
, hRgn
, FALSE
) != NULLREGION
)
241 if (!wParam
) wParam
= (RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
242 co_UserRedrawWindow(Wnd
, NULL
, hRgn
, wParam
);
244 GreDeleteObject(hRgn
);
251 if (!(Wnd
->style
& WS_VISIBLE
))
253 IntSetStyle( Wnd
, WS_VISIBLE
, 0 );
254 Wnd
->state
|= WNDS_SENDNCPAINT
;
259 if (Wnd
->style
& WS_VISIBLE
)
261 co_UserRedrawWindow( Wnd
, NULL
, NULL
, RDW_ALLCHILDREN
| RDW_VALIDATE
);
262 IntSetStyle( Wnd
, 0, WS_VISIBLE
);
280 ProbeForRead((PVOID
)lParam
,
288 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
295 lResult
= co_HOOK_CallHooks(WH_CBT
, HCBT_MOVESIZE
, (WPARAM
)Wnd
->head
.h
, lParam
? (LPARAM
)&rt
: 0);
306 static HICON
NC_IconForWindow( PWND pWnd
)
310 if (!pWnd
->pcls
|| pWnd
->fnid
== FNID_DESKTOP
) return hIcon
;
311 if (!hIcon
) hIcon
= pWnd
->pcls
->hIconSm
;
312 if (!hIcon
) hIcon
= pWnd
->pcls
->hIcon
;
314 if (!hIcon
&& pWnd
->style
& DS_MODALFRAME
)
315 { // Fake it out for now, we use it as a test.
317 /* FIXME: Need to setup Registry System Cursor & Icons via Callbacks at init time! */
318 if (!hIcon
) hIcon
= gpsi
->hIconSmWindows
; // Both are IDI_WINLOGO Small
319 if (!hIcon
) hIcon
= gpsi
->hIcoWindows
; // Reg size.
325 GetNCHitEx(PWND pWnd
, POINT pt
)
327 RECT rcWindow
, rcClient
;
328 DWORD Style
, ExStyle
;
330 if (!pWnd
) return HTNOWHERE
;
332 if (pWnd
== UserGetDesktopWindow()) // pWnd->fnid == FNID_DESKTOP)
334 rcClient
.left
= rcClient
.top
= rcWindow
.left
= rcWindow
.top
= 0;
335 rcWindow
.right
= UserGetSystemMetrics(SM_CXSCREEN
);
336 rcWindow
.bottom
= UserGetSystemMetrics(SM_CYSCREEN
);
337 rcClient
.right
= UserGetSystemMetrics(SM_CXSCREEN
);
338 rcClient
.bottom
= UserGetSystemMetrics(SM_CYSCREEN
);
342 rcClient
= pWnd
->rcClient
;
343 rcWindow
= pWnd
->rcWindow
;
346 if (!RECTL_bPointInRect(&rcWindow
, pt
.x
, pt
.y
)) return HTNOWHERE
;
349 ExStyle
= pWnd
->ExStyle
;
351 if (Style
& WS_MINIMIZE
) return HTCAPTION
;
353 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
)) return HTCLIENT
;
356 if (HAS_THICKFRAME( Style
, ExStyle
))
358 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXFRAME
), -UserGetSystemMetrics(SM_CYFRAME
) );
359 if (!RECTL_bPointInRect(&rcWindow
, pt
.x
, pt
.y
))
361 /* Check top sizing border */
362 if (pt
.y
< rcWindow
.top
)
364 if (pt
.x
< rcWindow
.left
+UserGetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
365 if (pt
.x
>= rcWindow
.right
-UserGetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
368 /* Check bottom sizing border */
369 if (pt
.y
>= rcWindow
.bottom
)
371 if (pt
.x
< rcWindow
.left
+UserGetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
372 if (pt
.x
>= rcWindow
.right
-UserGetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
375 /* Check left sizing border */
376 if (pt
.x
< rcWindow
.left
)
378 if (pt
.y
< rcWindow
.top
+UserGetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
379 if (pt
.y
>= rcWindow
.bottom
-UserGetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
382 /* Check right sizing border */
383 if (pt
.x
>= rcWindow
.right
)
385 if (pt
.y
< rcWindow
.top
+UserGetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
386 if (pt
.y
>= rcWindow
.bottom
-UserGetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
391 else /* No thick frame */
393 if (HAS_DLGFRAME( Style
, ExStyle
))
394 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXDLGFRAME
), -UserGetSystemMetrics(SM_CYDLGFRAME
));
395 else if (HAS_THINFRAME( Style
, ExStyle
))
396 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXBORDER
), -UserGetSystemMetrics(SM_CYBORDER
));
397 if (!RECTL_bPointInRect( &rcWindow
, pt
.x
, pt
.y
)) return HTBORDER
;
402 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
404 if (ExStyle
& WS_EX_TOOLWINDOW
)
405 rcWindow
.top
+= UserGetSystemMetrics(SM_CYSMCAPTION
) - 1;
407 rcWindow
.top
+= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
408 if (!RECTL_bPointInRect( &rcWindow
, pt
.x
, pt
.y
))
410 BOOL min_or_max_box
= (Style
& WS_SYSMENU
) && (Style
& (WS_MINIMIZEBOX
|WS_MAXIMIZEBOX
));
411 if (ExStyle
& WS_EX_LAYOUTRTL
)
413 /* Check system menu */
414 if ((Style
& WS_SYSMENU
) && !(ExStyle
& WS_EX_TOOLWINDOW
) && NC_IconForWindow(pWnd
))
416 rcWindow
.right
-= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
417 if (pt
.x
> rcWindow
.right
) return HTSYSMENU
;
420 /* Check close button */
421 if (Style
& WS_SYSMENU
)
423 rcWindow
.left
+= UserGetSystemMetrics(SM_CYCAPTION
);
424 if (pt
.x
< rcWindow
.left
) return HTCLOSE
;
427 /* Check maximize box */
428 /* In Win95 there is automatically a Maximize button when there is a minimize one */
429 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
431 rcWindow
.left
+= UserGetSystemMetrics(SM_CXSIZE
);
432 if (pt
.x
< rcWindow
.left
) return HTMAXBUTTON
;
435 /* Check minimize box */
436 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
438 rcWindow
.left
+= UserGetSystemMetrics(SM_CXSIZE
);
439 if (pt
.x
< rcWindow
.left
) return HTMINBUTTON
;
444 /* Check system menu */
445 if ((Style
& WS_SYSMENU
) && !(ExStyle
& WS_EX_TOOLWINDOW
) && NC_IconForWindow(pWnd
))
447 rcWindow
.left
+= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
448 if (pt
.x
< rcWindow
.left
) return HTSYSMENU
;
451 /* Check close button */
452 if (Style
& WS_SYSMENU
)
454 rcWindow
.right
-= UserGetSystemMetrics(SM_CYCAPTION
);
455 if (pt
.x
> rcWindow
.right
) return HTCLOSE
;
458 /* Check maximize box */
459 /* In Win95 there is automatically a Maximize button when there is a minimize one */
460 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
462 rcWindow
.right
-= UserGetSystemMetrics(SM_CXSIZE
);
463 if (pt
.x
> rcWindow
.right
) return HTMAXBUTTON
;
466 /* Check minimize box */
467 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
469 rcWindow
.right
-= UserGetSystemMetrics(SM_CXSIZE
);
470 if (pt
.x
> rcWindow
.right
) return HTMINBUTTON
;
479 if (HAS_MENU( pWnd
, Style
) && (pt
.y
< rcClient
.top
) &&
480 (pt
.x
>= rcClient
.left
) && (pt
.x
< rcClient
.right
))
483 /* Check vertical scroll bar */
485 if (ExStyle
& WS_EX_LAYOUTRTL
) ExStyle
^= WS_EX_LEFTSCROLLBAR
;
486 if (Style
& WS_VSCROLL
)
488 if((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
489 rcClient
.left
-= UserGetSystemMetrics(SM_CXVSCROLL
);
491 rcClient
.right
+= UserGetSystemMetrics(SM_CXVSCROLL
);
492 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
)) return HTVSCROLL
;
495 /* Check horizontal scroll bar */
497 if (Style
& WS_HSCROLL
)
499 rcClient
.bottom
+= UserGetSystemMetrics(SM_CYHSCROLL
);
500 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
))
503 if ((Style
& WS_VSCROLL
) &&
504 ((((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0) && (pt
.x
<= rcClient
.left
+ UserGetSystemMetrics(SM_CXVSCROLL
))) ||
505 (((ExStyle
& WS_EX_LEFTSCROLLBAR
) == 0) && (pt
.x
>= rcClient
.right
- UserGetSystemMetrics(SM_CXVSCROLL
)))))
511 /* Has to return HTNOWHERE if nothing was found
512 Could happen when a window has a customized non client area */