0

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

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

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

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

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

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

4

1 回答 1

1

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

如果图标数据表示类型的图标RC3_STOCKICON(通常不会遇到),则使用IDI_APPLICATION图标 from LoadIcon()。否则,如果图标数据表示类型的图标(通常情况下),则解析数据并传递与当前和属性值RC3_ICON最匹配的图像(如果尚未分配维度,则传递和指标)到.TIcon.WidthTIcon.HeightSM_CXICONSM_CYICONGetSystemMetrics()TIconCreateIcon()

从那时起,orHICON返回的图像将用于 的剩余生命周期,或者至少直到通过, , ,等释放/释放。LoadIcon()CreateIcon()TIconHICONTIcon.ReleaseHandle()TIcon.Assign()TIcon.LoadFrom...()TIcon.SetHandle()

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

更新TIcon不能同时加载多个不同分辨率的图像。AForm的角图标及其任务栏图标(请记住,当Application->MainFormOnTaskbar为 false 时,任务栏按钮由隐藏Application窗口控制,而不是由MainForm窗口控制,除非您手动覆盖该行为)实际上是操作系统层上的单独图标,通过WM_SETICON消息使用不同的输入参数(wParam=ICON_SMALLwParam=ICON_BIG,分别)。然而,VCL 只WM_SETICON用于设置窗口的大图标,从不设置小图标。因此, 的角图标只是其任务栏图标(何时为真)或的任务栏按钮(何时为假)Form的缩小版本。当 VCL 发出一个MainFormOnTaskbarApplicationMainFormOnTaskbarWM_SETICONForm, 如果已分配,则使用Form's own Icon,否则,如果已分配,则使用Application's Icon,否则LoadIcon()用于加载默认IDI_APPLICATION图标。

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

于 2014-12-10T01:04:10.390 回答