3 * reactos/subsys/csrss/win32csr/desktopbg.c
5 * Desktop background window functions
7 * ReactOS Operating System
15 #define DESKTOP_WINDOW_ATOM 32769
17 #define PM_SHOW_DESKTOP 1
18 #define PM_HIDE_DESKTOP 2
20 typedef struct tagDTBG_THREAD_DATA
25 } DTBG_THREAD_DATA
, *PDTBG_THREAD_DATA
;
27 typedef struct tagPRIVATE_NOTIFY_DESKTOP
30 struct /* PM_SHOW_DESKTOP */
35 } PRIVATE_NOTIFY_DESKTOP
, *PPRIVATE_NOTIFY_DESKTOP
;
37 static BOOL BgInitialized
= FALSE
;
38 static HWND VisibleDesktopWindow
= NULL
;
43 DtbgWindowProc(HWND Wnd
,
53 PaintDesktop((HDC
)wParam
);
57 if (BeginPaint(Wnd
, &PS
))
62 return (LRESULT
)SetCursor(LoadCursorW(0, (LPCWSTR
)IDC_ARROW
));
68 NtUserSetWindowFNID(Wnd
, FNID_DESKTOP
); // Anti-ReactOS hack!
72 case WM_DISPLAYCHANGE
:
73 MoveWindow(Wnd
, 0, 0, LOWORD(lParam
), HIWORD(lParam
), TRUE
);
78 PPRIVATE_NOTIFY_DESKTOP nmh
= (PPRIVATE_NOTIFY_DESKTOP
)lParam
;
80 /* Use WM_NOTIFY for private messages since
81 * it can't be sent between processes!
83 switch (nmh
->hdr
.code
)
89 Result
= !SetWindowPos(Wnd
, NULL
, 0, 0,
90 nmh
->ShowDesktop
.Width
,
91 nmh
->ShowDesktop
.Height
,
92 SWP_NOACTIVATE
| SWP_NOZORDER
|
96 VisibleDesktopWindow
= Wnd
;
100 case PM_HIDE_DESKTOP
:
104 Result
= !SetWindowPos(Wnd
, NULL
, 0, 0, 0, 0,
105 SWP_NOACTIVATE
| SWP_NOZORDER
|
106 SWP_NOMOVE
| SWP_NOSIZE
| SWP_HIDEWINDOW
);
109 VisibleDesktopWindow
= NULL
;
114 DPRINT("Unknown notification code 0x%x sent to the desktop window!\n",
121 return DefWindowProcW(Wnd
, Msg
, wParam
, lParam
);
136 * Create the desktop window class
138 Class
.cbSize
= sizeof(WNDCLASSEXW
);
139 Class
.style
= CS_GLOBALCLASS
;
140 Class
.lpfnWndProc
= DtbgWindowProc
;
141 Class
.cbClsExtra
= 0;
142 Class
.cbWndExtra
= 0;
143 Class
.hInstance
= (HINSTANCE
)GetModuleHandleW(NULL
);
145 Class
.hCursor
= NULL
;
146 Class
.hbrBackground
= GetSysColorBrush(COLOR_BACKGROUND
);
147 Class
.lpszMenuName
= NULL
;
148 Class
.lpszClassName
= (LPCWSTR
)DESKTOP_WINDOW_ATOM
;
149 ClassAtom
= RegisterClassExW(&Class
);
151 if (ClassAtom
== INVALID_ATOM
)
153 DPRINT1("Unable to register desktop background class (error %d)\n",
159 VisibleDesktopWindow
= NULL
;
167 DtbgDesktopThread(PVOID Data
)
171 PDTBG_THREAD_DATA ThreadData
= (PDTBG_THREAD_DATA
)Data
;
173 if (!SetThreadDesktop(ThreadData
->Desktop
))
175 DPRINT1("Failed to set thread desktop\n");
176 ThreadData
->Status
= STATUS_UNSUCCESSFUL
;
177 SetEvent(ThreadData
->Event
);
181 BackgroundWnd
= CreateWindowW((LPCWSTR
)DESKTOP_WINDOW_ATOM
,
183 WS_POPUP
| WS_CLIPCHILDREN
,
186 (HINSTANCE
)GetModuleHandleW(NULL
),
189 if (NULL
== BackgroundWnd
)
191 DPRINT1("Failed to create desktop background window\n");
192 ThreadData
->Status
= STATUS_UNSUCCESSFUL
;
193 SetEvent(ThreadData
->Event
);
197 ThreadData
->Status
= STATUS_SUCCESS
;
198 SetEvent(ThreadData
->Event
);
200 while (GetMessageW(&msg
, NULL
, 0, 0))
202 TranslateMessage(&msg
);
203 DispatchMessageW(&msg
);
209 CSR_API(CsrCreateDesktop
)
211 DTBG_THREAD_DATA ThreadData
;
214 DPRINT("CsrCreateDesktop\n");
216 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
217 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
221 BgInitialized
= TRUE
;
224 return STATUS_UNSUCCESSFUL
;
228 * The desktop handle we got from win32k is in
229 * the scope of CSRSS so we can just use it.
231 ThreadData
.Desktop
= Request
->Data
.CreateDesktopRequest
.DesktopHandle
;
233 ThreadData
.Event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
235 if (NULL
== ThreadData
.Event
)
237 DPRINT1("Failed to create event (error %d)\n", GetLastError());
238 return STATUS_UNSUCCESSFUL
;
241 ThreadHandle
= CreateThread(NULL
,
248 if (NULL
== ThreadHandle
)
250 CloseHandle(ThreadData
.Event
);
251 DPRINT1("Failed to create desktop window thread.\n");
252 return STATUS_UNSUCCESSFUL
;
255 CloseHandle(ThreadHandle
);
257 WaitForSingleObject(ThreadData
.Event
, INFINITE
);
258 CloseHandle(ThreadData
.Event
);
260 return ThreadData
.Status
;
263 CSR_API(CsrShowDesktop
)
265 PRIVATE_NOTIFY_DESKTOP nmh
;
266 DPRINT("CsrShowDesktop\n");
268 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
269 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
271 nmh
.hdr
.hwndFrom
= Request
->Data
.ShowDesktopRequest
.DesktopWindow
;
273 nmh
.hdr
.code
= PM_SHOW_DESKTOP
;
275 nmh
.ShowDesktop
.Width
= (int)Request
->Data
.ShowDesktopRequest
.Width
;
276 nmh
.ShowDesktop
.Height
= (int)Request
->Data
.ShowDesktopRequest
.Height
;
278 if (SendMessageW(Request
->Data
.ShowDesktopRequest
.DesktopWindow
,
280 (WPARAM
)nmh
.hdr
.hwndFrom
,
283 return STATUS_UNSUCCESSFUL
;
286 return STATUS_SUCCESS
;
289 CSR_API(CsrHideDesktop
)
291 PRIVATE_NOTIFY_DESKTOP nmh
;
292 DPRINT("CsrHideDesktop\n");
294 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
295 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
297 nmh
.hdr
.hwndFrom
= Request
->Data
.ShowDesktopRequest
.DesktopWindow
;
299 nmh
.hdr
.code
= PM_HIDE_DESKTOP
;
301 if (SendMessageW(Request
->Data
.ShowDesktopRequest
.DesktopWindow
,
303 (WPARAM
)nmh
.hdr
.hwndFrom
,
306 return STATUS_UNSUCCESSFUL
;
309 return STATUS_SUCCESS
;
314 DtbgIsDesktopVisible(VOID
)
316 if (VisibleDesktopWindow
!= NULL
&&
317 !IsWindowVisible(VisibleDesktopWindow
))
319 VisibleDesktopWindow
= NULL
;
322 return VisibleDesktopWindow
!= NULL
;