问题在于VCL中的惰性编程与操作系统的行为变化不匹配。更准确地说,就像这样;
TCustomForm.CreateWnd,在窗口句柄创建后调用;
SendMessage(Handle, WM_SETICON, 1, LPARAM(GetIconHandle)) else
注意,在wParam的位置上有个"1",这是ICON_BIG。实际上,VCL设置了窗体的大图标。但是,图标的请求大小(TIcon.FRequestedSize)默认为16x16,因此窗体的TIcon返回了一个小图标的句柄。这是系统小图标的大小,并在CreateNew构造函数中通过调用GetSystemMetrics来确定。
早期版本的Windows在任务栏上使用小图标,这不是问题。然而,Alt+Tab对话框却相反;如果给窗体分配了图标,则在Alt+Tab对话框中显示为“模糊”。无论如何,在Windows 7中,默认情况下仍然返回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');