CreateDC/BitBlt/GetDIBits 등을 사용하여 화면을 캡처하지만 커서가 캡처되지 않습니다. 거기에 간단한 논증이나 포함시킬 것이 있습니까?화면 캡처에 마우스 커서 포함
3
A
답변
2
덧글에서 발생한 토론과 더불어 더 질문 할 기회가있었습니다. 결과적으로 현재 커서의 HBITMAP을 가져 와서 화면에 그려주는 다음 코드를 작성했습니다.
커서 은 실제로 HICON 인이므로 마스크가 제공됩니다. 처음에는 간단한 BitBlt를 만들었지 만, 커서가 왼쪽 위 1/4 1/4 정도에있는 32x32 검정색 sqaure를 얻었습니다.
그런 다음 MaskBlt를 사용하여 조사했습니다. 앱이 시작될 때 커서 위치에 따라 대기 커서, NS 크기 변경 커서 또는 표준 포인터 중 하나가 표시됩니다. 나는 당신이 타이머를 시작하고 WM_TIMER 핸들러를 추가하여 시스템의 다른 윈도우에서 사용 된 것처럼 커서의 실시간 업데이트를 얻기 위해 두 번째로 몇 번 발사 할 수 있다고 생각한다. 그렇게 단순한 호기심처럼 보였으므로 걱정하지 않았습니다.
편집 : 실제로는 WM_INITDIALOG에서 타이머를 시작하고 WM_TIMER에서 처리했습니다. 이제 초당 10 번 업데이트 된 이미지를 볼 수 있습니다. 어떤 이유로 I-beam 커서가 전혀 표시되지 않는 것 같습니다. 필요에 따라 추가 조사를해야 할 수도 있습니다.
여기에 전체 목록입니다 (resource.rc 및 및 Resource.h을 제외하고는 - 그냥 대화 응용 프로그램을 작성하고 대화 상자의 자원 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);
}
0
#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;
}
한 마디로, 아니. 커서는 OS에 의해 그려지기 때문에 실제로는 HDIC로 선택된 HBITMAP에 의해 유지되는 이미지의 일부가 아닙니다. 화면에 그릴 때이 이미지의 사본 (사본)의 꼭대기에 그려집니다. 이것을 처리하는 방법은 캡처를 수행 할 때 마우스 위치를 얻는 것입니다. 그런 다음이 위치에 커서 이미지의 복사본을 그립니다. PrtSc 버튼을 누르면 커서가 캡처되지 않습니다. InstantDemo (스크린 레코딩 앱) 소프트웨어는 내가 마우스 커서를 표시하는 방법에 대해 언급합니다. – enhzflep
어떻게 커서 이미지를 얻을 수 있습니까? – Tez
"포인터 커서"를 검색하여 원하는 것을 다운로드하십시오. 500 만 명 정도의 히트 곡이 있습니다. 당신이 좋아하는 곡을 찾을 수있을 거라 생각합니다. – enhzflep