2011-12-14 10 views
10

私は、列に文字列を表示するコンボボックスを描いたオーナーを持っています。何らかの理由で列指定をOnDrawItemイベントに渡すことができれば、描画ルーチンをコンボで共有することができます。これを行う自然な方法は、列幅の配列をComboBox.Tagプロパティに渡して、それを配列にキャストすることです。配列をポインタにキャストして戻す方法はありますか?

私のように列配列を定義します。

const arrWidth :array[1..4] of integer = (100,100,100,70); 

とにTagプロパティを設定します。

ComboBox.Tag := integer(@arrWidth); 

、その後、OnDrawItemイベントで、配列に戻ってそれをキャスト:

Widths :array of integer; 
Widths := pointer(ComboBox.Tag); 

配列要素はきれいに見えますが、配列の長さはわかりません。あらゆる種類のランダムな値ではずっと長いようです。

私は動的配列を使用しようとしましたが、適切な列値を取得できませんでした。

+4

代替タスクに専用のプロパティに値を格納する子孫を書き、そしてcombo-をマップ(TDictionaryのような)連想配列内の列の幅を格納することを含みますboxインスタンスを幅の配列に変換します。 –

+0

コメントありがとうございます。私は子孫を作ることを検討しましたが、それはあまりにも多くの努力と見なしました。おそらく、将来的にはフォームをより保守的にするでしょうが、これは15年ぶりのことです。私はコラムボックスを必要としていたので、再利用するとは思わなかったです。 –

答えて

19

キャストはタイプチェックシステム外に出るため危険です。それがあなたをここに連れてきました。問題はarray[1..4] of integerarray of integerが同じタイプではないことです。あなたはその後、この

TWidthArray = array [1..4] of Integer; 
PWidthArray = ^TWidthArray; 

のような特殊タイプとしてあなたの配列を宣言する必要が

は、このようなあなたの一定の操作を行います。あなたはコンボボックスから列を抽出する必要がある場合

const 
    arrWidth: TWidthArray = (100,100,100,70); 

それを行います

Widths: TWidthArray; 
... 
Widths := PWidthArray(ComboBox.Tag)^; 

ダイナミックアレイの長さを使用する必要がある場合は、 dそれを反映するためにあなたの共通のタイプを変更する必要があります。ただし、にキャストするとTagにキャストするとダイナミックアレイの参照カウントをバイパスすることに注意してください。あなたがそのルートを降りる場合、あなたがしていることを本当に理解する必要があります。

最後の1つです。今まであなたが64ビットのため、このコードをコンパイルしたい場合には、このための行で失敗します:integer以来

ComboBox.Tag := integer(@arrWidth); 

は、32ビット・データ・タイプです。代わりにNativeIntを使用してください。これは、ポインタと同じ幅の整数です。タグに配列ポインタを格納伴わない

ComboBox.Tag := NativeInt(@arrWidth); 
関連する問題