代码之家  ›  专栏  ›  技术社区  ›  Dennis G.

Windows 7任务栏上的Delphi窗体图标模糊(启用MainFormontaskBar)

  •  13
  • Dennis G.  · 技术社区  · 15 年前

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

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

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

    2 回复  |  直到 15 年前
        1
  •  10
  •   Sertac Akyuz    15 年前

    问题在于VCL中的惰性编程不适合操作系统的行为变化。或多或少是这样的;

    tcustomform.createwnd,创建窗口句柄后,调用;

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

    注意wparam中的“1”,这是icon_big。实际上,vcl设置窗体的大图标。但是图标的请求大小(ticon.frequestedsize)是16x16(默认情况下),因此表单的ticon返回小图标的句柄。这是系统小图标的大小,在调用getSystemMetrics的构造函数createNew中确定。

    由于早期版本的windows使用了任务栏上的小图标,这没有问题。然而alt+tab对话框有另一个问题;如果一个图标被分配给一个窗体,它在alt+tab对话框中显示“模糊”。无论如何,默认情况下,Windows7仍然会返回16x16作为小图标(sm_cxsmicon/sm_cysmicon)和32x32作为大图标(sm_cxicon/sm_cyicon),但如果有大图标,则大任务栏会显示大图标。

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


    为了解决这个问题,我没有给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');
    
        2
  •  3
  •   frogb    15 年前

    把这件事做好可能有点像噩梦。我发现最成功的策略是在主窗体和应用程序上放置一个非常简单的图标,然后将replaceVistaIcon程序合并到生成工作流中,以便在生成完成后(以及在签署exe之前)用多图标文件替换该图标。这似乎正确地放置了图标,以便Windows优先于任何其他图标资源来获取它。不得不这样做是件麻烦事,但一旦(在我们的finalbuilder项目中)建立起来,它就对我们起作用了。

    当您测试这个的时候,令人恼火的问题是您可能必须删除windows图标缓存才能看到任何更改的效果。这包括关闭资源管理器以允许您从命令会话中删除缓存文件。