从另一个桌面捕获屏幕截图

2024-04-04

我使用创建了第二个桌面CreateDesktop我不会切换到它。我还在其中创建了一些进程,例如 Explorer.exe 和 Winrar.exe。接下来我有一个代码,它将当前桌面的屏幕截图保存到剪贴板。 CreateDesktop 和 Screenshot 都有效,但是新桌面或窗口的屏幕截图返回黑色位图:

这是桌面中返回当前桌面的窗口的屏幕截图:

// hwnd is handle to winrar or ... created in a new desktop retrieved by EnumDesktopWindow
RECT rc;
GetClientRect(hwnd, &rc);
const HDC hScreenDC = GetDC(nullptr);
const HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
const int width = GetDeviceCaps(hScreenDC, HORZRES);
const int height = GetDeviceCaps(hScreenDC, VERTRES);
const HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
HBITMAP(SelectObject(hMemoryDC, hBitmap));
BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);

OpenClipboard(nullptr);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();

DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);

我已经在 C# 中实现了这两种方法,但那里发生了同样的事情。

有很多很棒的资源,例如:

捕获隐藏桌面的屏幕截图 https://stackoverflow.com/questions/10375509/capture-screenshot-of-hidden-desktop

使用 createdesktop api 创建桌面的屏幕截图 https://stackoverflow.com/questions/4580520/take-a-screenshot-of-a-desktop-created-using-createdesktop-api

C# – 使用 VISTA DWM 进行屏幕捕获(共享 DIRECT3D 表面) http://spazzarama.com/2009/02/12/screen-capture-with-vista-dwm/

使用 WM_PRINT 消息捕获窗口内容 http://www.fengyuan.com/article/wmprint.html

如何从另一个桌面捕获屏幕?(CreateDesktop) https://stackoverflow.com/questions/5643637/how-to-capture-screen-from-another-desktopcreatedesktop

这也就像一个死主题,没有新文章、解释或解决方案。

我读过其中的大部分,但没有运气,我认为这是我最接近的尝试。另外,语言对我来说并不重要:C#、C++、Python 或...。


我找到了解决方案,它很有趣,但并不完美,只是解决了我的需求。

After CreateDesktop通过致电OpenDesktop then SetThreadDesktop然后使用屏幕截图代码,您可以获得在 CreateDesktop 中创建的窗口的屏幕截图,如果您只想要该窗口,也无需在其中创建 Explorer.exe:

CreateDesktopW(L"NewDesktop"); // CreateDesktop code here. This is my function
const HDESK Handle = OpenDesktopW(L"NewDesktop", 0, 0, GENERIC_ALL);
SetThreadDesktop(Handle);

// Above ScreenShot code here ...

截图代码需要PrintWindow:

RECT rc;
GetClientRect(hwnd, &rc);
const HDC hScreenDC = GetDC(nullptr);
const HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
const int width = GetDeviceCaps(hScreenDC, HORZRES);
const int height = GetDeviceCaps(hScreenDC, VERTRES);
const HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
HBITMAP(SelectObject(hMemoryDC, hBitmap));
BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);

/// ADDED CODE
PrintWindow(hWnd, hMemoryDC, PW_CLIENTONLY);
///

OpenClipboard(nullptr);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();

DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);

我的使用的是非活动桌面内的 winrar.exe 窗口。您可以尝试一下,然后将其粘贴到绘图中以查看结果。

只有一件事,屏幕截图位图的整个区域都是黑色的,除了我想要的窗口句柄,这对我来说很好。我想我应该按顺序处理每个窗口,然后将它们混合起来。

对此的所有补充均表示赞赏。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从另一个桌面捕获屏幕截图 的相关文章

