2010-11-22 5 views
6

複数のTInnerControlの親であるカスタムコントロールTOuterControlを作成しました。デザイン時にDelphi IDEがコンポーネントアイコンを作成しないようにする

IDEが子TInnerControl(スクリーンショットのInnerControl1とInnerControl2)ごとにアイコンを作成していることを除いて、すべてがうまくいきます。 IDEがアイコンを生成しないようにするにはどうすればよいですか?

alt text

unit TestControl; 

interface 

Procedure Register; 

implementation 

Uses 
    Classes, 
    Controls, 
    SysUtils, 
    DesignEditors, 
    DesignIntf, 
    VCLEditors; 

Type 

TOuterControl = Class; 

TInnerControl = Class(TComponent) 
Protected 
    FOuterControl : TOuterControl; 

    function GetParentComponent: TComponent; Override; 
    Function HasParent : Boolean; Override; 
    procedure SetParentComponent     (Value: TComponent); Override; 
End; 

TOuterControl = Class(TCustomControl) 
Protected 
    FInnerControls : TList; 

    Procedure Paint; Override; 
Public 
    Constructor Create(AOwner : TComponent); Override; 
    Procedure AddInnerControl(AInnerControl : TInnerControl); 
    procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override; 
End; 

TOuterControlEditor = Class(TDefaultEditor) 
Public 
    Procedure ExecuteVerb(Index : Integer);   Override; 
    Function GetVerb (Index : Integer) : String; Override; 
    Function GetVerbCount  : Integer;   Override; 
End; 

procedure TOuterControl.AddInnerControl(AInnerControl: TInnerControl); 
begin 
    AInnerControl.FOuterControl := Self;; 
    FInnerControls.Add(AInnerControl); 
    Invalidate; 
end; 

constructor TOuterControl.Create(AOwner: TComponent); 
begin 
    inherited; 

    FInnerControls := TList.Create; 
end; 

procedure TOuterControl.GetChildren(Proc: TGetChildProc; Root: TComponent); 
var 
    I : Integer; 
begin 
    inherited; 

    For I := 0 To FInnerControls.Count - 1 Do 
     Proc(FInnerControls[I]); 
end; 

procedure TOuterControl.Paint; 
begin 
    inherited; 

    Canvas.FillRect(ClientRect); 
    Canvas.TextOut(0,0, Format('Inner Control Count = %d', [FInnerControls.Count])); 
end; 

function TInnerControl.GetParentComponent: TComponent; 
begin 
    Result := FOuterControl; 
end; 

function TInnerControl.HasParent: Boolean; 
begin 
    Result := True; 
end; 

procedure TInnerControl.SetParentComponent(Value: TComponent); 
begin 
    If Value Is TOuterControl Then 
     If FOuterControl <> Value Then 
    Begin 
     FOuterControl := TOuterControl(Value); 
     FOuterControl.AddInnerControl(Self); 
    End; 
end; 

procedure TOuterControlEditor.ExecuteVerb(Index: Integer); 
Var 
    OuterControl : TOuterControl; 
    InnerControl : TInnerControl; 
begin 
    inherited; 

    OuterControl := TOuterControl(Component); 

    If Index = 0 Then 
    Begin 
     InnerControl := TInnerControl.Create(OuterControl.Owner); 
     OuterControl.AddInnerControl(InnerControl); 
    End; 
end; 

function TOuterControlEditor.GetVerb(Index: Integer): String; 
begin 
    Result := 'Add Inner'; 
end; 

function TOuterControlEditor.GetVerbCount: Integer; 
begin 
    Result := 1; 
end; 

Procedure Register; 
Begin 
    RegisterComponents('AA', [TOuterControl]); 
    RegisterComponentEditor(TOuterControl, TOuterControlEditor); 
End; 


Initialization 
    Classes.RegisterClasses([TInnerControl]); 

end. 
+3

「TCollection」を再発明しているようです。内側の "コントロール"を 'TCollectionItem'の子孫にし、外側のコントロールの小さな' TOwnedCollection'子孫を定義すると、すべてのデザイン時管理タスクが解決されます。 –

+0

私の状況でTCollectionItemとTOwnedCollectionを使用するのは意味がありません。私が投稿したコードは、カットダウンの例です。 – Frank

+0

なぜそれは意味をなさないのですか? TCollection/TCollectionItemが正確に処理できないことを達成しようとしていますか? –

答えて

7

あなたがして、フォーム上のappeaingからそれらを防ぐことができます。RegisterNoIcon上

RegisterNoIcon([TInnerControl]); 

詳細情報は、それは「コントロール」で終わる名前を持つクラスを持つ少し紛らわしいですhttp://docwiki.embarcadero.com/VCL/e/index.php/Classes.RegisterNoIcon

で見つけることができます彼らは通常の視覚的なコントロールではありません。

+0

+1 "RegisterNoIcon"というフレーズも混乱しているとは言いません - 私たちは "アイコンを登録しません"ので、コンポーネントパレットアイコンなしで登録します。 RegisterWithoutIconやRegisterComponentsWithoutIconを使用しても、さらに自己文書化されていました。 – TheBlastOne

+0

@TheBlastという混乱した名前に言及していない*ためにこの答えを投票した人として、あなたは混乱している名前についてよく話します。 –

+1

SetSubComponent()は正しいアプローチです。 RegisterNoIcon()は有用な副作用を持っているかもしれませんが(実際にはテストされていませんが)、実際には技術的には必要なことはしません(事故以外では、ある時点で)。 – Deltics

4

あなたは、内側のコントロールを作成するときは、その所有者は、フォーム(外部制御の所有者)であることを伝え。したがって、フォームは、それが所有する他のすべてのコンポーネントを描画するのと同様に、それらを描画します。あなたはおそらく外側のコントロールが内側のコントロールを所有することを望みます。

5

TInnerControlがTOuterControl内でのみ使用される場合は、TInnerControlの作成中またはその後にSetSubComponent(True)を呼び出す必要があります。

+1

これが正解としてなぜ受け入れられなかったのか分かりません。これは正解です。私はRegisterNoIconが有用な副作用を持っているとしか思えません(私はそうであるかどうかを調べるためにテストしていません)。 – Deltics