Delphi表单图标在Windows 7';s任务栏(启用MainFormOnTaskbar)
我们有一个用Delphi编写的Windows桌面应用程序,它在Windows7上运行良好,只是主窗体的图标在Windows的新任务栏中看起来很模糊。只要应用程序尚未启动,图标看起来就正常(即,当它固定在任务栏上时)。一旦启动,Windows就会使用主窗体的图标(而不是.exe资源图标),而且它很模糊(看起来像是放大了16x16版本的图标) 我们用于.exe和主窗体的图标完全相同,它包含各种分辨率,包括带有alpha混合的48x48Delphi表单图标在Windows 7';s任务栏(启用MainFormOnTaskbar),delphi,windows-7,icons,taskbar,Delphi,Windows 7,Icons,Taskbar,我们有一个用Delphi编写的Windows桌面应用程序,它在Windows7上运行良好,只是主窗体的图标在Windows的新任务栏中看起来很模糊。只要应用程序尚未启动,图标看起来就正常(即,当它固定在任务栏上时)。一旦启动,Windows就会使用主窗体的图标(而不是.exe资源图标),而且它很模糊(看起来像是放大了16x16版本的图标) 我们用于.exe和主窗体的图标完全相同,它包含各种分辨率,包括带有alpha混合的48x48 我的理论是,当我在Delphi中为主窗体导入.ico文件时,De
我的理论是,当我在Delphi中为主窗体导入.ico文件时,Delphi会忽略/删除图标的额外分辨率。有没有办法防止/解决这个问题?确保用Delphi编写的应用程序在Windows 7任务栏中使用正确的图标分辨率的最佳方法是什么?要做到这一点可能有点像噩梦。我发现,最成功的策略是在主窗体和应用程序上放置一个非常简单的图标,然后将ReplaceVistaIcon程序合并到构建工作流中,以便在构建完成后(以及在签署exe之前)使用多图标文件替换图标。这似乎正确地放置了图标,以便Windows优先于任何其他图标资源选择它。必须这样做是一件麻烦事,但一旦(在我们的FinalBuilder项目中)建立起来,它就为我们工作了
在测试时,令人恼火的问题是,您可能必须删除Windows图标缓存才能查看任何更改的效果。这涉及到关闭资源管理器以允许您从命令会话中删除缓存文件。问题在于VCL中的延迟编程不适合操作系统的行为变化。或多或少是这样的, TCustomForm.CreateWnd,在创建窗口句柄后,调用
SendMessage(Handle, WM_SETICON, 1, LPARAM(GetIconHandle)) else
请注意wParam中的“1”,这是一个大图标。实际上,VCL设置窗体的大图标。但是图标请求的大小(TIcon.FRequestedSize)是16x16(默认情况下),因此表单的TIcon返回小图标的句柄。这是系统小图标的大小,在构造函数CreateNew中通过调用GetSystemMetrics确定
因为早期版本的Windows使用了任务栏上的小图标,所以这没有问题。但是,Alt+Tab对话框的问题恰恰相反;如果将图标指定给窗体,则在Alt+Tab对话框中会显示“模糊”。无论如何,默认情况下,Windows 7仍然会为小图标(SM_CXSMICON/SM_CYSMICON)返回16x16,为大图标(SM_CXSMICON/SM_CYSMICON)返回32x32,但如果存在大图标,则大任务栏会显示大图标
正确的方法是为大图标分配一个大图像(如果图标中有),并为小图标分配一个小图像(如果有)。当然,由于大小不必精确匹配,因此需要复杂的算法。相反,实现了一个更简单但不完整的设计。
为了解决这个问题,我没有给OI中的表单指定图标,而是使用这个图标
procedure SetFormIcons(FormHandle: HWND; SmallIconName, LargeIconName: string);
var
hIconS, hIconL: Integer;
begin
hIconS := LoadIcon(hInstance, PChar(SmallIconName));
if hIconS > 0 then begin
hIconS := SendMessage(FormHandle, WM_SETICON, ICON_SMALL, hIconS);
if hIconS > 0 then
DestroyIcon(hIconS);
end;
hIconL := LoadIcon(hInstance, PChar(LargeIconName));
if hIconL > 0 then begin
hIconL := SendMessage(FormHandle, WM_SETICON, ICON_BIG, hIconL);
if hIconL > 0 then
DestroyIcon(hIconL);
end;
end;
并在项目中包含一个名为“icons.res”的图标,该图标具有16x16和32x32图像。OnCreate调用中的所有窗体
SetFormIcons(Handle, 'MYFORM', 'MYFORM');
有趣的是,我发现的解决方案就是不为表单设置图标,而且使用应用程序的图标似乎效果更好。现在我将检查Win7中的解决方案。@mj2008-您的解决方案也适用于W7。我忽略了Dennis提到他为应用程序和表单分配了相同的图标。在这种情况下,这将是更简单的解决方案。我的解决方案只有在需要为表单指定不同的图标时才有意义。OP and answer已经很久了,但我想指出的是,这个解决方案似乎不适用于使用VCL样式的用户。关闭样式,解决方案就会起作用。要修复VCL样式,请参阅@spurgeon-感谢链接。+1谢谢或建议,如果Sertac的方法不太管用,我们会使用它。