Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在屏幕捕获中包括鼠标光标_C++_C_Screenshot_Screen Capture - Fatal编程技术网

C++ 在屏幕捕获中包括鼠标光标

C++ 在屏幕捕获中包括鼠标光标,c++,c,screenshot,screen-capture,C++,C,Screenshot,Screen Capture,我使用CreateDC/BitBlt/GetDIBits等来捕获屏幕,但没有捕获光标。是否有一些简单的论据或其他东西可以包括在内?除了评论中的讨论之外,我还有机会进一步调查这个问题。因此,我产生了以下代码,将获取当前光标的HBITMAP并将其绘制到屏幕上 因为光标实际上是一个HICON,所以它带有一个掩码。起初,我只是做了一个简单的BitBlt——然而,我得到了一个32x32的黑色sqaure,光标位于左上1/4左右 然后我使用MaskBlt进行了调查。根据应用程序启动时光标的位置,我会得到等待

我使用CreateDC/BitBlt/GetDIBits等来捕获屏幕,但没有捕获光标。是否有一些简单的论据或其他东西可以包括在内?

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

因为光标实际上是一个HICON,所以它带有一个掩码。起初,我只是做了一个简单的BitBlt——然而,我得到了一个32x32的黑色sqaure,光标位于左上1/4左右

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

编辑:我确实在WM\u INITDIALOG中启动了一个计时器,并在WM\u timer中处理它。现在可以看到图像每秒更新10次。出于某种原因,I-beam光标似乎根本没有显示出来——我想这是一个需要进一步调查的案例

以下是完整的列表(除了resource.rc和resource.h-只需创建一个对话框应用程序,并确保在调用对话框的Main中使用对话框的资源ID)

#包括
#包括
#包括
#包括“resource.h”
HINSTANCE hInst;
HBITMAP getCursorHBITMAP(HBITMAP*maskBmp)
{
CURSORINFO pci;
ICONINFO-ICONINFO;
HBITMAP结果;
pci.cbSize=sizeof(pci);
GetCursorInfo(&pci);
if(GetIconInfo(pci.hCursor和iconinfo))
{
结果=iconinfo.hbmColor;
if(maskBmp)
*maskBmp=iconinfo.hbmMask;
}
其他的
结果=空;
返回结果;
}
BOOL回调DlgMain(HWND hwndDlg、UINT uMsg、WPARAM WPARAM、LPARAM LPARAM)
{
开关(uMsg)
{
案例WM_初始化对话框:
{
设置计时器(hwndDlg,1100,空);
}
返回TRUE;
案例WM_计时器:
{
无效设置(hwndDlg,NULL,true);
}
返回0;
案例WM_擦除BKGND:
{
HDC HDC=(HDC)wParam;
直视磁共振;
GetClientRect(hwndDlg和mRect);
FillRect(hdc,&mRect,(HBRUSH)GetStockObject(GRAY_BRUSH));
}
返回1;
案例WM_油漆:
{
HBITMAP oldBm、cursorBmp、maskBmp;
cursorBmp=getCursorHBITMAP(&maskBmp);
if(cursorBmp)
{
HDC-HDC;
PAINTSTRUCT-ps;
HDC-memDC;
位图bm;
hdc=开始修补(hwndDlg和ps);
memDC=CreateCompatibleDC(hdc);
oldBm=(HBITMAP)选择对象(memDC、cursorBmp);
GetObject(cursorBmp、sizeof(bm)和bm);
//printf(“光标大小:%d x%d\n”,bm.bmWidth,bm.bmHeight);
//BitBlt(hdc,10,10,32,32,memDC,0,0,srcopy);
MaskBlt(hdc,10,10,bm.bmWidth,bm.bmHeight,memDC,0,0,maskBmp,0,0,MAKEROP4(SRCPAINT,SRCCOPY));
选择对象(memDC、oldBm);
DeleteDC(memDC);
EndPaint(hwndDlg和ps);
}
}
返回0;
案例WM_结束:
{
EndDialog(hwndDlg,0);
}
返回TRUE;
case WM_命令:
{
开关(LOWORD(wParam))
{
}
}
返回TRUE;
}
返回FALSE;
}
int APIENTRY WinMain(HINSTANCE HINSTANCE、HINSTANCE hPrevInstance、LPSTR lpCmdLine、int nShowCmd)
{
hInst=hInstance;
InitCommonControls();
返回对话框(hInst,MAKEINTRESOURCE(DLG_MAIN),NULL,(DLGPROC)DlgMain);
}
#包括
#包括
#包括
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(空);
hbitmap=CreateCompatibleBitmap(hdc、cx、cy);
选择对象(hdcMem、hbitmap);
BitBlt(hdcMem,0,0,cx,cy,hdc,0,0,srcopy);
CURSORINFO cursor={sizeof(cursor)};
GetCursorInfo(&cursor);
if(cursor.flags==光标显示){
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;
位图bmpCursor={0};
GetObject(info.hbmColor、sizeof(bmpCursor)和bmpCursor);
DrawIconEx(hdcMem、x、y、cursor.hCursor、bmpCursor.bmWidth、bmpCursor.bmHeight、,
0,空,DI_正常);
}
}
int main(){
scrshot();
返回0;
}

总之,不是。光标由操作系统绘制,因此,它实际上不是HDC中选择的HBITMAP所保存图像的一部分。当绘制到屏幕上时,它绘制在该图像的(副本)上。处理此问题的方法是在执行捕获时获取鼠标位置。然后在此位置绘制光标图像的副本。请注意,按下PrtSc按钮时也不会捕获光标。软件InstantDemo(一个屏幕录制应用程序)采用了我提到的显示鼠标光标的方法。我如何获得光标的图像?通过谷歌搜索“指针光标”,然后下载一个你喜欢的。点击率只有500万左右——我想你会找到一个你喜欢的。但我需要光标与屏幕上的光标相同,因为它将被捕获到带有自定义光标的软件中。有趣的是,你应该这么说,我在发布后不久就考虑过这种可能性
#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);
}
#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;
}