2011-12-14 10 views
10

Tengo un cuadro combinado dibujado por el propietario que muestra las cadenas en columnas. La rutina de dibujo se puede compartir en combos si de alguna manera puedo pasar las especificaciones de columna al evento OnDrawItem. Una forma natural de hacerlo sería pasar el conjunto de anchuras de columna en la propiedad ComboBox.Tag y luego convertirlo a una matriz.Cómo lanzar una matriz al puntero y viceversa en Delphi?

Cuando defino la matriz columna como:

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

y establecer la propiedad Tag a:

ComboBox.Tag := integer(@arrWidth); 

y luego en caso OnDrawItem, lo arrojó de nuevo a una matriz:

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

Puedo ver los elementos de la matriz bien, pero la matriz no sabe su longitud. Parece ser mucho más largo con todo tipo de valores aleatorios.

He intentado utilizar una matriz dinámica, pero ni siquiera obtengo los valores de columna adecuados.

+4

alternativas que no implican el almacenamiento de los punteros de la matriz en la etiqueta incluyen la redacción de un descendiente que almacena los valores de una propiedad dedicada a la tarea, y el almacenamiento de los anchos de columna en una matriz asociativa (como TDictionary) que mapea combo- instancias de caja a matrices de ancho. –

+0

Gracias por el comentario. Consideré crear un descendiente, pero lo consideré demasiado esfuerzo. Tal vez haría la forma más fácil de mantener en el futuro, pero esta era la primera vez en 15 años que quería un cuadro combinado con columnas, así que no pensé que volvería a usarlo mucho. –

Respuesta

19

Los yesos son peligrosos porque salen del sistema de verificación de tipos. Eso te atrapó aquí. El problema es que array[1..4] of integer y array of integer no son del mismo tipo.

tiene que declarar la matriz como un tipo distinto como esto

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

A continuación, hacer su constante así:

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

Cuando necesite extraer la matriz en el cuadro combinado lo hacen como este:

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

Si necesita admitir el uso de longitudes de matriz dinámica, entonces woul Necesito cambiar tu tipo común para reflejar eso. Sin embargo, tenga en cuenta que la conversión a Integer para poner en Tag omitirá el recuento de referencias de la matriz dinámica. Entonces, realmente debes entender lo que estás haciendo si sigues esa ruta.

Un último punto. Si alguna vez desea compilar el código de 64 bits para que no falle debido a esta línea:

ComboBox.Tag := integer(@arrWidth); 

desde integer es un tipo de datos de 32 bits. En su lugar, debe usar NativeInt, que es un entero del mismo ancho que un puntero.

ComboBox.Tag := NativeInt(@arrWidth); 
Cuestiones relacionadas