Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendesktopbg.c
Go to the documentation of this file.
00001 /* $Id: desktopbg.c 55696 2012-02-19 03:51:36Z ion $ 00002 * 00003 * reactos/subsys/csrss/win32csr/desktopbg.c 00004 * 00005 * Desktop background window functions 00006 * 00007 * ReactOS Operating System 00008 */ 00009 00010 #define NDEBUG 00011 00012 #include "w32csr.h" 00013 #include <debug.h> 00014 00015 #define DESKTOP_WINDOW_ATOM 32769 00016 00017 #define PM_SHOW_DESKTOP 1 00018 #define PM_HIDE_DESKTOP 2 00019 00020 typedef struct tagDTBG_THREAD_DATA 00021 { 00022 HDESK Desktop; 00023 HANDLE Event; 00024 NTSTATUS Status; 00025 } DTBG_THREAD_DATA, *PDTBG_THREAD_DATA; 00026 00027 typedef struct tagPRIVATE_NOTIFY_DESKTOP 00028 { 00029 NMHDR hdr; 00030 struct /* PM_SHOW_DESKTOP */ 00031 { 00032 int Width; 00033 int Height; 00034 } ShowDesktop; 00035 } PRIVATE_NOTIFY_DESKTOP, *PPRIVATE_NOTIFY_DESKTOP; 00036 00037 static BOOL BgInitialized = FALSE; 00038 static HWND VisibleDesktopWindow = NULL; 00039 00040 static 00041 LRESULT 00042 CALLBACK 00043 DtbgWindowProc(HWND Wnd, 00044 UINT Msg, 00045 WPARAM wParam, 00046 LPARAM lParam) 00047 { 00048 PAINTSTRUCT PS; 00049 00050 switch (Msg) 00051 { 00052 case WM_ERASEBKGND: 00053 PaintDesktop((HDC)wParam); 00054 return 1; 00055 00056 case WM_PAINT: 00057 if (BeginPaint(Wnd, &PS)) 00058 EndPaint(Wnd, &PS); 00059 return 0; 00060 00061 case WM_SETCURSOR: 00062 return (LRESULT)SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW)); 00063 00064 case WM_NCCREATE: 00065 return (LRESULT)TRUE; 00066 00067 case WM_CREATE: 00068 NtUserSetWindowFNID(Wnd, FNID_DESKTOP); // Anti-ReactOS hack! 00069 case WM_CLOSE: 00070 return 0; 00071 00072 case WM_DISPLAYCHANGE: 00073 MoveWindow(Wnd, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE); 00074 break; 00075 00076 case WM_NOTIFY: 00077 { 00078 PPRIVATE_NOTIFY_DESKTOP nmh = (PPRIVATE_NOTIFY_DESKTOP)lParam; 00079 00080 /* Use WM_NOTIFY for private messages since 00081 * it can't be sent between processes! 00082 */ 00083 switch (nmh->hdr.code) 00084 { 00085 case PM_SHOW_DESKTOP: 00086 { 00087 LRESULT Result; 00088 00089 Result = !SetWindowPos(Wnd, NULL, 0, 0, 00090 nmh->ShowDesktop.Width, 00091 nmh->ShowDesktop.Height, 00092 SWP_NOACTIVATE | SWP_NOZORDER | 00093 SWP_SHOWWINDOW); 00094 00095 UpdateWindow(Wnd); 00096 VisibleDesktopWindow = Wnd; 00097 return Result; 00098 } 00099 00100 case PM_HIDE_DESKTOP: 00101 { 00102 LRESULT Result; 00103 00104 Result = !SetWindowPos(Wnd, NULL, 0, 0, 0, 0, 00105 SWP_NOACTIVATE | SWP_NOZORDER | 00106 SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW); 00107 00108 UpdateWindow(Wnd); 00109 VisibleDesktopWindow = NULL; 00110 return Result; 00111 } 00112 00113 default: 00114 DPRINT("Unknown notification code 0x%x sent to the desktop window!\n", 00115 nmh->hdr.code); 00116 return 0; 00117 } 00118 } 00119 00120 default: 00121 return DefWindowProcW(Wnd, Msg, wParam, lParam); 00122 } 00123 00124 return 0; 00125 } 00126 00127 static 00128 BOOL 00129 FASTCALL 00130 DtbgInit(VOID) 00131 { 00132 WNDCLASSEXW Class; 00133 ATOM ClassAtom; 00134 00135 /* 00136 * Create the desktop window class 00137 */ 00138 Class.cbSize = sizeof(WNDCLASSEXW); 00139 Class.style = 0; // Local Class 00140 Class.lpfnWndProc = DtbgWindowProc; 00141 Class.cbClsExtra = 0; 00142 Class.cbWndExtra = 0; 00143 Class.hInstance = (HINSTANCE)GetModuleHandleW(NULL); 00144 Class.hIcon = NULL; 00145 Class.hCursor = NULL; 00146 Class.hbrBackground = GetSysColorBrush(COLOR_BACKGROUND); 00147 Class.lpszMenuName = NULL; 00148 Class.lpszClassName = (LPCWSTR)DESKTOP_WINDOW_ATOM; 00149 ClassAtom = RegisterClassExW(&Class); 00150 00151 if (ClassAtom == INVALID_ATOM) 00152 { 00153 DPRINT1("Unable to register desktop background class (error %d)\n", 00154 GetLastError()); 00155 00156 return FALSE; 00157 } 00158 00159 VisibleDesktopWindow = NULL; 00160 00161 return TRUE; 00162 } 00163 00164 static 00165 DWORD 00166 WINAPI 00167 DtbgDesktopThread(PVOID Data) 00168 { 00169 HWND BackgroundWnd; 00170 MSG msg; 00171 PDTBG_THREAD_DATA ThreadData = (PDTBG_THREAD_DATA)Data; 00172 00173 if (!SetThreadDesktop(ThreadData->Desktop)) 00174 { 00175 DPRINT1("Failed to set thread desktop\n"); 00176 ThreadData->Status = STATUS_UNSUCCESSFUL; 00177 SetEvent(ThreadData->Event); 00178 return 1; 00179 } 00180 00181 BackgroundWnd = CreateWindowW((LPCWSTR)DESKTOP_WINDOW_ATOM, 00182 L"", 00183 WS_POPUP | WS_CLIPCHILDREN, 00184 0, 0, 0, 0, 00185 NULL, NULL, 00186 (HINSTANCE)GetModuleHandleW(NULL), 00187 NULL); 00188 00189 if (NULL == BackgroundWnd) 00190 { 00191 DPRINT1("Failed to create desktop background window\n"); 00192 ThreadData->Status = STATUS_UNSUCCESSFUL; 00193 SetEvent(ThreadData->Event); 00194 return 1; 00195 } 00196 00197 ThreadData->Status = STATUS_SUCCESS; 00198 SetEvent(ThreadData->Event); 00199 00200 while (GetMessageW(&msg, NULL, 0, 0)) 00201 { 00202 TranslateMessage(&msg); 00203 DispatchMessageW(&msg); 00204 } 00205 00206 return 1; 00207 } 00208 00209 CSR_API(CsrCreateDesktop) 00210 { 00211 DTBG_THREAD_DATA ThreadData; 00212 HANDLE ThreadHandle; 00213 00214 DPRINT("CsrCreateDesktop\n"); 00215 00216 if (!BgInitialized) 00217 { 00218 BgInitialized = TRUE; 00219 00220 if (!DtbgInit()) 00221 return STATUS_UNSUCCESSFUL; 00222 } 00223 00224 /* 00225 * The desktop handle we got from win32k is in 00226 * the scope of CSRSS so we can just use it. 00227 */ 00228 ThreadData.Desktop = Request->Data.CreateDesktopRequest.DesktopHandle; 00229 00230 ThreadData.Event = CreateEventW(NULL, FALSE, FALSE, NULL); 00231 00232 if (NULL == ThreadData.Event) 00233 { 00234 DPRINT1("Failed to create event (error %d)\n", GetLastError()); 00235 return STATUS_UNSUCCESSFUL; 00236 } 00237 00238 ThreadHandle = CreateThread(NULL, 00239 0, 00240 DtbgDesktopThread, 00241 (PVOID)&ThreadData, 00242 0, 00243 NULL); 00244 00245 if (NULL == ThreadHandle) 00246 { 00247 CloseHandle(ThreadData.Event); 00248 DPRINT1("Failed to create desktop window thread.\n"); 00249 return STATUS_UNSUCCESSFUL; 00250 } 00251 00252 CloseHandle(ThreadHandle); 00253 00254 WaitForSingleObject(ThreadData.Event, INFINITE); 00255 CloseHandle(ThreadData.Event); 00256 00257 return ThreadData.Status; 00258 } 00259 00260 CSR_API(CsrShowDesktop) 00261 { 00262 PRIVATE_NOTIFY_DESKTOP nmh; 00263 DPRINT("CsrShowDesktop\n"); 00264 00265 nmh.hdr.hwndFrom = Request->Data.ShowDesktopRequest.DesktopWindow; 00266 nmh.hdr.idFrom = 0; 00267 nmh.hdr.code = PM_SHOW_DESKTOP; 00268 00269 nmh.ShowDesktop.Width = (int)Request->Data.ShowDesktopRequest.Width; 00270 nmh.ShowDesktop.Height = (int)Request->Data.ShowDesktopRequest.Height; 00271 00272 if (SendMessageW(Request->Data.ShowDesktopRequest.DesktopWindow, 00273 WM_NOTIFY, 00274 (WPARAM)nmh.hdr.hwndFrom, 00275 (LPARAM)&nmh)) 00276 { 00277 return STATUS_UNSUCCESSFUL; 00278 } 00279 00280 return STATUS_SUCCESS; 00281 } 00282 00283 CSR_API(CsrHideDesktop) 00284 { 00285 PRIVATE_NOTIFY_DESKTOP nmh; 00286 DPRINT("CsrHideDesktop\n"); 00287 00288 nmh.hdr.hwndFrom = Request->Data.ShowDesktopRequest.DesktopWindow; 00289 nmh.hdr.idFrom = 0; 00290 nmh.hdr.code = PM_HIDE_DESKTOP; 00291 00292 if (SendMessageW(Request->Data.ShowDesktopRequest.DesktopWindow, 00293 WM_NOTIFY, 00294 (WPARAM)nmh.hdr.hwndFrom, 00295 (LPARAM)&nmh)) 00296 { 00297 return STATUS_UNSUCCESSFUL; 00298 } 00299 00300 return STATUS_SUCCESS; 00301 } 00302 00303 BOOL 00304 FASTCALL 00305 DtbgIsDesktopVisible(VOID) 00306 { 00307 if (VisibleDesktopWindow != NULL && 00308 !IsWindowVisible(VisibleDesktopWindow)) 00309 { 00310 VisibleDesktopWindow = NULL; 00311 } 00312 00313 return VisibleDesktopWindow != NULL; 00314 } 00315 00316 /* EOF */ Generated on Sat May 26 2012 04:37:33 for ReactOS by
1.7.6.1
|