在屏幕捕获中包含鼠标光标

时间:2014-06-22 04:26:32

标签: c++ c screenshot screen-capture

我使用CreateDC / BitBlt / GetDIBits等来捕获屏幕,但是没有捕获光标。是否有一些简单的论点或其他内容包含它?

2 个答案:

答案 0 :(得分:2)

除了评论中发生的讨论之外,我还有机会进一步调查这个问题。结果,我想出了以下代码,它将获取当前光标的HBITMAP并将其绘制到屏幕上。

由于光标实际上是是一个HICON,它带有一个掩码。最初,我只做了一个简单的BitBlt - 然而,我得到了一个32x32黑色sqaure,光标在左上角1/4左右。

然后我使用MaskBlt进行了调查。根据应用程序启动时光标的位置,我得到等待光标,NS调整大小光标或标准指针。我猜你可以启动一个计时器并添加一个WM_TIMER处理程序,每秒触发几次,以便获得光标的实时更新,因为它在系统的其他窗口中使用。做这样的事似乎只是好奇,所以我没有打扰。

编辑:我确实在WM_INITDIALOG中启动了一个计时器并在WM_TIMER中处理它。您现在可以看到图像每秒更新10次。出于某种原因,I-beam光标似乎根本没有显示 - 我猜是根据需要进行进一步调查的情况。

这是完整的清单(除了resource.rc和resource.h之外 - 只需创建一个对话框应用程序,并确保在调用DialogBox时在Main内部使用对话框的资源ID)

#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"

HINSTANCE hInst;

HBITMAP getCursorHBITMAP(HBITMAP *maskBmp)
{
    CURSORINFO pci;
    ICONINFO iconinfo;
    HBITMAP result;

    pci.cbSize = sizeof(pci);
    GetCursorInfo(&pci);

    if (GetIconInfo(pci.hCursor,&iconinfo))
    {
        result = iconinfo.hbmColor;
        if (maskBmp)
            *maskBmp = iconinfo.hbmMask;
    }
    else
        result = NULL;

    return result;
}

BOOL CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_INITDIALOG:
        {
            SetTimer(hwndDlg, 1, 100, NULL);
        }
        return TRUE;

        case WM_TIMER:
        {
            InvalidateRect(hwndDlg, NULL, true);
        }
        return 0;

        case WM_ERASEBKGND:
        {
            HDC hdc = (HDC)wParam;
            RECT mRect;
            GetClientRect(hwndDlg, &mRect);
            FillRect(hdc, &mRect, (HBRUSH)GetStockObject(GRAY_BRUSH));
        }
        return 1;

        case WM_PAINT:
        {
            HBITMAP oldBm, cursorBmp, maskBmp;

            cursorBmp = getCursorHBITMAP(&maskBmp);
            if (cursorBmp)
            {
                HDC hdc;
                PAINTSTRUCT ps;
                HDC memDC;
                BITMAP bm;

                hdc = BeginPaint(hwndDlg, &ps);
                memDC = CreateCompatibleDC(hdc);
                oldBm = (HBITMAP) SelectObject(memDC, cursorBmp);

                GetObject(cursorBmp, sizeof(bm), &bm);
    //            printf("Cursor size: %d x %d\n", bm.bmWidth, bm.bmHeight);

    //            BitBlt(hdc, 10,10, 32,32, memDC, 0,0, SRCCOPY);
                MaskBlt(hdc, 10,10, bm.bmWidth, bm.bmHeight, memDC, 0,0, maskBmp, 0,0, MAKEROP4(SRCPAINT,SRCCOPY) );


                SelectObject(memDC, oldBm);
                DeleteDC(memDC);
                EndPaint(hwndDlg, &ps);
            }
        }
        return 0;

        case WM_CLOSE:
        {
            EndDialog(hwndDlg, 0);
        }
        return TRUE;

        case WM_COMMAND:
        {
            switch(LOWORD(wParam))
            {
            }
        }
        return TRUE;
    }
    return FALSE;
}


int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    hInst=hInstance;
    InitCommonControls();
    return DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgMain);
}

答案 1 :(得分:1)

#include <Windows.h>
#include <stdio.h>
#include <assert.h>

void scrshot() {
    HWND hwnd = GetDesktopWindow();
    HDC hdc = GetWindowDC(hwnd);
    HDC 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);
    CURSORINFO cursor = { sizeof(cursor) };
    GetCursorInfo(&cursor);
    if (cursor.flags == CURSOR_SHOWING) {
        RECT rect;
        GetWindowRect(hwnd, &rect);
        ICONINFO info = { sizeof(info) };
        GetIconInfo(cursor.hCursor, &info);
        const int x = cursor.ptScreenPos.x - rect.left - rect.left - info.xHotspot;
        const int y = cursor.ptScreenPos.y - rect.top - rect.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);
    }
}

int main(){
    scrshot();
    return 0;
}