随机推荐

  • 日期时间在数据网格、列表视图中不以当前文化格式显示

    在 WPF 中 我试图将日期属性绑定在DataGrid我只能在它绑定到 a 时进行排序DateTime财产 应用程序应以与用户的区域和语言设置相对应的格式显示日期 问题是当日期是string属性 它根据 Region 设置显示 但是当该属性
  • Swing 主动渲染效率或如何将主动渲染与 GUI 小部件结合起来

    继续从上一个问题 https stackoverflow com questions 3256269 jtextfields on top of active drawing on jpanel threading problems 我一直
  • Composer/Laravel:如何添加/更新特定包

    如何使用 Composer 添加 更新特定包 我也在使用最新的 Laravel 不确定它是否重要 但任何可以帮助确定答案的东西 我还从我发现的旧 Stackoverflow 帖子中尝试了以下内容 但它对我不起作用 它将包附加到compose
  • 如何将 Docker Web 应用程序容器连接到 Docker PostgreSQL 容器?

    我正在练习制作一个与 PostgreSQL 数据库交互的 Golang Web 应用程序 每个应用程序都在自己的容器上运行 我正在运行容器docker compose up 但我似乎无法正确设置 postgres 容器 为了简洁起见 链接到
  • 在 MATLAB 中使用连续滑块的值

    我有点被困在这里了 我尝试阅读和实现一些简单的连续滑块脚本 像这个 https stackoverflow com questions 6032924 in matlab how can you have a callback execut
  • 如何延长 CloudBuild 超时

    我尝试了许多不同的选项来延长 CloudBuild 持续时间 但我的 gcloud 应用程序部署步骤总是在 10 分钟后超时 根据其他线程的提示 我在本地终端上尝试了此设置 gcloud config set app cloud build
  • 我应该使用 Selenium 还是 Jasmine 来使用 RSpec 测试视图文件?

    我使用 Ruby on Rails 3 2 2 cucumber rails 1 3 0 rspec rails 2 8 1 和 capybara 1 1 2 以及 Selenium 驱动程序 收到我的答复后上一个问题 https stac
  • 更改 SF 对象的 CRS

    我有一些 道路 作为 sp 对象 class SpatialLinesDataFrame features 17360 extent 490176 4 567680 9 148639 1 212821 xmin xmax ymin ymax
  • 在开始日期和结束日期之间 Firestore

    我的文件带有startDate and endDate 我想查询的范围之间startDate and endDate 我可以在一个日期的范围之间查询 如下所示 whereField startDate isGreaterThan start
  • 在 Android 编辑文本的提示上显示错误

    如果用户在编辑文本中输入空白值 我想显示错误 但是我不知道如何执行此操作 这就是我想要的方式 这是我创建的 xml
  • 使用滑动手势关闭键盘(如在消息应用程序中)

    当键盘显示在 iPhone 的消息应用程序上时 如果用户开始从消息表视图向下滑动并继续进入键盘区域 键盘将开始消失 如果他们在此过程中上下移动手指 键盘也会随之移动 Apple 是否使用私有 API 来做到这一点 或者有没有办法通过 我推测
  • 通过 Ctypes 将 std:vector 从 C++ 传递到 Python:获取无意义的值

    我试图遵循程序 https stackoverflow com a 14887649 8408902但我被困住了 我正在尝试通过std vector来自我的 C 代码 包含在extern C 到Python 这就是我所拥有的 extern
  • 如何同时加入 multiprocessing.Process() 列表?

    Given a list 跑步的multiprocessing Process 实例 我怎样才能加入所有实例并在其中一个实例退出时立即返回而没有Process join 超时和循环 Example from multiprocessing
  • IPv4 允许的最大 TCP/IP 网络端口号是多少?

    可以使用的最大端口号是多少 端口号是一个无符号 16 位整数 即 65535
  • 使用js删除html按钮

    我下面有一些代码 用于在 html 表单上创建一个按钮 当用户使用按钮输入一些信息时 我希望表单通过删除按钮并将其替换为纯文本来反映这一点 我尝试获取内部 html 并使用 div 但没有任何效果 有人可以帮忙吗 我并不是在寻找任何人为我编
  • 在 Python 中比较两个列表中的值

    在 Python 2 7 中 我有两个整数列表 x 1 3 2 0 2 y 1 2 2 3 1 我想创建第三个列表 指示每个元素是否x and y是相同的 产生 z 1 0 1 0 0 如何使用列表理解来做到这一点 我的尝试是 z i j
  • Scala 更新数组元素

    我从没想过我会问这么简单的问题 但是如何更新 scala 中的数组元素 我已经在我的 Main 对象中声明了内部函数 我有这样的东西 object Main def main args Array String def miniFunc n
  • Android FragmentStatePagerAdapter

    我正在使用 FragmentStatePagerAdapter这个例子 http developer android com reference android support v4 app FragmentStatePagerAdapte
  • Javascript 和 C# 舍入地狱

    如您所知 由于天才舍入规则C 我们得到以下值 decimal d 2 155M var r Math Round d 2 2 16 decimal d 2 145M var r Math Round d 2 2 14 现在在客户端Javas
  • 从另一个桌面捕获屏幕截图

    我使用创建了第二个桌面CreateDesktop我不会切换到它 我还在其中创建了一些进程 例如 Explorer exe 和 Winrar exe 接下来我有一个代码 它将当前桌面的屏幕截图保存到剪贴板 CreateDesktop 和 Sc