2016-10-09 116 views
5

Próbuję utworzyć niestandardowy komponent, który po kliknięciu myszy wyświetla ikonę. wczytuję ikony tak:Niepoprawna ikona używana jako ikona domyślna po załadowaniu ikon z pliku RES

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; 

Chodzi o to, że jak tylko dodam Test.pas do zastosowań przyczynę mojej aplikacji testowej, ikona (czerwony kask) Delphi aplikacji zastępuje się „folder ' Ikona.

Aktualizacja:
Ikony w pliku EXE są w następującej kolejności: „Folder”, Default_Delphi_icon Więc ikona TTestPath jest dodany do exe przed ikoną aplikacji.

Co jest nie tak: fakt, że ikona TTestPath jest obecna w ten sposób w pliku EXE lub fakt, że jest umieszczona przed ikoną aplikacji (domyślnie)?


Kod Control poniżej:

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. 

aplikacja testowa:

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

Delphi używa głównej ikony z nazwy zasobu 'MAINICON', która jest pierwszą ikoną. Nazwy ikon są sortowane alfabetycznie. jeśli nazwałeś swoją drugą ikonę jako np. 'X_FOLDER' powinno działać. – kobik

+0

Dziwne, że wszystkie ikony w exe MUSZĄ zaczynać się od "N" (lub wyższego znaku) :) Ale spróbuję tego. Dzięki. – Ampere

+0

Ale czy "FOLDER" powinien być dostępny jako ikona w EXE? – Ampere

Odpowiedz

7

Ze względu na raczej zawiedli decyzji od Embarcadero, zasoby ikony są sortowane alfabetycznie, gdy połączone. Reguła systemu Windows polega na tym, że ikona używana przez powłokę dla pliku wykonywalnego jest pierwszą ikoną. Kod VCL Delphi zakłada, że ​​ikona aplikacji nosi nazwę 'MAINICON'.

Połączyć te wymagania ze sobą i można wywnioskować, że wszystkie ikony muszą mieć nazwy, które pojawiają się po 'MAINICON' w kolejności alfabetycznej.

To dość frustrujące, ale łatwe do obejścia. Zastosuj odpowiednią konwencję nazewnictwa dla swoich ikon i wszystko będzie działać zgodnie z twoim intencją.

Dość, dlaczego Embarcadero nie zmienia kodu, aby upewnić się, że ikona o nazwie 'MAINICON' jest emitowana jako pierwsza, jest poza mną. Można również ustawić, że ikona aplikacji jest zdefiniowana jako pierwsza, a tym samym przestrzegać zasad platformy. Ale nic nie możemy zrobić.

+0

Domyślam się, że opcja "nother" w ogóle nie używa głównej ikony Delphi. i link do mojego własnego pliku zasobów. – kobik

+0

@kobik Myślę, że linker Delphi bierze wszystkie ikony, które dostarczasz, a następnie sortuje według ich nazw. Nie używam głównej ikony Delphi i dostarczam wszystkich moich ikon w jednym pliku res. Ale Delphi zamawia je w wykonywalnym IIRC. –

+0

@kobik - To nie jest trudny problem do zarządzania. Dostępne są rozwiązania (zmień nazwy ikon, nie używaj głównej ikony delphi). Problemem jest wiedza na temat tego problemu. Gdy już masz wiedzę ...... :) :) – Ampere