我正在使用createdesktop api来创build一个桌面,我想要截图或发送input鼠标/键盘不显示桌面的user.any ideeas如何实现这?
编辑 :这将无法工作的隐形桌面,我看着我的旧代码,我看到我需要捕捉活动桌面(这不是 'WinSta0 \ Default')的截图,以获得活动用户的句柄桌面我已经使用OpenInputDesktop。
+1 ThievingSix你是对的 。
对不起,我的误解。
您需要使用SetThreadDesktop(如果您正在通过CreateDestkop创建桌面,那么您已经将它传递给了SetThreadDesktop)。 切换线程后,您可以捕捉截图。 好主意会恢复到以前的桌面线程(不要“打破”其他/未来的代码)。
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;
这个代码应该在非主线程中运行,因为ThievingSix指出,因为SetThreadDesktop在这种情况下可能会失败。 安全的方式是产生线程来制作截图。
PS。 我不知道这是否会与“发送输入鼠标/键盘”(它应该),但截图的作品。
编辑 :
我发现的简短答案是,你不能。 您不能截取非活动的桌面,因为没有绘画调用,因为没有可见的窗口重绘。
你可以做一个SwitchDesktop()调用,屏幕截图,然后SwitchDesktop()回来。 用户不会注意到它,但是在屏幕截图中可能不会有太多的东西,因为在这么短的时间内,窗口没有时间重绘。
另一件事是,你必须创建一个新的线程来调用SetThreadDesktop()。 如果您使用主线程来执行此操作,则在使用GUI应用程序时将失败。 SetThreadDesktop()在当前桌面中有一个窗口时失败。
SysInternals有一个应用程序来管理多个桌面(如Linux桌面切换)。 当你要选择一个桌面切换到它会显示您的桌面缩略图。 这个缩略图不是实时的,当用户在桌面上时,它被最后一次已知的完全重绘所捕获。 总之,如果SysInternals不能做一个生动的截图我怀疑我们任何人都会。
这当然是基于我自己对这个确切特征的研究。 如果有人真的得到它的工作,我很想知道,所以我不能使用它!