none
Is it possible to get a DC handle of another Desktop?

    Question

  •  

    I made a new desktop( using CreateDesktop() ).

    and I want to capture a screen shot of another desktop - this's unactive desktop.

    Is is possible or are there any other way to capture a screen shot??

     

    Tuesday, July 31, 2007 2:53 AM

All replies

  • I haven't tried this, but you could try SetThreadDesktop followed by GetDesktopWindow / GetDC and that might just work out for you.
    Tuesday, July 31, 2007 3:42 AM
  • Thanks for answering my question.

     

    I tried that you've suggested, but this SetThreadDesktop() function doesn't work.

     

       HDESK hDesk = OpenDesktop(_T("New"),NULL,TRUE,GENERIC_ALL);
       BOOL bRes = SetThreadDesktop(hDesk);

     

    I made a "New" Desktop. so there're two desktops( "Default" and "New" ).

    I can get a "New" desktop handle by OpenDesktop(), but SetThreadDesktop(hDesk) function doesn't work.

    it returns FALSE. I don't know why?  please let me know...

     

    Tuesday, July 31, 2007 4:22 AM
  • If no other solutions, maybe you have to start a helper application in new desktop? You can specify the target desktop in STARTUPINFO structure of CreateProcess function. Probably this helper application will have access to the device context of the new desktop.

     

    I hope this makes sense.

     

    Tuesday, July 31, 2007 7:07 AM
  • Thanks for answering my question.

     

    I tried a similar way that you've recommended.

     

    I made a new desktop and started my "A" application there.

     

    then, my "B" application in default desktop(active desktop) sends a message to "A" appliction in new desktop(unactive desktop).

     

    and, "A" application get a DC of own desktopwindow and capture a screen shot when get a message from "B" application.

     

    but the capture image is just all black...I think the reason is the new desktop isn't active. right? I'm not sure...

     

    So, I also tried this reversely. "B" application sends a message to "A" application with a DC handle of default desktop.

     

    and "B" application capture a screen shot of default desktop using this DC handle( got from "A" ).

     

    but this capture image is also all black...does it make sense?...I really don't know why?...

     

     

    Tuesday, July 31, 2007 7:54 AM
  • I would suggest the following tests. Check your screen-capturing routine first on the main active desktop, then on second desktop, but after activating it with SwitchDesktop function; instead of HDC created for GetDesktopWindow, try GetDC(NULL).

     

    Tuesday, July 31, 2007 8:10 AM
  • yes..In case of using SwitchDesktop function first, there's no problem. but I want to get a capture image before changing a desktop. do you think it's impossible?

    Tuesday, July 31, 2007 8:28 AM
  • I am not sure if it is possible to capture a window which is not visible or a desktop which is not active.

    Tuesday, July 31, 2007 8:57 AM
  • Then, reversely do you think it's possible to capture a window of active desktop from an applicaton in unactive desktop?

    Tuesday, July 31, 2007 9:11 AM
  • I am facing same problem. The reason I think is BitBlt fails with GetLastError() value of 6 which is invalid handle, may be the handle of the dc is invalid after the switchdesktop. I don't know how this can be resolved...any solution yet...

     

    Tuesday, January 29, 2008 9:33 PM
  • Not sure if this would work but..

     

    Try getting the desktop window of the B or hidden desktop, create a memory DC and send the desktop window a WM_PRINT or WM_PRINTCLIENT message with the memory DC.

    Monday, February 04, 2008 2:53 PM
  • I found this piece of code which may help http://www.catch22.net/source/


    #include <windows.h>
    #include <stdio.h>
    
    HDESK   hdeskCurrent;
    HDESK   hdesk;
    HWINSTA hwinstaCurrent;
    HWINSTA hwinsta;
    
    BOOL Attach(LPCTSTR szWinSta)
    {
          // 
          // Save the current Window station
          // 
          hwinstaCurrent = GetProcessWindowStation();
          if (hwinstaCurrent == NULL)
             return FALSE;
    
          // 
          // Save the current desktop
          // 
          hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
          if (hdeskCurrent == NULL)
             return FALSE;
    
          // 
          // Obtain a handle to WinSta0 - service must be running
          // in the LocalSystem account
          // 
          hwinsta = OpenWindowStation(szWinSta, FALSE,
                                      WINSTA_ACCESSCLIPBOARD   |
                                      WINSTA_ACCESSGLOBALATOMS |
                                      WINSTA_CREATEDESKTOP     |
                                      WINSTA_ENUMDESKTOPS      |
                                      WINSTA_ENUMERATE         |
                                      WINSTA_EXITWINDOWS       |
                                      WINSTA_READATTRIBUTES    |
                                      WINSTA_READSCREEN        |
                                      WINSTA_WRITEATTRIBUTES);
          if (hwinsta == NULL)
             return FALSE;
    
          // 
          // Set the windowstation to be winsta0
          // 
          if (!SetProcessWindowStation(hwinsta))
             return FALSE;
    
    	  // 
          // Get the default desktop on winsta0
          // 
          hdesk = OpenDesktop("default", 0, FALSE,
                                DESKTOP_CREATEMENU |
                      DESKTOP_CREATEWINDOW |
                                DESKTOP_ENUMERATE    |
                                DESKTOP_HOOKCONTROL  |
                                DESKTOP_JOURNALPLAYBACK |
                                DESKTOP_JOURNALRECORD |
                                DESKTOP_READOBJECTS |
                                DESKTOP_SWITCHDESKTOP |
                                DESKTOP_WRITEOBJECTS);
    
    	  printf("%d %d\n", hdesk, GetLastError());
    
    	  SetThreadDesktop(hdesk);
    
    
    	return TRUE;
    }
    
    BOOL Detach()
    {
    	// 
       // Reset the Window station and desktop
       // 
       if (!SetProcessWindowStation(hwinstaCurrent))
               return FALSE;
    
       if (!SetThreadDesktop(hdeskCurrent))
          return FALSE;
    
       // 
       // Close the windowstation and desktop handles
       // 
       if (!CloseWindowStation(hwinsta))
          return FALSE;
    
       if (!CloseDesktop(hdesk))
               return FALSE;
    
       return TRUE;
    }
    
    int main()
    {
        if(Attach("WinSta0"))
        {
    	// do stuff here
    	
    	Detach();
        }
    }
    Sunday, May 11, 2008 8:47 PM
  • the code above doesn't solve it

    I'm facing the same problem.

    Working on it !

    Tuesday, October 26, 2010 8:52 PM