使用鼠标光标捕获屏幕截图

发布于 2024-08-09 10:44:26 字数 403 浏览 6 评论 0原文

我使用以下代码在 Windows 上获取屏幕截图。

 hdcMem = CreateCompatibleDC (hdc) ;
 int cx = GetDeviceCaps (hdc, HORZRES);
 int cy = GetDeviceCaps (hdc, VERTRES);
 HBITMAP hBitmap(NULL);
 hBitmap = CreateCompatibleBitmap (hdc, cx, cy) ;
 SelectObject (hdcMem, hBitmap) ;
 BitBlt(hdcMem, 0, 0, cx, cy, hdc, 0, 0, SRCCOPY);

但是,鼠标光标不显示。

我怎样才能获得光标?或者有没有图书馆可以做到这一点?

提前致谢。

I have used the following code to get screen shot on Windows.

 hdcMem = CreateCompatibleDC (hdc) ;
 int cx = GetDeviceCaps (hdc, HORZRES);
 int cy = GetDeviceCaps (hdc, VERTRES);
 HBITMAP hBitmap(NULL);
 hBitmap = CreateCompatibleBitmap (hdc, cx, cy) ;
 SelectObject (hdcMem, hBitmap) ;
 BitBlt(hdcMem, 0, 0, cx, cy, hdc, 0, 0, SRCCOPY);

However, the mouse cursor doesn't show up.

How could I get the cursor? or Is there a library can do that?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

兲鉂ぱ嘚淚 2024-08-16 10:44:26

在 BitBlt 之后和从 hdcMem 中选择位图之前,您可以执行以下操作:

CURSORINFO cursor = { sizeof(cursor) };
::GetCursorInfo(&cursor);
if (cursor.flags == CURSOR_SHOWING) {
    RECT rcWnd;
    ::GetWindowRect(hwnd, &rcWnd);
    ICONINFOEXW info = { sizeof(info) };
    ::GetIconInfoExW(cursor.hCursor, &info);
    const int x = cursor.ptScreenPos.x - rcWnd.left - rc.left - info.xHotspot;
    const int y = cursor.ptScreenPos.y - rcWnd.top  - rc.top  - info.yHotspot;
    BITMAP bmpCursor = {0};
    ::GetObject(info.hbmColor, sizeof(bmpCursor), &bmpCursor);
    ::DrawIconEx(hdcMem, x, y, cursor.hCursor, bmpCursor.bmWidth, bmpCursor.bmHeight,
                 0, NULL, DI_NORMAL);
}

上面的代码使用全局光标状态确定光标是否显示,因为您可能正在截取一个窗口(或多个窗口)的屏幕截图在另一个进程中。然后它获取目标窗口坐标以从屏幕进行调整。它获取有关光标的特定信息,包括其热点。它计算图标的绘制位置。最后,它获取光标图标的实际大小,以便可以在不进行任何拉伸的情况下绘制它。

据我所知,这种方法的唯一限制是:

  • 如果启用了光标阴影,则不会获得光标阴影。
  • 如果它是动画光标,则仅显示第一帧。据我所知,没有办法确定当前帧。

After your BitBlt and before you select the bitmap back out of hdcMem, you can do this:

CURSORINFO cursor = { sizeof(cursor) };
::GetCursorInfo(&cursor);
if (cursor.flags == CURSOR_SHOWING) {
    RECT rcWnd;
    ::GetWindowRect(hwnd, &rcWnd);
    ICONINFOEXW info = { sizeof(info) };
    ::GetIconInfoExW(cursor.hCursor, &info);
    const int x = cursor.ptScreenPos.x - rcWnd.left - rc.left - info.xHotspot;
    const int y = cursor.ptScreenPos.y - rcWnd.top  - rc.top  - info.yHotspot;
    BITMAP bmpCursor = {0};
    ::GetObject(info.hbmColor, sizeof(bmpCursor), &bmpCursor);
    ::DrawIconEx(hdcMem, x, y, cursor.hCursor, bmpCursor.bmWidth, bmpCursor.bmHeight,
                 0, NULL, DI_NORMAL);
}

The code above figures out if the cursor is showing, using the global cursor state since you're probably taking a screenshot of a window (or windows) in another process. It then gets the target window coordinates for adjusting from screen. It gets specific info about the cursor, including its hotspot. It computes the drawing position of the icon. Finally, it gets the actual size of the cursor icon so that it can draw it without any stretching.

The only limitations to this approach that I know of are:

  • You don't get cursor shadows if you have them enabled.
  • If it's an animated cursor, this just shows the first frame. As far as I know, there's no way to determine the current frame.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文