2016-11-19 13 views
7

Tôi đang cố gắng thực hiện một chức năng thuận tiện để chuyển đổi một System.Classes.TShiftState thành chuỗi có thể đọc được. Để làm cho nó dễ dàng hơn, tôi đã thực hiện một chương trình con để thực hiện mã phổ biến, để làm cho chức năng nhỏ gọn hơn.Làm cách nào để chuyển một loại được liệt kê nặc danh vào một chương trình con?

Vấn đề là, tôi không thể tìm ra cách vượt qua một trong các loại enum TShiftState enum vào chương trình con này. Tôi đã thử Byte, IntegerCardinal nhưng tôi vẫn nhận được Incompatible types: 'Byte' and 'Enumeration' (hoặc bất kỳ kiểu nào tôi đang thử). Di chuột qua một trong số chúng chỉ hiển thị $1 nơi thường là loại.

function ShiftStateStr(const Shift: TShiftState): String; 
    procedure A(const Sh: Byte; const Str: String); 
    begin 
    if Sh in Shift then 
     Result:= Result + StrLen(Str, Length(Str)+1) 
    else 
     Result:= Result + StrLen('', Length(Str)+1); 
    end; 
begin 
    Result:= ''; 
    A(ssShift, 'Shift'); 
    A(ssAlt, 'Alt'); 
    A(ssCtrl, 'Ctrl'); 
    A(ssLeft, 'Left'); 
    A(ssRight, 'Right'); 
    A(ssMiddle, 'Middle'); 
    A(ssDouble, 'Double'); 
    A(ssTouch, 'Touch'); 
    A(ssPen, 'Pen'); 
    A(ssCommand, 'Cmd'); 
    A(System.Classes.ssHorizontal, 'Horz'); 
end; 

LƯU Ý: StrLen là một chức năng riêng biệt mà miếng một chuỗi với không gian của một chiều dài nhất định.

TShiftState được định nghĩa trong System.Classes như vậy:

type 
    TShiftState = set of (ssShift, ssAlt, ssCtrl, 
    ssLeft, ssRight, ssMiddle, ssDouble, ssTouch, ssPen, ssCommand, ssHorizontal); 

Làm thế nào tôi có thể đúng cách chuyển thông tin này vào A chương trình con?

+2

Bạn đã bị bắt ra theo quyết định vũng EMBA không đặt tên cho kiểu liệt kê. Đây là một ví dụ hoàn hảo về lý do tại sao các loại liệt kê phải luôn được đặt tên. –

+1

Ngoài ra 'StrLen' là một tên được sử dụng cho một hàm trả về độ dài của một mảng ký tự kết thúc null. Sử dụng 'str.PadLeft (n)' để thay thế. –

+0

Tại sao không sử dụng chức năng tích hợp để thực hiện việc này? https://community.embarcadero.com/blogs/entry/using-generics-rtti-to-get-enum-string-name-or-enum-value –

Trả lời

7

Thay đổi thông số đầu tiên của A thành const Sh: TShiftState. Sau đó thay đổi mỗi cuộc gọi đến A thành dạng

A([ssShift], 'Shift'); 

và cuối cùng là kiểm tra điều kiện vào

if Sh <= Shift then 

Ref. Expressions

X < = Y là True chỉ trong trường hợp tất cả các thành viên của X là thành viên của Y

Các vấn đề liên quan