在 cmets 中发生的进一步讨论之后,我有机会进一步调查这个问题。结果,我想出了下面的代码,它将抓取当前光标的 HBITMAP 并将其绘制到屏幕上。
由于光标是实际上是一个HICON,它带有一个掩码。最初,我只是做了一个简单的 BitBlt - 但是,我得到了一个 32x32 黑色方块,光标在左上角 1/4 左右。
然后我使用 MaskBlt 进行了调查。根据应用程序启动时光标所在的位置,我得到等待光标、NS 调整大小光标或标准指针。我想您可以启动一个计时器并添加一个 WM_TIMER 处理程序以每秒触发几次,以便实时更新光标,因为它在系统中的其他窗口中使用。做这样的事情似乎只是出于好奇,所以我没有打扰。
编辑:我实际上确实在 WM_INITDIALOG 中启动了一个计时器并在 WM_TIMER 中处理它。您现在可以看到图像每秒更新 10 次。出于某种原因,I 型光标似乎根本没有显示——我猜这是需要进一步调查的案例。
这是完整列表(resource.rc 和 resource.h 除外 - 只需创建一个对话框应用程序并确保在 Main 中调用 DialogBox 时使用了对话框的资源 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);
}