1

Delphi (2006) がクォンタムになると: 観察方法によっては、TToolBar と TPanel の両方のように見える「何か」があります。何が起こっているのか理解したいです。

作成方法と何が起こるかは次のとおりです。

  1. DFMで

    • bar という名前の TToolBar を追加します。
    • その TToolBar に TPanel を配置します。
  2. コード内および実行時:

    • パネルがボタン bar.Buttons[] のリストに表示されます。インデックス i としましょう
    • コンパイラの観点から見た bar.Buttons[i] は TToolButton です。
    • bar.Buttons[i].ClassName = 'TPanel'
    • (bar.Buttons[i] is TToolButton) = true ですが、これはコンパイラが「is」out への呼び出しを最適化するためです。
    • 実際、IsBarButton(bar.Buttons[i]) は IsBarButton 関数 (以下で定義) に対して false です。
    • bar.Buttons[i].Name は、DFM で TPanel に付けた名前です
    • デバッグで値 bar.Buttons[i] を調べる:
      • 実際の TToolButton にはない「キャプション」プロパティがあります。
      • 奇妙なことに、TToolButton.Indeterminate (=true) のように、TToolButton が持っているすべてのプロパティを持っています。

IsToolButton:

function IsToolButton(X : TObject) : boolean;
begin
    Result := X is TToolButton;
end;

したがって、bar.Buttons[i] は TToolButton である場合とない場合があります...どうしたのですか?

(一番下の話は、自分の TPanel を本物の TToolButton と区別したいということです。これは多かれ少なかれハックな方法で行うことができます。ここでこの質問をすることで、ここで実際に何が起こっているのかをより完全に理解することが私の目標です。)

質問: 何が起こっていますか? サブ質問: TPanel を TToolBar に追加することは正当ですか?

4

3 に答える 3

2

OS がツールバーに追加できる唯一のものは、ツール ボタンです。他のものを追加するには、技術的にはボタンを作成してから、他のものをその上に配置する必要があります。追加されるボタンは文字通りプレースホルダーです。次に追加するものが適切に配置されるように、スペースを占有するためにあります。

これは、追加するツール ボタン以外のコントロールが透明である場合に見られることがあります。次に、下にツールバーのセパレーターが表示されるので、コントロールの中央に縦線が走っているように見えます。

ツール ボタン以外のコントロールをツールバーに追加すると、Buttonsプロパティは実際にはコントロールのタイプに関するものになります。ComCtrls.pas全体で、それTToolBar自体が常にボタンを にキャストし、TControl実際に から派生したものかどうかを確認することに気付くでしょうTToolButton。ボタン以外をツールバーに追加することは完全に合法です。フォーム デザイナが最初にそれを許可するのはそのためです。

Form Designer を使用してツールバーを作成することをお勧めします。こうすることで、IDE はフォーム内でユーザーの識別子を保持するため、常にパネルを直接参照できます。ツールバーで探しに行く必要はありません。ツールバーを手動で作成している場合でも、パネルを参照するために追加のフィールドを作成することをお勧めします。パネルをツールバー内で移動しても、ずっと同じオブジェクトなので、ぶら下がり参照を気にする必要はありません。

于 2010-06-21T14:10:48.907 に答える
0

ツールバーにいくつかのボタンとパネルを配置し、どこかにメモを配置したら、フォームの onCreate で次のコードを実行します。

procedure TForm1.FormCreate(Sender: TObject);
  function _IsToolButton(const aObject: TObject): Boolean;
  begin
    Result := aObject is TToolButton;
  end;

  function _IsPanel(const aObject: TObject): Boolean;
  begin
    Result := aObject is TPanel;
  end;
var
  i: Integer;
begin
  for i := 0 to bar.ButtonCount - 1 do begin
    Memo.Lines.Add(Format('bar.Buttons[%d].Name: %s', [i, bar.Buttons[i].Name]));
    Memo.Lines.Add(Format('bar.Buttons[%d].ClassName: %s', [i, bar.Buttons[i].ClassName]));
    Memo.Lines.Add(Format('bar.Buttons[%d] is TToolButton: %s', [i, BoolToStr(_IsToolButton(bar.Buttons[i]), True)]));
    Memo.Lines.Add(Format('bar.Buttons[%d] is TPanel: %s', [i, BoolToStr(_IsPanel(bar.Buttons[i]), True)]));
//    Memo.Lines.Add(Format('bar.Buttons[%d] has Caption property: %s', [i, 'dunno yet']));
    Memo.Lines.Add('');
  end;
end;

パネルがTooButton ではなく、間違いなく TPanel であることがわかります。

パネルの ToolButton のプロパティを表示するデバッガは、すべての bar.Buttons[i] を TToolButton にキャストするデバッガです。デバッグ インスペクタの [データ] タブを右クリックすると、それを TPanel に型キャストして、正しい情報を取得できます。

于 2010-06-21T10:37:41.923 に答える
0

「合法ですか?」- まあ、ツールバーの作成者がツールバーを使用するように指示しなかった方法でツールバーを使用していることは間違いありません。それはあなたの顔で爆発しますか?知るか。ツールバーのソースコードを調べて、それが安全かどうかを確認できると思いますが、ツールバーにボタンが見つかることを期待して、サードパーティのツールやコンポーネントの可能性はどうでしょうか?

私の問題を解決する別の方法を見つけることができるかどうかを確認します。巧妙なハックは結局それほど巧妙ではないことが判明する傾向があり、コードのwtf レートが確実に高くなります。

ツールバーを使用する必要がありますか? 代わりにボタンとパネルを備えたフローパネルはどうですか? それとも、ツールバーとパネルを備えたパネルですか?

于 2010-06-21T11:57:00.027 に答える