How to pass an anonymous enumerated type into a subroutine?
Asked Answered
B

1

8

I'm trying to make a convenient function to convert a System.Classes.TShiftState into a user-readable string. To make it easier, I've made a subroutine to perform common code, to make the function more compact.

The problem is, I cannot figure out how to pass one of the TShiftState enum types into this subroutine. I tried Byte, Integer, and Cardinal but I keep getting Incompatible types: 'Byte' and 'Enumeration' (or whichever type I was trying). Hovering over one of them only shows $1 where the type would usually be.

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;

NOTE: StrLen is a separate function which pads a string with spaces of a given length.

TShiftState is defined in System.Classes like so:

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

How can I properly pass this into the A subroutine?

Bula answered 19/11, 2016 at 2:36 Comment(9)
You have been caught out by the pool decision of Emba not to name the enumerated type. This is a perfect example of why enumerated types should always be named.Wilkins
Also StrLen is a name used for a function that returns the length of a null terminated character array. Use str.PadLeft(n) instead.Wilkins
Why not use built in functions to do this? community.embarcadero.com/blogs/entry/…Tipsy
@John Because I want the strings to be shortened, and not have ss in front of them. Like I said, more human-readable :PBula
@David Thanks for pointing that out, actually this function can pad left, right, or center, and can use desired character instead of a space.Bula
All the same StrLen is a weak nameWilkins
@JerryDodge you can copy the string minus the first two characters. The problem with your approach is if you change your set, you need to change your function later on.Tipsy
@John Well if Emba wants to change the set. If it were my own, I wouldn't have a problem :D But Command is shortened to Cmd, and Horizontal to Horz, etc.Bula
@John What would you pass to TypeInfo()? There is no named type for the values that make up the TShiftState set. The enumeration is anonymous.Lipoprotein
L
8

Change first parameter of A to const Sh: TShiftState. Then change each call to A into the form

A([ssShift], 'Shift');

and finally the condition test into

if Sh <= Shift then

Ref. Expressions

X <= Y is True just in case every member of X is a member of Y

Lipoprotein answered 19/11, 2016 at 3:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.