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

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

问题描述

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



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



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

解决方案

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



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));
如果hIconS> 0然后开始
hIconS:= SendMessage(FormHandle,WM_SETICON,ICON_SMALL,hIconS);
如果hIconS> 0然后
DestroyIcon(hIconS);
结束
hIconL:= LoadIcon(hInstance,PChar(LargeIconName));
如果hIconL> 0然后开始
hIconL:= SendMessage(FormHandle,WM_SETICON,ICON_BIG,hIconL);
如果hIconL> 0然后
DestroyIcon(hIconL);
结束
结束

,并在项目中添加一个icons.res和带有16x16和32x32图像的命名图标。 OnCreate调用中的所有表单

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


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).

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.

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?

解决方案

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, after the window handle is created, calls;

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

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.

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..

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;

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的任务栏(启用了MainFormOnTaskbar)的Delphi窗体图标模糊的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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