Search code examples
windowsdelphiwinapiscreenshot

take a screenshot of a desktop created using createdesktop api


i am using the createdesktop api to create a desktop and i would like to take a screenshot or send input mouse/keyboard without dispalying the desktop to the user.any ideeas on how to implement this???


Solution

  • Edit: This won't work for invisible desktops, I've looked to my old code, and I see that I needed that for catching screenshot of active desktop (which was not 'WinSta0\Default'), to get handle of active user desktop I've used OpenInputDesktop.

    +1 ThievingSix you are right.

    Sorry everyone for my misunderstanding.


    You need to use SetThreadDesktop (if you are creating desktop by CreateDestkop, then you have handle for it which you pass to SetThreadDesktop). After switching desktop for thread, you can catch screenshot. Good idea would be revert to previous desktop for thread (to not 'break' other/future code).

    var
      lOldDesktop: HDESK;
    begin
      lOldDesktop:= GetThreadDesktop(GetCurrentThreadId);
      try
        if not SetThreadDesktop(ADesktop) then // pass handle to your desktop, or dekstop handle obtained from OpenInputDesktop
          {error handle, like RaiseLastOSError or Exit(False)};
    
        // your screenshot/input/mouse code here
    
      finally
        if lOldDesktop<> 0 then // GetThreadDesktop can fail (I don't know condition when this GetThreadDesktop(GetCurrentThreadId) could fail)
          SetThreadDesktop(lOldDesktop); // revert thread to previous desktop
      end;
    end;
    

    This code should run in non-main thread, as ThievingSix pointed because SetThreadDesktop can fail in that case. Safe way is spawn thread to make screenshot.

    PS. I'm not sure if this will work with "send input mouse/keyboard" (it should), but for screenshot works.

    Edit: