2016-11-19 4 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는 소정 길이의 공백 문자열을 패딩하는 별도의 함수이다.

TShiftState은과 같이 System.Classes에 정의되어

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

어떻게 제대로 A 서브 루틴이 점을 통과 할 수 있습니까?

+2

의 구성원 인 경우를 대비 True입니다. 이것은 열거 형을 항상 명명해야하는 이유의 완벽한 예입니다. –

+1

또한'StrLen'은 null로 끝나는 문자 배열의 길이를 반환하는 함수에 사용되는 이름입니다. 대신에'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