【问题标题】:TIcon only loads one image from the icon fileTIcon 只从图标文件中加载一张图片
【发布时间】:2014-12-09 22:27:56
【问题描述】:

我有一个包含 24x24、32x32、48x48、64x64 和 256x256 图标的图标文件。但是,当我像这样加载它时:

Application->Icon->LoadFromFile("filename.ico");

它似乎只从文件中加载一个图像,尽管我的图标包含图标的多种分辨率。结果是任何表单都使用为任务栏图标和角图标重新缩放的单个图标,这看起来很糟糕。

但是,如果我将 filename.ico 设置为已编译资源,或者如果我在项目属性 > 应用程序 > 图标中设置图标,那么我的表单将使用 24x24 图标作为角图标,将 48x48 图标用于任务栏。

我的问题是:如何让我的表单使用 filename.ico 中的图标,其中文件名在运行时才知道;但仍然使用 24x24 图标作为角落并使用 48x48 图标作为任务栏?

注意。我不喜欢硬编码这些尺寸 24x24 和 48x48,因为其他版本的 Windows(或者如果用户使用 Windows 字体缩放选项)可能会需要不同尺寸的图标。

【问题讨论】:

标签: icons vcl c++builder-xe5


【解决方案1】:

当您调用TIcon.LoadFrom...() 时,它会将原始图标数据的副本存储到内部内存块中,然后退出。直到下次调用 TIcon.HandleNeeded() 时才会处理该块,例如使用 TIcon.Handle 属性时。

如果图标数据代表RC3_STOCKICON 类型的图标(通常不会遇到),则使用来自LoadIcon()IDI_APPLICATION 图标。否则,如果图标数据表示RC3_ICON 类型的图标(通常情况下),则解析数据并与当前TIcon.WidthTIcon.Height 属性值(或SM_CXICON 和@如果尚未分配 TIcon 维度,则 987654336@ 指标通过 GetSystemMetrics() 传递给 CreateIcon()

从那时起,LoadIcon()CreateIcon() 返回的HICON 是用于TIcon 剩余生命周期的图像,或者至少在HICON 被释放/释放之前TIcon.ReleaseHandle()TIcon.Assign()TIcon.LoadFrom...()TIcon.SetHandle()

内存块本身仅在TIcon 被释放、TIcon.Assign() 被调用或加载新图像源时才被释放。因此,例如,应该可以调用TIcon.ReleaseHandle() 来释放当前的HICON(然后您必须通过DestroyIcon() 手动释放它),然后调整TIcon 的尺寸,然后调用@ 987654355@重新解析内存块以加载下一个最接近的匹配图像。

更新TIcon 不能同时加载多张不同分辨率的图片。 Form 的角图标及其任务栏图标(请记住,当 Application->MainFormOnTaskbar 为 false 时,任务栏按钮由隐藏的 Application 窗口控制,而不是 MainForm 窗口,除非您手动覆盖该行为)实际上是操作系统层的独立图标,通过WM_SETICON消息使用不同的输入参数(分别为wParam=ICON_SMALLwParam=ICON_BIG)分配。然而,VCL 只使用WM_SETICON 来设置窗口的大图标,而不是它的小图标。所以Form 的角图标只是其任务栏图标的缩小版本(当MainFormOnTaskbar 为真时)或Application 的任务栏按钮(当MainFormOnTaskbar 为假时)。当VCL为Form发出WM_SETICON时,它使用Form自己的Icon,否则它使用ApplicationIcon,否则它使用LoadIcon()加载默认的IDI_APPLICATION 图标。

所以,如果你真的想为Form 的角图标和任务栏图标使用不同分辨率的不同图标,你将不得不使用单独的TIcon 对象来加载所需分辨率的图像,如上所述,然后相应地发出您自己的WM_SETICON 消息。

【讨论】:

  • RC3_STOCKICON 和 RC3_ICON 是什么意思?
  • 谢谢。我了解更新,但我不清楚的最后一件事是主窗口如何从编译的资源中加载小图标(要重现这个,只需制作一个空白项目并添加一个带有大图标和小图标的图标通过项目属性 > 图标)。必须有代码可以读取这两个图标并将一个分配给角落。
  • 没有这样的代码。正如我所说,VCL 只处理大图标。自己研究 VCL 源代码,你会发现这是真的。至于项目属性中的图标,TApplication构造函数通过LoadIcon()函数将MAINICON资源加载到TApplication.Icon属性中,所以它的使用以我上面提到的细节为准。
  • 那么您如何解释 Small 出现了不同的图标? (如果需要,我可以发布截图作为证据)
  • VCL源码中没有设置小图标的,只有大图标。 HICON 代表特定大小的图像,它不能引用多个图像,并且分配给项目属性的 .ICO 文件被拆分为每个图像的单独资源。因此,无论是允许小图标和大图标在没有 VCL 明确分配它们的情况下引用不同图像的技巧,都必须在操作系统层进行处理。由于您想在运行时显式加载它们,因此您也必须显式分配它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-03
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多