Как определить, является ли текущий курсор мыши анимированным? - PullRequest
6 голосов
/ 07 августа 2011

есть ли способ определить, является ли текущий курсор мыши анимированным?

Я искал способ как сохранить текущий курсор некоторое время назад. Я нашел функцию DrawIconEx , которая идеально подходит для моей цели. К сожалению, я не знаю, как определить, является ли текущий курсор анимированным. Я надеялся, что если я установлю для параметра istepIfAniCur значение 1 в случае статического курсора DrawIconEx возвращает значение False, но он действительно игнорирует этот параметр и возвращает значение True, что не позволяет мне использовать его в цикле для получения статического курсора как а также все кадры из анимации. В случае анимации один работает должным образом, поэтому, когда вы выходите за пределы диапазона с помощью istepIfAniCur, он возвращает False.

Так как мне узнать, что HICON (HCURSOR) является анимированным курсором? Как DrawIconEx определяет, что курсор анимирован?

Большое спасибо

Ответы [ 3 ]

7 голосов
/ 07 августа 2011

Я нашел один обходной путь - передайте параметру istepIfAniCur параметра DrawIconEx максимальное значение UINT . Невозможно, чтобы кто-то создал анимированный курсор с 4 294 967 295 кадрами (возможно, возможно для какого-то фильма с курсором:)

С этим фактом вы можете передать это значение в функцию DrawIconEx , которая будет возвращать False в случае, когда курсор анимирован (из-за превышения диапазона кадра), и True в случае статического, потому что оно игнорирует параметр istepIfAniCur. Вы должны передать 0 параметру diFlags, потому что не нужно ничего рисовать.

Вот пример Delphi:

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 ...";


Превышение диапазона фреймов также обозначается ошибкой ОС ERROR_INVALID_PARAMETER , что вы можете проверить с помощью функции GetLastError , когда DrawIconEx не удается.

2 голосов
/ 03 марта 2017

Лучший способ:

      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);
0 голосов
/ 07 августа 2011

Вот пример в 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);
...