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
13 DBG_DEFAULT_CHANNEL(UserDefwnd
);
15 // Client Shutdown messages
16 #define MCS_SHUTDOWNTIMERS 1
17 #define MCS_QUERYENDSESSION 2
18 // Client Shutdown returns
19 #define MCSR_GOODFORSHUTDOWN 1
20 #define MCSR_SHUTDOWNFINISHED 2
21 #define MCSR_DONOTSHUTDOWN 3
24 * Based on CSRSS and described in pages 1115 - 1118 "Windows Internals, Fifth Edition".
25 * Apparently CSRSS sends out messages to do this w/o going into win32k internals.
38 LRESULT lResult
= MCSR_GOODFORSHUTDOWN
;
41 lParams
= wParam
& (ENDSESSION_LOGOFF
|ENDSESSION_CRITICAL
|ENDSESSION_CLOSEAPP
);
42 KillTimers
= wParam
& MCS_SHUTDOWNTIMERS
? TRUE
: FALSE
;
44 First, send end sessions to children.
46 List
= IntWinListChildren(pWindow
);
50 for (i
= 0; List
[i
]; i
++)
54 if (!(WndChild
= UserGetWindowObject(List
[i
])))
57 if (wParam
& MCS_QUERYENDSESSION
)
59 if (!co_IntSendMessage(WndChild
->head
.h
, WM_QUERYENDSESSION
, 0, lParams
))
61 lResult
= MCSR_DONOTSHUTDOWN
;
67 co_IntSendMessage(WndChild
->head
.h
, WM_ENDSESSION
, KillTimers
, lParams
);
70 DestroyTimersForWindow(WndChild
->head
.pti
, WndChild
);
72 lResult
= MCSR_SHUTDOWNFINISHED
;
75 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
77 if (List
&& (lResult
== MCSR_DONOTSHUTDOWN
)) return lResult
;
81 if (wParam
& MCS_QUERYENDSESSION
)
83 if (!co_IntSendMessage(pWindow
->head
.h
, WM_QUERYENDSESSION
, 0, lParams
))
85 lResult
= MCSR_DONOTSHUTDOWN
;
90 co_IntSendMessage(pWindow
->head
.h
, WM_ENDSESSION
, KillTimers
, lParams
);
93 DestroyTimersForWindow(pWindow
->head
.pti
, pWindow
);
95 lResult
= MCSR_SHUTDOWNFINISHED
;
101 DefWndControlColor(HDC hDC
, UINT ctlType
)
103 if (ctlType
== CTLCOLOR_SCROLLBAR
)
105 HBRUSH hb
= IntGetSysColorBrush(COLOR_SCROLLBAR
);
106 COLORREF bk
= IntGetSysColor(COLOR_3DHILIGHT
);
107 IntGdiSetTextColor(hDC
, IntGetSysColor(COLOR_3DFACE
));
108 IntGdiSetBkColor(hDC
, bk
);
110 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
111 * we better use 0x55aa bitmap brush to make scrollbar's background
112 * look different from the window background.
114 if ( bk
== IntGetSysColor(COLOR_WINDOW
))
115 return gpsi
->hbrGray
;
117 NtGdiUnrealizeObject( hb
);
121 IntGdiSetTextColor(hDC
, IntGetSysColor(COLOR_WINDOWTEXT
));
123 if ((ctlType
== CTLCOLOR_EDIT
) || (ctlType
== CTLCOLOR_LISTBOX
))
125 IntGdiSetBkColor(hDC
, IntGetSysColor(COLOR_WINDOW
));
129 IntGdiSetBkColor(hDC
, IntGetSysColor(COLOR_3DFACE
));
130 return IntGetSysColorBrush(COLOR_3DFACE
);
133 return IntGetSysColorBrush(COLOR_WINDOW
);
138 DefWndHandleSysCommand(PWND pWnd
, WPARAM wParam
, LPARAM lParam
)
143 if (ISITHOOKED(WH_CBT
) || (pWnd
->head
.rpdesk
->pDeskInfo
->fsHooks
& HOOKID_TO_FLAG(WH_CBT
)))
146 lResult
= co_HOOK_CallHooks(WH_CBT
, HCBT_SYSCOMMAND
, wParam
, lParam
);
148 if (lResult
) return lResult
;
151 switch (wParam
& 0xfff0)
154 ERR("Screensaver Called!\n");
155 UserPostMessage(hwndSAS
, WM_LOGONNOTIFY
, LN_START_SCREENSAVE
, 0); // always lParam 0 == not Secure
159 // We do not support anything else here so we should return normal even when sending a hook.
163 return(Hook
? 1 : 0); // Don't call us again from user space.
167 Win32k counterpart of User DefWindowProc
178 USER_REFERENCE_ENTRY Ref
;
180 if (Msg
> WM_USER
) return 0;
186 ERR("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd
->head
.h
, wParam
, lParam
);
187 lResult
= DefWndHandleSysCommand(Wnd
, wParam
, lParam
);
192 if ((Wnd
->style
& WS_VISIBLE
) && wParam
) break;
193 if (!(Wnd
->style
& WS_VISIBLE
) && !wParam
) break;
194 if (!Wnd
->spwndOwner
) break;
199 if (!(Wnd
->state
& WNDS_HIDDENPOPUP
)) break;
200 Wnd
->state
&= ~WNDS_HIDDENPOPUP
;
203 Wnd
->state
|= WNDS_HIDDENPOPUP
;
205 co_WinPosShowWindow(Wnd
, wParam
? SW_SHOWNOACTIVATE
: SW_HIDE
);
209 case WM_CLIENTSHUTDOWN
:
210 return IntClientShutdown(Wnd
, wParam
, lParam
);
213 ERR("WM_APPCOMMAND\n");
214 if ( (Wnd
->style
& (WS_POPUP
|WS_CHILD
)) != WS_CHILD
&&
215 Wnd
!= co_GetDesktopWindow(Wnd
) )
217 if (!co_HOOK_CallHooks(WH_SHELL
, HSHELL_APPCOMMAND
, wParam
, lParam
))
218 co_IntShellHookNotify(HSHELL_APPCOMMAND
, wParam
, lParam
);
221 UserRefObjectCo(Wnd
->spwndParent
, &Ref
);
222 lResult
= co_IntSendMessage(UserHMGetHandle(Wnd
->spwndParent
), WM_APPCOMMAND
, wParam
, lParam
);
223 UserDerefObjectCo(Wnd
->spwndParent
);
226 case WM_CTLCOLORMSGBOX
:
227 case WM_CTLCOLOREDIT
:
228 case WM_CTLCOLORLISTBOX
:
231 case WM_CTLCOLORSTATIC
:
232 case WM_CTLCOLORSCROLLBAR
:
233 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
236 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
239 return DefWndGetHotKey(Wnd
);
241 return DefWndSetHotKey(Wnd
, wParam
);
246 Point
.x
= GET_X_LPARAM(lParam
);
247 Point
.y
= GET_Y_LPARAM(lParam
);
248 return GetNCHitEx(Wnd
, Point
);
254 Wnd
->state
&= ~WNDS_SYNCPAINTPENDING
;
255 ERR("WM_SYNCPAINT\n");
256 hRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
257 if (co_UserGetUpdateRgn(Wnd
, hRgn
, FALSE
) != NULLREGION
)
259 if (!wParam
) wParam
= (RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
260 co_UserRedrawWindow(Wnd
, NULL
, hRgn
, wParam
);
262 GreDeleteObject(hRgn
);
269 if (!(Wnd
->style
& WS_VISIBLE
))
271 IntSetStyle( Wnd
, WS_VISIBLE
, 0 );
272 Wnd
->state
|= WNDS_SENDNCPAINT
;
277 if (Wnd
->style
& WS_VISIBLE
)
279 co_UserRedrawWindow( Wnd
, NULL
, NULL
, RDW_ALLCHILDREN
| RDW_VALIDATE
);
280 IntSetStyle( Wnd
, 0, WS_VISIBLE
);
298 ProbeForRead((PVOID
)lParam
,
306 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
313 lResult
= co_HOOK_CallHooks(WH_CBT
, HCBT_MOVESIZE
, (WPARAM
)Wnd
->head
.h
, lParam
? (LPARAM
)&rt
: 0);
324 HICON FASTCALL
NC_IconForWindow( PWND pWnd
)
327 // First thing to do, init the Window Logo icons.
328 if (!gpsi
->hIconSmWindows
) co_IntSetWndIcons();
330 if (!hIcon
) hIcon
= UserGetProp(pWnd
, gpsi
->atomIconSmProp
);
331 if (!hIcon
) hIcon
= UserGetProp(pWnd
, gpsi
->atomIconProp
);
332 if (!hIcon
) hIcon
= pWnd
->pcls
->hIconSm
;
333 if (!hIcon
) hIcon
= pWnd
->pcls
->hIcon
;
335 if (!hIcon
&& pWnd
->style
& DS_MODALFRAME
)
337 if (!hIcon
) hIcon
= gpsi
->hIconSmWindows
; // Both are IDI_WINLOGO Small
338 if (!hIcon
) hIcon
= gpsi
->hIconWindows
; // Reg size.
345 GetNCHitEx(PWND pWnd
, POINT pt
)
347 RECT rcWindow
, rcClient
;
348 DWORD Style
, ExStyle
;
350 if (!pWnd
) return HTNOWHERE
;
352 if (pWnd
== UserGetDesktopWindow()) // pWnd->fnid == FNID_DESKTOP)
354 rcClient
.left
= rcClient
.top
= rcWindow
.left
= rcWindow
.top
= 0;
355 rcWindow
.right
= UserGetSystemMetrics(SM_CXSCREEN
);
356 rcWindow
.bottom
= UserGetSystemMetrics(SM_CYSCREEN
);
357 rcClient
.right
= UserGetSystemMetrics(SM_CXSCREEN
);
358 rcClient
.bottom
= UserGetSystemMetrics(SM_CYSCREEN
);
362 rcClient
= pWnd
->rcClient
;
363 rcWindow
= pWnd
->rcWindow
;
366 if (!RECTL_bPointInRect(&rcWindow
, pt
.x
, pt
.y
)) return HTNOWHERE
;
369 ExStyle
= pWnd
->ExStyle
;
371 if (Style
& WS_MINIMIZE
) return HTCAPTION
;
373 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
)) return HTCLIENT
;
376 if (HAS_THICKFRAME( Style
, ExStyle
))
378 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXFRAME
), -UserGetSystemMetrics(SM_CYFRAME
) );
379 if (!RECTL_bPointInRect(&rcWindow
, pt
.x
, pt
.y
))
381 /* Check top sizing border */
382 if (pt
.y
< rcWindow
.top
)
384 if (pt
.x
< rcWindow
.left
+UserGetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
385 if (pt
.x
>= rcWindow
.right
-UserGetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
388 /* Check bottom sizing border */
389 if (pt
.y
>= rcWindow
.bottom
)
391 if (pt
.x
< rcWindow
.left
+UserGetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
392 if (pt
.x
>= rcWindow
.right
-UserGetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
395 /* Check left sizing border */
396 if (pt
.x
< rcWindow
.left
)
398 if (pt
.y
< rcWindow
.top
+UserGetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
399 if (pt
.y
>= rcWindow
.bottom
-UserGetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
402 /* Check right sizing border */
403 if (pt
.x
>= rcWindow
.right
)
405 if (pt
.y
< rcWindow
.top
+UserGetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
406 if (pt
.y
>= rcWindow
.bottom
-UserGetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
411 else /* No thick frame */
413 if (HAS_DLGFRAME( Style
, ExStyle
))
414 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXDLGFRAME
), -UserGetSystemMetrics(SM_CYDLGFRAME
));
415 else if (HAS_THINFRAME( Style
, ExStyle
))
416 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXBORDER
), -UserGetSystemMetrics(SM_CYBORDER
));
417 if (!RECTL_bPointInRect( &rcWindow
, pt
.x
, pt
.y
)) return HTBORDER
;
422 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
424 if (ExStyle
& WS_EX_TOOLWINDOW
)
425 rcWindow
.top
+= UserGetSystemMetrics(SM_CYSMCAPTION
) - 1;
427 rcWindow
.top
+= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
428 if (!RECTL_bPointInRect( &rcWindow
, pt
.x
, pt
.y
))
430 BOOL min_or_max_box
= (Style
& WS_SYSMENU
) && (Style
& (WS_MINIMIZEBOX
|WS_MAXIMIZEBOX
));
431 if (ExStyle
& WS_EX_LAYOUTRTL
)
433 /* Check system menu */
434 if ((Style
& WS_SYSMENU
) && !(ExStyle
& WS_EX_TOOLWINDOW
) && NC_IconForWindow(pWnd
))
436 rcWindow
.right
-= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
437 if (pt
.x
> rcWindow
.right
) return HTSYSMENU
;
440 /* Check close button */
441 if (Style
& WS_SYSMENU
)
443 rcWindow
.left
+= UserGetSystemMetrics(SM_CYCAPTION
);
444 if (pt
.x
< rcWindow
.left
) return HTCLOSE
;
447 /* Check maximize box */
448 /* In Win95 there is automatically a Maximize button when there is a minimize one */
449 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
451 rcWindow
.left
+= UserGetSystemMetrics(SM_CXSIZE
);
452 if (pt
.x
< rcWindow
.left
) return HTMAXBUTTON
;
455 /* Check minimize box */
456 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
458 rcWindow
.left
+= UserGetSystemMetrics(SM_CXSIZE
);
459 if (pt
.x
< rcWindow
.left
) return HTMINBUTTON
;
464 /* Check system menu */
465 if ((Style
& WS_SYSMENU
) && !(ExStyle
& WS_EX_TOOLWINDOW
) && NC_IconForWindow(pWnd
))
467 rcWindow
.left
+= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
468 if (pt
.x
< rcWindow
.left
) return HTSYSMENU
;
471 /* Check close button */
472 if (Style
& WS_SYSMENU
)
474 rcWindow
.right
-= UserGetSystemMetrics(SM_CYCAPTION
);
475 if (pt
.x
> rcWindow
.right
) return HTCLOSE
;
478 /* Check maximize box */
479 /* In Win95 there is automatically a Maximize button when there is a minimize one */
480 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
482 rcWindow
.right
-= UserGetSystemMetrics(SM_CXSIZE
);
483 if (pt
.x
> rcWindow
.right
) return HTMAXBUTTON
;
486 /* Check minimize box */
487 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
489 rcWindow
.right
-= UserGetSystemMetrics(SM_CXSIZE
);
490 if (pt
.x
> rcWindow
.right
) return HTMINBUTTON
;
499 if (HAS_MENU( pWnd
, Style
) && (pt
.y
< rcClient
.top
) &&
500 (pt
.x
>= rcClient
.left
) && (pt
.x
< rcClient
.right
))
503 /* Check vertical scroll bar */
505 if (ExStyle
& WS_EX_LAYOUTRTL
) ExStyle
^= WS_EX_LEFTSCROLLBAR
;
506 if (Style
& WS_VSCROLL
)
508 if((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
509 rcClient
.left
-= UserGetSystemMetrics(SM_CXVSCROLL
);
511 rcClient
.right
+= UserGetSystemMetrics(SM_CXVSCROLL
);
512 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
)) return HTVSCROLL
;
515 /* Check horizontal scroll bar */
517 if (Style
& WS_HSCROLL
)
519 rcClient
.bottom
+= UserGetSystemMetrics(SM_CYHSCROLL
);
520 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
))
523 if ((Style
& WS_VSCROLL
) &&
524 ((((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0) && (pt
.x
<= rcClient
.left
+ UserGetSystemMetrics(SM_CXVSCROLL
))) ||
525 (((ExStyle
& WS_EX_LEFTSCROLLBAR
) == 0) && (pt
.x
>= rcClient
.right
- UserGetSystemMetrics(SM_CXVSCROLL
)))))
531 /* Has to return HTNOWHERE if nothing was found
532 Could happen when a window has a customized non client area */