How to determine if the current mouse cursor is animated?

Is there a way to determine if the current mouse cursor is animated?

I was looking for a way to save the current cursor some time ago. I found a DrawIconEx function that is perfect for my purpose. Unfortunately, I do not know how to determine if the current cursor is animated. I was hoping that if I set the istepIfAniCur parameter to 1 in the case of a static cursor, DrawIconEx returns False, but it really ignores this parameter and returns True, which prevents me from using it in a loop to get a static cursor, as well as all frames from the animated one. In the case of animated, it works as expected, so when you go out of range with istepIfAniCur, it returns False.

So, how do I know that HICON (HCURSOR) is an animated cursor? How does DrawIconEx determine that the cursor is animated?

thanks a lot

+6
source share
3 answers

I found one workaround - go to the istepIfAniCur parameter of the DrawIconEx max UINT parameter . It is impossible for someone to create an animated cursor with 4,294,967,295 frames (perhaps for some kind of cursor movie :)

Using this fact, you can pass this value to the DrawIconEx function, which will return False if the cursor is animating (due to exceeding the frame range) and True if it is static, since it ignores the istepIfAniCur parameter. You must pass 0 to the diFlags parameter because there is no need to draw anything.

Here is a Delphi example:

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

And since I promised the C ++ tag here, my translation attempt

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


Exceeding the frame range is also indicated by the OS ERROR_INVALID_PARAMETER error , which you can check using GetLastError when DrawIconEx fails.

+7
source

The best way:

  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); 
+2
source

Here is an example in Delphi (and trying to translate to C ++), how I tried to get the cursor sizes using GetIconInfo , but this does not work as I expected. It always returns the width of one frame in the case of an animated cursor, so it seems that GetIconInfo doesn't care about frames at all. Or am I wrong?

 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; 

My attempt at Visual C ++ (note that I don't know C ++ and don't have a compiler :)

 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); 
0
source

Source: https://habr.com/ru/post/894461/


All Articles