2 * win32ss/user/win32csr/desktopbg.c
4 * Desktop background window functions
6 * ReactOS Operating System
8 * Looks as a hax fix to a problem of not having a proper class window proc support
9 * which ReactOS has now.
11 * Notes on reason why this is here:
12 * http://www.reactos.org/archives/public/ros-kernel/2003-November/000538.html
13 * http://www.reactos.org/archives/public/ros-kernel/2003-November/000545.html
14 * http://www.reactos.org/archives/public/ros-kernel/2003-November/000586.html
15 * http://www.reactos.org/archives/public/ros-kernel/2003-November/000674.html
16 * Revision 6908 Move desktop window proc from WIN32K to CSRSS
19 * http://www.reactos.org/archives/public/ros-kernel/2003-December/001186.html
22 Now this is used to start Desktops Threads with TEB support.
23 These first three are Application, Winlogon and ScreenSaver desktops.
32 #define DESKTOP_WINDOW_ATOM 32769
34 #define PM_SHOW_DESKTOP 1
35 #define PM_HIDE_DESKTOP 2
37 typedef struct tagDTBG_THREAD_DATA
42 } DTBG_THREAD_DATA
, *PDTBG_THREAD_DATA
;
44 typedef struct tagPRIVATE_NOTIFY_DESKTOP
47 struct /* PM_SHOW_DESKTOP */
52 } PRIVATE_NOTIFY_DESKTOP
, *PPRIVATE_NOTIFY_DESKTOP
;
54 static BOOL BgInitialized
= FALSE
;
55 static HWND VisibleDesktopWindow
= NULL
;
60 DtbgWindowProc(HWND Wnd
,
70 PaintDesktop((HDC
)wParam
);
74 if (BeginPaint(Wnd
, &PS
))
79 return (LRESULT
)SetCursor(LoadCursorW(0, (LPCWSTR
)IDC_ARROW
));
85 NtUserSetWindowFNID(Wnd
, FNID_DESKTOP
); // Anti-ReactOS hack!
89 case WM_DISPLAYCHANGE
:
90 MoveWindow(Wnd
, 0, 0, LOWORD(lParam
), HIWORD(lParam
), TRUE
);
95 PPRIVATE_NOTIFY_DESKTOP nmh
= (PPRIVATE_NOTIFY_DESKTOP
)lParam
;
97 /* Use WM_NOTIFY for private messages since
98 * it can't be sent between processes!
100 switch (nmh
->hdr
.code
)
102 case PM_SHOW_DESKTOP
:
106 Result
= !SetWindowPos(Wnd
, NULL
, 0, 0,
107 nmh
->ShowDesktop
.Width
,
108 nmh
->ShowDesktop
.Height
,
109 SWP_NOACTIVATE
| SWP_NOZORDER
|
113 VisibleDesktopWindow
= Wnd
;
117 case PM_HIDE_DESKTOP
:
121 Result
= !SetWindowPos(Wnd
, NULL
, 0, 0, 0, 0,
122 SWP_NOACTIVATE
| SWP_NOZORDER
|
123 SWP_NOMOVE
| SWP_NOSIZE
| SWP_HIDEWINDOW
);
126 VisibleDesktopWindow
= NULL
;
131 DPRINT("Unknown notification code 0x%x sent to the desktop window!\n",
138 return DefWindowProcW(Wnd
, Msg
, wParam
, lParam
);
153 * Create the desktop window class
155 Class
.cbSize
= sizeof(WNDCLASSEXW
);
156 Class
.style
= 0; // Local Class
157 Class
.lpfnWndProc
= DtbgWindowProc
;
158 Class
.cbClsExtra
= 0;
159 Class
.cbWndExtra
= 0;
160 Class
.hInstance
= (HINSTANCE
)GetModuleHandleW(NULL
);
162 Class
.hCursor
= NULL
;
163 Class
.hbrBackground
= GetSysColorBrush(COLOR_BACKGROUND
);
164 Class
.lpszMenuName
= NULL
;
165 Class
.lpszClassName
= (LPCWSTR
)DESKTOP_WINDOW_ATOM
;
166 ClassAtom
= RegisterClassExW(&Class
);
168 if (ClassAtom
== INVALID_ATOM
)
170 DPRINT1("Unable to register desktop background class (error %d)\n",
176 VisibleDesktopWindow
= NULL
;
184 DtbgDesktopThread(PVOID Data
)
188 PDTBG_THREAD_DATA ThreadData
= (PDTBG_THREAD_DATA
)Data
;
190 DPRINT("DtbgDesktopThread\n");
192 if (!SetThreadDesktop(ThreadData
->Desktop
))
194 DPRINT1("Failed to set thread desktop\n");
195 ThreadData
->Status
= STATUS_UNSUCCESSFUL
;
196 SetEvent(ThreadData
->Event
);
200 BackgroundWnd
= CreateWindowW((LPCWSTR
)DESKTOP_WINDOW_ATOM
,
202 WS_POPUP
| WS_CLIPCHILDREN
,
203 GetSystemMetrics(SM_XVIRTUALSCREEN
),
204 GetSystemMetrics(SM_YVIRTUALSCREEN
),
205 GetSystemMetrics(SM_CXVIRTUALSCREEN
),
206 GetSystemMetrics(SM_CYVIRTUALSCREEN
),
208 (HINSTANCE
)GetModuleHandleW(L
"user32.dll"), // Run in win32k/user32.
211 if (NULL
== BackgroundWnd
)
213 DPRINT1("Failed to create desktop background window\n");
214 ThreadData
->Status
= STATUS_UNSUCCESSFUL
;
215 SetEvent(ThreadData
->Event
);
219 DPRINT("BackgroundWnd 0x%p\n",BackgroundWnd
);
221 ThreadData
->Status
= STATUS_SUCCESS
;
222 SetEvent(ThreadData
->Event
);
224 while (GetMessageW(&msg
, NULL
, 0, 0))
226 if (msg
.message
== WM_QUIT
)
228 DPRINT1("DtbgDesktopThread WM_QUIT\n");
230 TranslateMessage(&msg
);
231 DispatchMessageW(&msg
);
234 DPRINT1("DtbgDesktopThread Exit\n");
238 CSR_API(CsrCreateDesktop
)
240 DTBG_THREAD_DATA ThreadData
;
243 DPRINT("CsrCreateDesktop\n");
247 BgInitialized
= TRUE
;
250 // return STATUS_UNSUCCESSFUL;
254 * The desktop handle we got from win32k is in
255 * the scope of CSRSS so we can just use it.
257 ThreadData
.Desktop
= Request
->Data
.CreateDesktopRequest
.DesktopHandle
;
259 ThreadData
.Event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
261 if (NULL
== ThreadData
.Event
)
263 DPRINT1("Failed to create event (error %d)\n", GetLastError());
264 return STATUS_UNSUCCESSFUL
;
267 ThreadHandle
= CreateThread(NULL
,
274 if (NULL
== ThreadHandle
)
276 CloseHandle(ThreadData
.Event
);
277 DPRINT1("Failed to create desktop window thread.\n");
278 return STATUS_UNSUCCESSFUL
;
281 CloseHandle(ThreadHandle
);
283 WaitForSingleObject(ThreadData
.Event
, INFINITE
);
284 CloseHandle(ThreadData
.Event
);
286 return ThreadData
.Status
;
289 CSR_API(CsrShowDesktop
)
292 PRIVATE_NOTIFY_DESKTOP nmh
;
293 DPRINT("CsrShowDesktop\n");
295 nmh
.hdr
.hwndFrom
= Request
->Data
.ShowDesktopRequest
.DesktopWindow
;
297 nmh
.hdr
.code
= PM_SHOW_DESKTOP
;
299 nmh
.ShowDesktop
.Width
= (int)Request
->Data
.ShowDesktopRequest
.Width
;
300 nmh
.ShowDesktop
.Height
= (int)Request
->Data
.ShowDesktopRequest
.Height
;
302 if (SendMessageW(Request
->Data
.ShowDesktopRequest
.DesktopWindow
,
304 (WPARAM
)nmh
.hdr
.hwndFrom
,
307 return STATUS_UNSUCCESSFUL
;
310 return STATUS_SUCCESS
;
313 CSR_API(CsrHideDesktop
)
316 PRIVATE_NOTIFY_DESKTOP nmh
;
317 DPRINT("CsrHideDesktop\n");
319 nmh
.hdr
.hwndFrom
= Request
->Data
.ShowDesktopRequest
.DesktopWindow
;
321 nmh
.hdr
.code
= PM_HIDE_DESKTOP
;
323 if (SendMessageW(Request
->Data
.ShowDesktopRequest
.DesktopWindow
,
325 (WPARAM
)nmh
.hdr
.hwndFrom
,
328 return STATUS_UNSUCCESSFUL
;
331 return STATUS_SUCCESS
;
336 DtbgIsDesktopVisible(VOID
)
338 VisibleDesktopWindow
= GetDesktopWindow(); // DESKTOPWNDPROC
340 if (VisibleDesktopWindow
!= NULL
&&
341 !IsWindowVisible(VisibleDesktopWindow
))
343 VisibleDesktopWindow
= NULL
;
346 return VisibleDesktopWindow
!= NULL
;