ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

desktopbg.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.