TIcon仅从图标文件加载一个图像

时间:2014-12-09 22:27:57

标签: icons vcl c++builder-xe5

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

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

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

但是,如果我将filename.ico设置为已编译的资源,或者我在Project Properties>中设置了图标。申请>图标,然后我的表格使用角落图标的24x24图标和任务栏的48x48图标。

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

NB。我不想硬编码这些尺寸24x24和48x48,因为其他版本的Windows(或者如果此人使用Windows字体缩放选项)可能会调用不同大小的图标。

1 个答案:

答案 0 :(得分:1)

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

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

从那时起,HICONLoadIcon()返回的CreateIcon()是用于TIcon生命周期剩余时间的图像,或者至少在通过HICONTIcon.ReleaseHandle()TIcon.Assign()TIcon.LoadFrom...()等方式释放/发布TIcon.SetHandle()

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

更新TIcon无法同时加载多个不同分辨率的图像。一个Form的角点图标及其任务栏图标(请记住,当Application->MainFormOnTaskbar为false时,任务栏按钮由隐藏的Application窗口控制,而不是MainForm窗口,除非您手动覆盖该行为)实际上是OS层的单独图标,通过WM_SETICON消息使用不同的输入参数(分别为wParam=ICON_SMALLwParam=ICON_BIG)分配。但是,VCL只使用WM_SETICON来设置窗口的BIG图标,而不是它的SMALL图标。因此,Form的角落图标只是其任务栏图标的缩小版本(当MainFormOnTaskbar为真时)或Application的任务栏按钮(MainFormOnTaskbar为时)假)。当VCL为WM_SETICON发出Form时,如果已分配,则会使用Form自己的Icon,否则会使用Application的{​​{1}}如果已分配,则使用Icon加载默认的LoadIcon()图标。

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