2011-12-14 2 views
10

Ho una casella combinata disegnata dal proprietario che visualizza le stringhe nelle colonne. La routine di disegno può essere condivisa tra combo se posso in qualche modo passare le specifiche della colonna all'evento OnDrawItem. Un modo naturale per farlo sarebbe passare la matrice di larghezze di colonna nella proprietà ComboBox.Tag e quindi ricondurla a un array.Come lanciare un array al puntatore e tornare in Delphi?

Quando definisco la matrice colonna come:

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

e impostare la proprietà Tag a:

ComboBox.Tag := integer(@arrWidth); 

e poi in caso OnDrawItem, gettò di nuovo a un array:

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

Posso vedere bene gli elementi dell'array, ma l'array non conosce la sua lunghezza. Sembra essere molto più lungo con tutti i tipi di valori casuali.

Ho provato a utilizzare un array dinamico, ma non riesco nemmeno a ottenere i valori di colonna corretti.

+4

alternative che non comportano memorizzare i puntatori array nel tag includono crei una discendente che memorizza i valori in una struttura dedicata al compito, e memorizzare la larghezza delle colonne in un array associativo (come TDictionary) che associa combo- istanze box a matrici di larghezza. –

+0

Grazie per il commento. Avevo pensato di creare un discendente, ma lo consideravo troppo impegnativo. Forse renderebbe la forma più manutenibile in futuro, ma questa era la prima volta in 15 anni che volevo una casella combinata con colonne, quindi non pensavo che avrei riutilizzato molto. –

risposta

19

I lanci sono pericolosi perché si esce dal sistema di controllo del tipo. Questo ti ha sorpreso qui. Il problema è che array[1..4] of integer e array of integer non sono dello stesso tipo.

è necessario dichiarare la matrice come un tipo distinto come questo

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

Poi fare il vostro costante come questa:

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

Quando è necessario estrarre la matrice dalla casella combinata farlo In questo modo:

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

Se è necessario supportare l'utilizzo di lunghezze di array dinamici, si d bisogno di cambiare il tuo tipo comune per riflettere questo. Tuttavia, fai attenzione che il lancio su un valoreda esclude il conteggio dei riferimenti dell'array dinamico. Quindi devi capire davvero cosa stai facendo se segui questa strada.

Un ultimo punto. Se mai si desidera compilare il codice per 64 bit fallirà a causa di questa linea:

ComboBox.Tag := integer(@arrWidth); 

dal integer è un tipo di dati a 32 bit. Invece dovresti usare NativeInt che è un intero della stessa larghezza di un puntatore.

ComboBox.Tag := NativeInt(@arrWidth);