SetSystemCursor没有动画* .ani游标

时间:2017-03-05 21:39:25

标签: c winapi

我刚刚用尽了Google和SO上的每个链接而没有找到解决方案......这可能是重复的,但其他问题要么没有回答,要么没有帮助并且已经存在多年了。出于某种原因,对我来说没有任何作用。

在我的程序中,我需要根据活动功能将系统范围的光标更改为其他光标。该程序添加和扩展鼠标的功能,更改光标将是活动功能的指示器。用户将选择加入此功能,因为知道光标会发生变化。

现在的问题是使用SetSystemCursor似乎没有动画,而只是绘制动画的第一帧。我注意到,通过使用SetCursor,动画可以工作,但仅限于应用程序本身(仅用于设置。它也不保留游标类型(箭头,文本,链接......))。为什么没有SetSytemCursor工作,有没有办法让它工作?

到目前为止我尝试过的例子......他们都工作到了他们绘制动画的第一帧的范围,实际上都没有动画。使用SetCursor将生成动画光标,但不会根据需要生成系统范围的特定光标。 Set *函数成功返回。

1:设置光标的简单尝试

SetSystemCursor( LoadCursorFromFile( L"custom_cursor.ani" ), OCR_NORMAL );

2:我的尝试,使用文档中的内容

/* Global HCURSOR */ arrowCurs = LoadCursorFromFile( L"custom_cursor.ani" );
HCURSOR temp = ( HCURSOR )CopyImage( arrowCurs, IMAGE_CURSOR, 0, 0, 0 );
SetSystemCursor( temp, OCR_NORMAL );
DestroyCursor( temp );

3:这是我发现的SO答案,链接丢失

FILE* fs = fopen( "--full path--\\custom_cursor.ani", "rb" );
fseek( fs, 0, SEEK_END ); int dwSize = ftell( fs ); fseek( fs, 0, SEEK_SET );
char* memory = new char[ dwSize + guardbandSize ];
fread( memory, 1, dwSize, fs ); memset( memory + dwSize, 0, guardbandSize );
fclose( fs );
SetSystemCursor( ( HCURSOR )CreateIconFromResource( ( PBYTE )memory, dwSize, FALSE, 0x00030000 ), 32512 );
delete memory;

到目前为止,唯一的解决方案是不更改光标图标,而是隐藏它并绘制一个无边框的最顶层窗口,并在其上绘制动画。但是,如果不能使用SetSystemCursor,我希望将其作为最后一个选项,因为增加了复杂性和不优雅。

使用Windows 10 x64和Visual Studio 2015

1 个答案:

答案 0 :(得分:0)

仍然赞赏更好的解决方案。

根据波特的评论和我自己的经验;看来你不能用SetSystemCursor设置.ani游标 - 这个解决方案会成功地将光标更改为动画光标,但它需要管理员权限,并注意它将永久设置给定用户的光标,这与临时SetSystemCursor不同直到会话重启。

HKEY key;
// The location of the new cursor to be set:
LPCWSTR loc = L"C:\\--full path--\\custom_cursor.ani";

if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_CURRENT_USER, L"Control Panel\\Cursors", 0, KEY_SET_VALUE, &key ) &&
     ERROR_SUCCESS == RegSetValueEx( key, L"Arrow", 0, REG_EXPAND_SZ, ( LPBYTE )loc, wcslen( loc ) * sizeof(  WCHAR ) ) )
{
    RegCloseKey(key);
}
else
{
    // Print error if failed
    WCHAR msg[ 256 ];
    FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, 0, 0, msg, 256, 0 );
    OutputDebugString( msg );
}

SystemParametersInfo( SPI_SETCURSORS, 0, NULL, 0 ); // Reload system cursors

改变L" Arrow"分别改为任何其他游标类型的图标。

还可以在外部存储原始注册表值,并在退出时或在崩溃时实施重置方法。