2016-11-19 5 views
7

System.Classes.TShiftStateをユーザーが読める文字列に変換する便利な関数を作成しようとしています。簡単にするために、関数をよりコンパクトにするために、共通コードを実行するサブルーチンを作成しました。匿名の列挙型をサブルーチンに渡すにはどうすればいいですか?

問題は、TShiftState列挙型の1つをこのサブルーチンに渡す方法がわかりません。私はByteInteger、およびCardinalを試しましたが、私はIncompatible types: 'Byte' and 'Enumeration'(または私が試していたどのタイプでも)を得続けます。そのうちの1つにカーソルを合わせると、タイプは通常$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は、与えられた長さのスペースの文字列をパッドの別個の機能です。

TShiftStateはそうのようなSystem.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に変更してください。その後

if Sh <= Shift then 

参考にフォーム

A([ssShift], 'Shift'); 

、最終的に条件テストへの各呼び出しを変更します。 Expressions

X < = Yは、Xのすべてのメンバーは、あなたが列挙型に名前を付けないエンバのプールの決定によってキャッチされているY

関連する問題