7

有没有办法确定当前鼠标光标是否动画?

前段时间我一直在寻找一种如何保存当前光标的方法。我发现DrawIconEx函数非常适合我的目的。不幸的是,我不知道如何确定当前光标是否为动画。我希望如果我将 istepIfAniCur 参数设置为 1 以防静态光标DrawIconEx返回 False 但它确实忽略了该参数并返回 True 什么不允许我在循环中使用它来获取静态光标以及所有帧动画的。如果动画按预期工作,因此当您使用 istepIfAniCur 超出范围时,它会返回 False。

那么如何找出 HICON (HCURSOR) 是动画光标呢?DrawIconEx如何确定光标是动画的?

非常感谢

4

3 回答 3

7

我找到了一种解决方法 - 传递给UINT的DrawIconEx函数最大值的 istepIfAniCur 参数。不可能有人会创建具有 4,294,967,295 帧的动画光标(可能对于某些光标电影 :)

有了这个事实,您可以将此值传递给DrawIconEx函数,如果光标处于动画状态(因为超出帧范围),该函数将返回 False,在静态光标的情况下返回 True,因为它忽略了 istepIfAniCur 参数。您应该将 0 传递给 diFlags 参数,因为不需要绘制任何内容。

这是德尔福的例子:

if not DrawIconEx(Canvas.Handle, 0, 0, hCursor, 0, 0, High(Cardinal), 0, 0) then
  Caption := 'Cursor is animated ...'
else
  Caption := 'Cursor is not animated ...';

因为我答应了 C++ 标签,所以这是我的翻译尝试

if (!DrawIconEx(this->Canvas->Handle, 0, 0, hCursor, 0, 0, UINT_MAX, NULL, 0))
  this->Caption = "Cursor is animated ...";
else
  this->Caption = "Cursor is not animated ...";


DrawIconEx失败时,您可以使用GetLastError函数检查操作系统错误ERROR_INVALID_PARAMETER 也指示超出帧范围。

于 2011-08-07T12:11:06.090 回答
3

最好的办法:

typedef HCURSOR(WINAPI* GET_CURSOR_FRAME_INFO)(HCURSOR, LPCWSTR, DWORD, DWORD*, DWORD*);
GET_CURSOR_FRAME_INFO fnGetCursorFrameInfo = 0;

HMODULE libUser32 = LoadLibraryA("user32.dll");
if (!libUser32)
{
  return false;
}

fnGetCursorFrameInfo = reinterpret_cast<GET_CURSOR_FRAME_INFO>(GetProcAddress(libUser32, "GetCursorFrameInfo"));
if (!fnGetCursorFrameInfo)
{
  return false;
}

DWORD displayRate, totalFrames;
fnGetCursorFrameInfo(hcursor, L"", 0, &displayRate, &totalFrames);
于 2017-03-02T21:23:30.130 回答
0

这是 Delphi 中的示例(并尝试转换为 C++)我如何尝试使用GetIconInfo函数获取光标尺寸,但它没有按我的预期工作。如果是动画光标,它总是返回一帧的宽度,因此GetIconInfo似乎根本不处理帧。还是我错了?

procedure TForm1.Timer1Timer(Sender: TObject);
var
  IconInfo: TIconInfo;
  CursorInfo: TCursorInfo;
  Bitmap: Windows.TBitmap;
begin
  CursorInfo.cbSize := SizeOf(CursorInfo);
  GetCursorInfo(CursorInfo);
  GetIconInfo(CursorInfo.hCursor, IconInfo);

  if GetObject(IconInfo.hbmColor, SizeOf(Bitmap), @Bitmap) <> 0 then
  begin
    Caption := 'Cursor size: ' +
               IntToStr(Bitmap.bmWidth) + ' x ' +
               IntToStr(Bitmap.bmHeight) + ' px';
  end;

  DeleteObject(IconInfo.hbmColor);
  DeleteObject(IconInfo.hbmMask);
end;

我的 Visual C++ 尝试(请注意,我不懂 C++,也没有编译器 :)

CString txt;
ICONINFO ii;
CURSORINFO ci;
BITMAP bitmap;

ci.cbSize = SizeOf(CURSORINFO);
GetCursorInfo(ci);
GetIconInfo(ci.hCursor, ii);
GetObject(ii.hbmColor, sizeof(BITMAP), &bitmap);
txt.Format("Cursor width: %d px", bitmap.bmWidth);
MessageBox(txt);
于 2011-08-07T14:23:51.107 回答