2011-12-14 39 views
10

Tôi có một hộp kết hợp được vẽ chủ sở hữu hiển thị các chuỗi trong cột. Các thói quen vẽ có thể được chia sẻ trên combo nếu tôi bằng cách nào đó có thể vượt qua các thông số kỹ thuật cột cho sự kiện OnDrawItem. Một cách tự nhiên để làm như vậy, sẽ là để vượt qua mảng chiều rộng cột trong thuộc tính ComboBox.Tag và sau đó đưa nó trở lại một mảng.Làm thế nào để đúc một mảng đến con trỏ và trở lại trong Delphi?

Khi tôi xác định các mảng cột như:

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

và thiết lập thuộc tính Tag để:

ComboBox.Tag := integer(@arrWidth); 

và sau đó trong trường hợp OnDrawItem, đúc nó trở lại một mảng:

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

Tôi có thể thấy các phần tử mảng tốt, nhưng mảng không biết chiều dài của nó. Nó dường như dài hơn nhiều với tất cả các loại giá trị ngẫu nhiên.

Tôi đã thử sử dụng mảng động nhưng sau đó tôi thậm chí không nhận được giá trị cột thích hợp.

+4

Alternatives không liên quan đến lưu trữ con trỏ mảng trong Tag bao gồm viết một hậu duệ lưu trữ các giá trị trong một tài sản dành riêng cho công việc, và lưu trữ các độ rộng cột trong một mảng kết hợp (như TDictionary) mà các bản đồ combo- trường hợp hộp cho mảng chiều rộng. –

+0

Cảm ơn nhận xét. Tôi đã cân nhắc việc tạo ra một hậu duệ, nhưng coi đó là quá nhiều nỗ lực. Có lẽ nó sẽ làm cho hình dạng bền vững hơn trong tương lai, nhưng đây là lần đầu tiên trong 15 năm tôi muốn có một hộp kết hợp với các cột, vì vậy tôi không nghĩ rằng tôi sẽ tái sử dụng nó nhiều. –

Trả lời

19

Hành vi nguy hiểm vì bạn đi ra ngoài hệ thống kiểm tra loại. Điều đó đã bắt bạn ở đây. Vấn đề là array[1..4] of integerarray of integer không phải là cùng loại.

Bạn cần phải khai báo mảng của bạn như là một loại riêng biệt như thế này

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

Sau đó làm thường xuyên của bạn như thế này:

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

Khi bạn cần phải giải nén các mảng từ hộp kết hợp làm điều đó như thế này:

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

Nếu bạn cần hỗ trợ bằng cách sử dụng độ dài mảng động thì bạn sẽ woul d cần phải thay đổi loại thông thường của bạn để phản ánh điều đó. Tuy nhiên, hãy cẩn thận khi truyền tới số Integer để đặt trong Tag sẽ bỏ qua việc tính tham chiếu của mảng động. Vì vậy, bạn cần phải thực sự hiểu những gì bạn đang làm nếu bạn đi xuống con đường đó.

Một điểm cuối cùng. Nếu bạn muốn biên dịch mã này cho 64 bit, nó sẽ thất bại vì dòng này:

ComboBox.Tag := integer(@arrWidth); 

integer là kiểu dữ liệu 32 bit. Thay vào đó, bạn nên sử dụng NativeInt là một số nguyên có cùng chiều rộng với con trỏ.

ComboBox.Tag := NativeInt(@arrWidth); 
Các vấn đề liên quan