Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi表单图标在Windows 7';s任务栏(启用MainFormOnTaskbar)_Delphi_Windows 7_Icons_Taskbar - Fatal编程技术网

Delphi表单图标在Windows 7';s任务栏(启用MainFormOnTaskbar)

Delphi表单图标在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编写的Windows桌面应用程序,它在Windows7上运行良好,只是主窗体的图标在Windows的新任务栏中看起来很模糊。只要应用程序尚未启动,图标看起来就正常(即,当它固定在任务栏上时)。一旦启动,Windows就会使用主窗体的图标(而不是.exe资源图标),而且它很模糊(看起来像是放大了16x16版本的图标)

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


我的理论是,当我在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的方法不太管用,我们会使用它。