2016-05-19 8 views
1

サブオブジェクトの動作(メソッド)をコンポーネントのサブクラス化時に再定義して変更する方法はありますか。たとえば、私はTlistboxをサブクラス化しています。そのItemsサブオブジェクトのDelete()メソッドの動作を変更したいと思います。そうする正式な方法はありますか? ありがとうサブオブジェクトの動作を変更する

+0

TCustomListBox.(Get/Set)ItemData()デルファイXEは、あなたが求めているものを行うことができます[ 'TVirtualMethodInterceptor'](http://docwiki.embarcadero.com/Libraries/en/System.Rtti.TVirtualMethodInterceptor)クラスを導入しました'Delete()'はバーチャルですが、Delphi 7ではそのようなものはありません(手動で移植しない限り)。また、 'Items'オブジェクトを別の実装に置き換える直接アクセス権がありません。あなたは本当に何を達成しようとしていますか?それを処理する別の方法があるかもしれません。 –

+0

itemsプロパティに追加された内部情報構造体を追加するので、objects []リストに追加するか、この場合、文字列を入力しないようにitems.add()の使用を制限する必要があります別のtstringsオブジェクトを作成し、items.addとitems.deleteを再定義して2つのtstringsオブジェクトを同期させます。 – DrWael

答えて

2

コメントに基づいて、実際にItemsプロパティの動作を変更する必要はありません。 ListBoxで項目が操作されていることを検出する他の方法がありますので、必要に応じて独自の内部オブジェクトを更新できます。

アイテムを削除する場合、Items.Delete()メソッドは、単に削除するインデックスをTCustomListBox.DeleteString()に渡します。 DeleteString()は、子孫によってオーバーライドできます。十分に簡単です。

新しいアイテムを追加/挿入するときはあまり簡単ではありません。 Items.Add()は、ListBoxのに直接メッセージを送信します(ListBoxのStyleが仮想モードに設定されている場合を除き、Add()は何もせずにそのまま終了します)。 Items.Insert()メソッド(LB_INSERTSTRINGメッセージ)と同じです。これらのメッセージをキャッチするには、ListBoxの仮想WndProc()メソッドをオーバーライドする必要があります。

Items.AddObject()最初にItems.Add()を呼び出してから、Items.Objects[]セッターを使用してオブジェクトを新しいアイテムに割り当てます。 Items.InsertObject()と同じですが、Items.Add()の代わりにItems.Insert()を呼び出します。

Items.Strings[]プロパティを経由して、既存の項目の文字列を更新するとき、物事は少し複雑を取得:もしあれば

  1. TCustomListBox.InternalGetItemData()を(上書きすることができます)、アイテムの既存のオブジェクトを取得するために呼び出されます。既定では、InternalGetItemData()GetItemData()(これも上書き可能)を呼び出します。これは、デフォルトでLB_GETITEMDATAメッセージをListBoxのHWNDに送信します。
  2. TCustomListBox.InternalSetItemData()(オーバーライド可能)は、アイテムのオブジェクトをnilに設定するために呼び出されます(次のステップのDelete()がそれを破棄しようとした場合)。既定ではInternalSetItemData()SetItemData()(これも上書き可能)を呼び出します。これは、既定ではLB_SETITEMDATAというメッセージをListBoxのHWNDに送信します。
  3. Items.Delete()がアイテムを削除するために呼び出されます。
  4. Items.InsertObject()nilオブジェクト
  5. TCustomListBox.InternalSetItemData()と新しい文字列を挿入するために呼び出され、新しいアイテムに元のオブジェクトを復元するために呼び出されます。

Items.Objects[]プロパティを経由して既存のアイテムのオブジェクトを更新すると、リストボックスのStyleが仮想モードに設定されていない場合、その後、TCustomListBox.SetItemData()が呼び出されます。

Items.Exchange()メソッドを使用して項目を移動する場合、ListBoxのStyleが仮想モードに設定されている場合、Exchange()は何もせずに単に終了します。それ以外の場合は、Items.Strings[]プロパティを使用して2つのアイテム文字列を交換し、Internal(Get/Set)ItemData()を呼び出して2つのアイテムオブジェクトを交換します。

だから、基本的に、あなたが内部のオブジェクトを管理するために必要なすべては、これらのメソッドのオーバーライドに要約:LB_(ADD/INSERT)STRING、多分LB_(GET/SET)ITEMDATAを処理するために

  1. TCustomListBox.DeleteString()
  2. TCustomListBox.WndProc()を。
  3. TCustomListBox.Internal(Get/Set)ItemData()または
関連する問題