从 RES 文件加载图标后,错误的图标用作默认图标
Wrong icon used as default icon after loading icons from a RES file
我正在尝试创建一个自定义组件,当鼠标移到它上面时会显示一个图标。
我正在加载这样的图标:
UNIT Test;
constructor TTestPath.Create(aOwner: TComponent);
VAR myIcon: TIcon;
begin
inherited Create(aOwner);
ImgList:= TImageList.Create(Self);
myicon := TIcon.Create;
TRY
myicon.LoadFromResourceName(HInstance, 'FOLDER'); <------ this becomes application's icon!
ImgList.AddIcon(myicon);
FINALLY
FreeAndNil(myicon);
end;
问题是,一旦我将 Test.pas 添加到我的测试应用程序的 USES 原因中,应用程序的图标(红色 delphi 头盔)就会被 'FOLDER' 图标替换。
更新:
EXE 文件中的图标顺序为:'FOLDER'、Default_Delphi_icon
因此,TTestPath 的图标被添加到应用程序图标之前的 exe。
这里有什么问题:TTestPath 的图标以这种方式出现在 EXE 文件中,或者它位于应用程序的(默认)图标之前?
控件代码如下:
UNIT test;
INTERFACE
USES
System.SysUtils, Winapi.Windows, System.Classes, Vcl.StdCtrls, Vcl.Controls, Vcl.Graphics, vcl.imglist, Vcl.ExtCtrls; {$WARN GARBAGE OFF} {Silent the: 'W1011 Text after final END' warning }
TYPE
TValidity= (vaNone, vaValid, vaInvalid); { Normal / Green / Red color }
TInputType= (itFile, itFolder); { What kind of path will the user type in this control: folder or file }
TTestPath = class(TCustomGroupBox)
private
edtPath : TButtonedEdit;
btnApply : TButton;
btnExplore : TButton;
FInputType : TInputType;
imgList : TImageList;
FShowApplyBtn: Boolean;
protected
public
constructor Create(aOwner: TComponent); override;
published
property Align;
property Anchors;
property BiDiMode;
property Caption;
property Color;
property Constraints;
property Ctl3D;
property DockSite;
property DoubleBuffered;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Font;
property Padding;
property ParentBackground default True;
property ParentBiDiMode;
property ParentColor;
property ParentCtl3D;
property ParentDoubleBuffered;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Touch;
property Visible;
property StyleElements;
property OnAlignInsertBefore;
property OnAlignPosition;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDockDrop;
property OnDockOver;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnGesture;
property OnGetSiteInfo;
property OnMouseActivate;
property OnMouseDown;
property OnMouseEnter;
property OnMouseLeave;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
property OnUnDock;
end;
procedure Register;
IMPLEMENTATION {$R cPathEdit.res}
USES cIO;
constructor TTestPath.Create(aOwner: TComponent);
VAR myIcon: TIcon;
begin
inherited Create(aOwner);
Caption := 'Folder';
Height:= 41;
FShowApplyBtn:= TRUE;
ImgList:= TImageList.Create(Self); { Freed by Self }
myicon := TIcon.Create;
TRY
myicon.LoadFromResourceName(HInstance, 'FOLDER');
ImgList.AddIcon(myicon);
myicon.LoadFromResourceName(HInstance, 'FOLDER_OPEN');
ImgList.AddIcon(myicon);
FINALLY
FreeAndNil(myicon);
end;
edtPath:= TButtonedEdit.Create(Self);
WITH edtPath DO
begin
Parent := Self;
Align := alClient;
Margins.Left := 1;
Margins.Top := 2;
Margins.Right := 1;
Margins.Bottom := 1;
AlignWithMargins := TRUE;
Images := imgList;
TabOrder := 0 ;
OnChange := nil;
RightButton.Hint := 'Browse for a folder';
RightButton.ImageIndex:= 0;
RightButton.HotImageIndex:= 1;
RightButton.Visible := TRUE;
OnRightButtonClick := nil;
OnKeyPress := nil;
end;
btnExplore:= TButton.Create(Self);
WITH btnExplore DO
begin
Parent := Self;
Align := alRight;
Width := 22;
Margins.Left := 1;
Margins.Top := 1;
Margins.Right := 1;
Margins.Bottom := 1;
AlignWithMargins := TRUE;
Caption := '^';
TabOrder := 1;
Hint := 'Open this folder in Windows Explorer';
OnClick := nil;
end;
btnApply:= TButton.Create(Self);
WITH btnApply DO
begin
Parent := Self;
Align := alRight;
Width := 38;
Margins.Left := 1;
Margins.Top := 1;
Margins.Right := 1;
Margins.Bottom := 1;
AlignWithMargins := TRUE;
Hint := 'Create folder if necessary';
Caption := 'Apply';
TabOrder := 2;
OnClick := nil;
end;
FInputType:= itFolder;
end;
procedure Register;
begin
RegisterComponents('xxx', [TTestPath]);
end;
end.
测试应用:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, Forms,
test; <-------- this
type
TForm1 = class(TForm)
private
public
end;
var
Form1: TForm1;
IMPLEMENTATION
{$R *.dfm}
end.
由于 Embarcadero 的一个相当混乱的决定,图标资源在链接时按字母顺序排序。 Windows 规则是 shell 用于可执行文件的图标是第一个图标。 Delphi VCL 代码假定应用程序图标名为 'MAINICON'
。
将这些要求放在一起,您可以推断出所有图标的名称必须按字母顺序出现在 'MAINICON'
之后。
这很令人沮丧,但很容易解决。为您的图标采用合适的命名约定,一切都会如您所愿。
为什么 Embarcadero 不更改他们的代码以确保首先发出名为 'MAINICON'
的图标,这超出了我的理解范围。或者安排应用程序图标被定义为第一个,从而遵循平台的规则。但我们无能为力。
我正在尝试创建一个自定义组件,当鼠标移到它上面时会显示一个图标。 我正在加载这样的图标:
UNIT Test;
constructor TTestPath.Create(aOwner: TComponent);
VAR myIcon: TIcon;
begin
inherited Create(aOwner);
ImgList:= TImageList.Create(Self);
myicon := TIcon.Create;
TRY
myicon.LoadFromResourceName(HInstance, 'FOLDER'); <------ this becomes application's icon!
ImgList.AddIcon(myicon);
FINALLY
FreeAndNil(myicon);
end;
问题是,一旦我将 Test.pas 添加到我的测试应用程序的 USES 原因中,应用程序的图标(红色 delphi 头盔)就会被 'FOLDER' 图标替换。
更新:
EXE 文件中的图标顺序为:'FOLDER'、Default_Delphi_icon
因此,TTestPath 的图标被添加到应用程序图标之前的 exe。
这里有什么问题:TTestPath 的图标以这种方式出现在 EXE 文件中,或者它位于应用程序的(默认)图标之前?
控件代码如下:
UNIT test;
INTERFACE
USES
System.SysUtils, Winapi.Windows, System.Classes, Vcl.StdCtrls, Vcl.Controls, Vcl.Graphics, vcl.imglist, Vcl.ExtCtrls; {$WARN GARBAGE OFF} {Silent the: 'W1011 Text after final END' warning }
TYPE
TValidity= (vaNone, vaValid, vaInvalid); { Normal / Green / Red color }
TInputType= (itFile, itFolder); { What kind of path will the user type in this control: folder or file }
TTestPath = class(TCustomGroupBox)
private
edtPath : TButtonedEdit;
btnApply : TButton;
btnExplore : TButton;
FInputType : TInputType;
imgList : TImageList;
FShowApplyBtn: Boolean;
protected
public
constructor Create(aOwner: TComponent); override;
published
property Align;
property Anchors;
property BiDiMode;
property Caption;
property Color;
property Constraints;
property Ctl3D;
property DockSite;
property DoubleBuffered;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Font;
property Padding;
property ParentBackground default True;
property ParentBiDiMode;
property ParentColor;
property ParentCtl3D;
property ParentDoubleBuffered;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Touch;
property Visible;
property StyleElements;
property OnAlignInsertBefore;
property OnAlignPosition;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDockDrop;
property OnDockOver;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnGesture;
property OnGetSiteInfo;
property OnMouseActivate;
property OnMouseDown;
property OnMouseEnter;
property OnMouseLeave;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
property OnUnDock;
end;
procedure Register;
IMPLEMENTATION {$R cPathEdit.res}
USES cIO;
constructor TTestPath.Create(aOwner: TComponent);
VAR myIcon: TIcon;
begin
inherited Create(aOwner);
Caption := 'Folder';
Height:= 41;
FShowApplyBtn:= TRUE;
ImgList:= TImageList.Create(Self); { Freed by Self }
myicon := TIcon.Create;
TRY
myicon.LoadFromResourceName(HInstance, 'FOLDER');
ImgList.AddIcon(myicon);
myicon.LoadFromResourceName(HInstance, 'FOLDER_OPEN');
ImgList.AddIcon(myicon);
FINALLY
FreeAndNil(myicon);
end;
edtPath:= TButtonedEdit.Create(Self);
WITH edtPath DO
begin
Parent := Self;
Align := alClient;
Margins.Left := 1;
Margins.Top := 2;
Margins.Right := 1;
Margins.Bottom := 1;
AlignWithMargins := TRUE;
Images := imgList;
TabOrder := 0 ;
OnChange := nil;
RightButton.Hint := 'Browse for a folder';
RightButton.ImageIndex:= 0;
RightButton.HotImageIndex:= 1;
RightButton.Visible := TRUE;
OnRightButtonClick := nil;
OnKeyPress := nil;
end;
btnExplore:= TButton.Create(Self);
WITH btnExplore DO
begin
Parent := Self;
Align := alRight;
Width := 22;
Margins.Left := 1;
Margins.Top := 1;
Margins.Right := 1;
Margins.Bottom := 1;
AlignWithMargins := TRUE;
Caption := '^';
TabOrder := 1;
Hint := 'Open this folder in Windows Explorer';
OnClick := nil;
end;
btnApply:= TButton.Create(Self);
WITH btnApply DO
begin
Parent := Self;
Align := alRight;
Width := 38;
Margins.Left := 1;
Margins.Top := 1;
Margins.Right := 1;
Margins.Bottom := 1;
AlignWithMargins := TRUE;
Hint := 'Create folder if necessary';
Caption := 'Apply';
TabOrder := 2;
OnClick := nil;
end;
FInputType:= itFolder;
end;
procedure Register;
begin
RegisterComponents('xxx', [TTestPath]);
end;
end.
测试应用:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, Forms,
test; <-------- this
type
TForm1 = class(TForm)
private
public
end;
var
Form1: TForm1;
IMPLEMENTATION
{$R *.dfm}
end.
由于 Embarcadero 的一个相当混乱的决定,图标资源在链接时按字母顺序排序。 Windows 规则是 shell 用于可执行文件的图标是第一个图标。 Delphi VCL 代码假定应用程序图标名为 'MAINICON'
。
将这些要求放在一起,您可以推断出所有图标的名称必须按字母顺序出现在 'MAINICON'
之后。
这很令人沮丧,但很容易解决。为您的图标采用合适的命名约定,一切都会如您所愿。
为什么 Embarcadero 不更改他们的代码以确保首先发出名为 'MAINICON'
的图标,这超出了我的理解范围。或者安排应用程序图标被定义为第一个,从而遵循平台的规则。但我们无能为力。