The short answer is: You can't use case. You have to use the "if" statements.
The long answer is, if you want to go on a tricky, slippery path and use some hacked together code .... You can get case do to the job. But as you said "there can be multiple enums set". The "case" will see
each combination as a different option.
I do _ NOT _ recommend the below. Do not use it.The below is for fun of hacking the code, not for use in any app.
It will probably break, if you use any options that change the size of sets.
It also depends on the CPU (big endian vs little endian).
// Example of really bad code
var
c: TShiftState;
begin
c := [ssRight];
// Example of really bad code
case cardinal(c) of
1 << (ord(ssLeft)) : writeln('left');
1 << (ord(ssRight)) : writeln('right');
(1 << (ord(ssLeft))) or
(1 << (ord(ssRight))) : writeln('both');
otherwise
writeln('left/right may still be set, but combined with other enums in the set');
end;
end;