2016-11-19 101 views
7

我試圖做一個方便的功能來將System.Classes.TShiftState轉換爲用戶可讀的字符串。爲了使它更容易,我做了一個子程序來執行通用代碼,使功能更加緊湊。如何將匿名枚舉類型傳遞給子例程?

問題是,我想不出如何將TShiftState枚舉類型之一傳遞到此子例程。我試過Byte,IntegerCardinal,但我一直得到Incompatible types: 'Byte' and 'Enumeration'(或無論我試過的類型)。懸停在其中一個只顯示$1類型通常會。

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; 

注:StrLen是一個單獨的函數,其與墊的給定長度的空格的字符串。

TShiftStateSystem.Classes定義,像這樣:

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

我怎樣才能正確地傳遞到A子程序呢?

+2

的成員,你被恩巴池決定不來命名枚舉類型抓出來。這是枚舉類型應始終被命名的一個完美例子。 –

+1

另外'StrLen'是一個用於函數的名字,它返回一個以空字符結尾的字符數組的長度。改用'str.PadLeft(n)'。 –

+0

爲什麼不使用內置函數來做到這一點? https://community.embarcadero.com/blogs/entry/using-generics-rtti-to-get-enum-string-name-or-enum-value –

回答

7

將第一個參數A更改爲const Sh: TShiftState。然後改變每次調用A分成形式

A([ssShift], 'Shift'); 

和最後的條件試驗進

if Sh <= Shift then 

參考。 Expressions

X < = Y爲真,以防萬一X的每一個成員爲Y