Windows 7 的任务栏上的 Delphi 表单图标模糊(启用 MainFormOnTaskbar) [英] Delphi form icons are blurry on Windows 7's taskbar (with MainFormOnTaskbar enabled)

查看:13
本文介绍了Windows 7 的任务栏上的 Delphi 表单图标模糊(启用 MainFormOnTaskbar)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We have a Windows desktop application written in Delphi that works fine on Windows 7, except that the icon of the main form looks blurry in Windows' new taskbar. As long as the application has not been started the icon looks fine (i.e. when it's pinned to the taskbar). Once it has been started Windows uses the icon of the main form (instead of the .exe resource icon) and it's blurry (it looks like a 16x16 version of the icon is scaled up).

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

The icon that we use for the .exe and for the main form are exactly the same and it contains all kinds of resolutions, including 48x48 with alpha blending.

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

My theory is that Delphi ignores/deletes the extra resolutions of the icon when I import the .ico file for the main form in Delphi. Is there a way to prevent/fix this? What's the best way to ensure that an application written in Delphi uses the correct icon resolution in Windows 7's taskbar?

推荐答案

问题在于 VCL 内部的惰性编程不适应操作系统的行为变化.或多或少是这样的;

The problem lies within lazy programming within the VCL not fitting with the behavioral change of the OS. More or less it is like this;

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

TCustomForm.CreateWnd, after the window handle is created, calls;

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

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

Notice the "1" in place of wParam, that's ICON_BIG. Actually the VCL sets the large icon of the form. But the icon's requested size (TIcon.FRequestedSize) is 16x16 (by default), and so the TIcon of the form returns a handle for the small icon. That's the size for the system small icon and is determined in the constructor CreateNew with calls to GetSystemMetrics.

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

Since earlier versions of Windows used the small icon on the taskbar this was no problem. Hovewer the Alt+Tab dialog had the problem other way around; if an icon was assigned to a form it showed "blurred" in the Alt+Tab dialog. Anyway, Windows 7, still, by default returns 16x16 for the small icon (SM_CXSMICON/SM_CYSMICON) and 32x32 for the large icon (SM_CXICON/SM_CYICON), but the large taskbar displays the large icon, if there is one that is..

正确的做法是为大图标分配一张大图(如果图标中有一张),给小图标分配一张小图(如果有的话).当然,由于大小不必完全匹配,因此这需要复杂的算法.取而代之的是,实现了一个更简单但被破坏的设计.


作为一种解决方法,我没有为 OI 中的表单分配图标,而是使用它;

The correct approach would be to assign a large image (if there is one in the icon) for the large icon and assign a small image (if there is one) to the small icon. Granted, since the sizes would not have to have exact matches, this would require a complex algorithm. Instead, a simpler but broken design is implemented.


For a workaround, I don't assign an icon to the forms in the OI and instead use this;

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 调用中的所有表单

and include an "icons.res" with named icons having 16x16 and 32x32 images, in the project. All the forms in their OnCreate call

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

这篇关于Windows 7 的任务栏上的 Delphi 表单图标模糊(启用 MainFormOnTaskbar)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