【问题标题】:SetSystemCursor not animating *.ani cursorsSetSystemCursor 没有动画 *.ani 光标
【发布时间】:2017-07-25 15:50:02
【问题描述】:

我几乎用尽了 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

【问题讨论】:

  • 我不认为SetSystemCursor 支持动画光标。您可以将新的文件名写入HKEY_CURRENT_USER\Control Panel\Cursors下的适当值,然后使用SystemParametersInfo(SPI_SETCURSORS...);使系统重新加载游标。
  • @JonathanPotter 感谢您的提示,我会调查的。我仍然不明白为什么动画光标不起作用,特别是考虑到 Microsoft 自己的文档包含有关使用 .ani 光标的说明。我认为这与光标的自动销毁有关,但同样,为什么他们不允许 .ani 光标是没有意义的。此外,听起来网上的人之前已经让他们工作了......
  • 我认为这是 Windows 10 中的错误/错误... SetSystemCursor 过去在 Windows 7 和 XP 中与 .ani 动画光标一起正常工作,与他们自己的文档一致。

标签: c winapi


【解决方案1】:

我们仍然感谢更好的解决方案。

根据波特的评论和我自己的经验;看来您无法使用 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“箭头”分别更改为任何其他光标类型以更改其图标。

在外部存储原始注册表值并实现一种在退出或崩溃时重置的方法也是值得的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-09
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 2014-02-23
    • 1970-01-01
    相关资源
    最近更新 更多