Windows 7的任务栏上的Delphi表单图标模糊(启用了MainFormOnTaskbar)

时间:2010-04-12 11:57:45

标签: delphi windows-7 icons taskbar

我们有一个用Delphi编写的Windows桌面应用程序在Windows 7上运行正常,只是主窗体的图标在Windows的新任务栏中看起来很模糊。只要应用程序尚未启动,图标就会很好(即当它固定在任务栏上时)。一旦启动,Windows将使用主窗体的图标(而不是.exe资源图标),并且模糊(看起来图标的16x16版本会放大)。

我们用于.exe和主窗体的图标完全相同,它包含各种分辨率,包括带有alpha混合的48x48。

我的理论是,当我在Delphi中导入主窗体的.ico文件时,Delphi会忽略/删除图标的额外分辨率。有没有办法防止/解决这个问题?确保用Delphi编写的应用程序在Windows 7任务栏中使用正确的图标分辨率的最佳方法是什么?

2 个答案:

答案 0 :(得分:10)

问题在于VCL内的懒惰编程不适合OS的行为变化。或多或少是这样的;

TCustomForm.CreateWnd,在创建窗口句柄后,调用;

  SendMessage(Handle, WM_SETICON, 1, LPARAM(GetIconHandle)) else

注意“1”代替wParam,即ICON_BIG。实际上VCL设置了表单的大图标。但是图标的请求大小(TIcon.FRequestedSize)是16x16(默认情况下),因此表单的TIcon返回小图标的句柄。这是系统小图标的大小,在构造函数CreateNew中通过调用GetSystemMetrics确定。

由于早期版本的Windows使用任务栏上的小图标,因此没有问题。 Hovewer Alt + Tab对话框有其他问题;如果图标已分配给表单,则在Alt + Tab对话框中显示“模糊”。无论如何,Windows 7仍默认为小图标(SM_CXSMICON / SM_CYSMICON)返回16x16,大图标(SM_CXICON / SM_CYICON)返回32x32,但是大任务栏显示大图标(如果有的话).. < / p>

正确的方法是为大图标分配一个大图像(如果图标中有一个),并为小图标指定一个小图像(如果有的话)。当然,由于尺寸不必具有完全匹配,这将需要复杂的算法。相反,实现了更简单但更破碎的设计。


对于变通方法,我不会在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;

并在项目中包含带有16x16和32x32图像的命名图标的“icons.res”。 OnCreate调用中的所有表单

 SetFormIcons(Handle, 'MYFORM', 'MYFORM');

答案 1 :(得分:3)

这样做可能有点噩梦。我发现最成功的策略是在主窗体和应用程序上放置一个非常简单的图标,然后将ReplaceVistaIcon程序合并到构建工作流程中,在构建完成后用多图标文件替换图标(和在签署exe之前)。这似乎正确地放置了图标,以便Windows优先于任何其他图标资源进行拾取。这是必须要做的,但一旦设置(在我们的FinalBuilder项目中)它对我们有用。

在测试时,令人讨厌的问题是您可能必须删除Windows图标缓存以查看任何更改的效果。这涉及关闭资源管理器以允许您从命令会话中删除缓存文件。