我的应用程序有2个表单,每个表单和应用程序都有单独的图标。在Form1BitBtn1.Click Form2上显示 - 非模式和Form1BitBtn2.Click Form1已关闭。在Form2BitBtn1.Click Form2已关闭,Form2BitBtn2.Click Form1已关闭。它工作正常。但问题是在Windows 7任务栏中,Form1图标是模糊的,另一个问题是当使用Form1BitBtn1显示Form2时。单击该应用程序仅显示Form1图标但不显示Form2图标。 请帮帮我。
以下是我的项目文件的下载链接是“http://hotfile.com/dl/140219264/04ce49c/Delphi_XE2_Form_Handler.7z.html”
我的代码如下:
unit KoushikHalder01;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls,
Vcl.ComCtrls;
type
TForm01 = class(TForm)
BitBtn01: TBitBtn;
BitBtn02: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
procedure FormHide(Sender: TObject);
procedure BitBtn01MouseEnter(Sender: TObject);
procedure BitBtn02MouseEnter(Sender: TObject);
procedure BitBtn01MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure BitBtn02MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure BitBtn01MouseLeave(Sender: TObject);
procedure BitBtn02MouseLeave(Sender: TObject);
procedure BitBtn02Click(Sender: TObject);
procedure BitBtn01Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form01: TForm01;
implementation
{$R *.dfm}
uses KoushikHalder02;
procedure TForm01.BitBtn01Click(Sender: TObject);
begin
Doublebuffered := True;
Form02.Show;
if Form01.Visible = true then Form01.BringToFront;
end;
procedure TForm01.BitBtn01MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
BitBtn01.Font.Color :=10379745;
end;
procedure TForm01.BitBtn01MouseEnter(Sender: TObject);
begin
BitBtn01.Font.Color :=16711825;
end;
procedure TForm01.BitBtn01MouseLeave(Sender: TObject);
begin
BitBtn01.Font.Color :=15756035;
end;
procedure TForm01.BitBtn02Click(Sender: TObject);
begin
Form01.Close;
end;
procedure TForm01.BitBtn02MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
BitBtn02.Font.Color :=10379745;
end;
procedure TForm01.BitBtn02MouseEnter(Sender: TObject);
begin
BitBtn02.Font.Color :=16711825;
end;
procedure TForm01.BitBtn02MouseLeave(Sender: TObject);
begin
BitBtn02.Font.Color :=15756035;
end;
procedure TForm01.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Doublebuffered := True;
end;
procedure TForm01.FormCreate(Sender: TObject);
begin
Doublebuffered := True;
end;
procedure TForm01.FormHide(Sender: TObject);
begin
Doublebuffered := True;
end;
procedure TForm01.FormShow(Sender: TObject);
begin
Doublebuffered := True;
end;
end.
答案 0 :(得分:7)
我知道如何解决这个问题......而且很简单。 不要为Form1.Icon提供图标。
在
中提供您的图标信息项目>选项>申请>应用程序图标设置>加载 图标。
请务必为您的图标选择最佳分辨率。
运行应用程序并使用shazan!
答案 1 :(得分:6)
在我看来,由于VCL框架中的设计缺陷,这里发生了什么。底层的Windows框架不会为每个顶级窗口维护一个,而是两个图标。这些图标通过窗口类(请参阅WNDCLASSEX
)或WM_SETICON
消息与窗口相关联。
VCL框架总是调用WM_SETICON
传递ICON_BIG
,因此只分配了大图标。对于Windows 7,任务栏上使用大图标,窗口标题栏上使用小图标。在具有较小任务栏的早期版本的Windows上,任务栏上使用了小图标。对于100%字体缩放,大图标为32px,小图标为16px。对于大字体,所需的图标大小会更改。
现在,如果应用程序仅提供所需图标之一,系统将在需要绘制尚未提供的图标大小时缩放提供的图标。如果您只提供一个大图标,通常,生成的缩放小图标看起来很好。如果你只提供一个小图标,那么它就难以扩展,通常会发生的是小图标(显示在标题栏上)看起来很好,但是大图标是像素化的。
事实上,发生在你身上的不是这些问题。 VCL代码意味着您始终在Windows中为大图标指定。但是,你显然提供了一个小图标,几乎可以肯定是16px。这与使用WM_SETICON
调用ICON_SMALL
并且像素化的32px图标具有相同的结果。
最简单的解决方案是在Form.Icon
或Application.Icon
中使用32px图标,无论您在何处设置图标。这在大多数情况下都可以正常工作。
但是,如果您的应用程序运行时字体缩放处于活动状态,那么您将再次遇到像素化。通过字体缩放,可以增加两个图标大小。为了正确处理这个问题,您必须向底层Windows框架提供正确大小的图标。如果没有,则会出现像素化现象。您可以致电GetSystemMetrics
了解图标大小。
SmallIconSize := GetSystemMetrics(SM_CXSMICON);
LargeIconSize := GetSystemMetrics(SM_CXICON);
现在通常只需提供一个大图标并依靠内置缩放来生成小图标。如果你真的关心视觉效果,你当然应该使用专为这么小的尺寸准备的图标。缩小到16px的32px图标在视觉上不如熟练的视觉设计师生成的16px图标有效。要使VCL使用您提供的小图标需要额外的工作。具体而言,您需要发送WM_SETICON
ICON_SMALL
。在我的代码库中,我执行此操作,实际上完全避免使用TForm.Icon
并为两个图标大小调用WM_SETICON
。为了获得所需的细粒度控制,VCL机制只是干涉。
答案 2 :(得分:1)
我最好的猜测是你的表单图标大小为16x16,并且从16x16扩展到大约48x48,导致你所谓的“模糊外观”,但这是输入时的标准Windows行为(你的图标)形式或应用)分辨率非常低。
图标在同一.ico文件中可以有多种分辨率。因此,请将当前图标替换为尺寸为16x16,32x32和48x48的图标。这个窗口将能够显示正确的全分辨率图像。 Windows使用的现代图标还可能包括一些较大的Vista / Win7图标,大小高达256x256。 更新 OP报告图标已经具有所有正确的尺寸,并且在此处的其他答案中确实显示您正在遇到VCL内部处理问题,正如David在回答中提到的那样。
简而言之,Windows就是这样做的,因为你没有办法避免它。它是模糊或像素化的选择。窗口内的“拉伸”代码会导致模糊,正是为了避免在不模糊时产生的块状外观。
答案 3 :(得分:0)
TL; DR版本:不要将Icon
属性设置为除通过从包含多个图标大小的Win32资源加载获得的值之外的任何值。例如,仅使用TIcon.LoadFromResourceName
。如果在表单设计器中设置Icon
属性,则只会使用一个图标大小,从而导致缩放工件。
多年来,VCL一直不支持具有多种图标大小的图标图形的概念:TIcon
始终被认为是一个单独的图形 - 而不是一组不同尺寸和分辨率的图形。这仍然是正确的,在VCL中可能不容易纠正设计问题。
VCL将通过WM_SETICON
消息设置表单图标。 VCL始终将wParam
设置为ICON_BIG
:对VCL来源的检查表明,在设置图标时,它永远不会使用ICON_SMALL
。此外,创建窗口类时,hIcon
结构的hIconSm
和WNDCLASSEX
成员变量始终为NULL
。因此,很明显,VCL甚至都没有试图设置一个小图标。通常情况下,如果应用程序从不设置小图标,Windows会将大图标调整为小尺寸,这非常难看。但是,该规则有一个重要的例外。
请注意,Windows资源文件的ICON
资源实际上会存储所谓的图标组,这是一组来自原始.ico
的单个图标图像文件。 LoadIcon
API声明只会加载大型32x32图标。然而,这实际上并不严格。似乎Windows本身在HICON
和原始资源之间保持链接,因此如果需要其他大小的图标,Windows可以根据需要加载它们。
这个事实没有详细记录,但MSDN中有一个地方陈述了这一事实:WNDCLASSEX
structure,hIconSm
变量:
与窗口类关联的小图标的句柄。如果此成员为NULL,系统将搜索hIcon成员指定的图标资源,以获取适当大小的图标,以用作小图标。
因此,即使VCL不能通过公共TForm.Icon
类正确支持小图标(例如,通过在设计时从属性编辑器中分配它),仍然可以使用一个正常工作。这两种方法:
保持TForm.Icon
属性未设置(无图标)。在这种情况下,表单将从TApplication.Icon
获取图标。默认值来自应用程序的MAINICON
资源。来自TApplication.Create
:
FIcon := TIcon.Create;
FIcon.Handle := LoadIcon(MainInstance, 'MAINICON');
如果您不想使用应用程序默认图标,则可以在运行时加载不同的图标资源;在C ++中:
myForm->Icon->LoadFromResourceName(FindHInstance(...), L"OtherResource");
因此,VCL为小图标提供基本支持,因为它支持从资源加载图标,Windows支持从资源加载的大图标中加载小图标。
如果您使用的是VCL样式,请参阅我在此处对相关错误的回答: https://stackoverflow.com/a/35067909/562766