0

Create a VCL Forms application and in the main form's OnMouseDown event handler write:

procedure TForm2.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Shift = [ssCtrl] then
    ShowMessage('CTRL pressed');
end;

Then run the app, press and hold the CTRL key down, with no other modifier keys, and then click on the form. No message is displayed. Why now?

So which value does Shift have in this case when only the CTRL key is pressed?

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
user1580348
  • 5,721
  • 4
  • 43
  • 105
  • 2
    Why didn't you answer this yourself by evaluating `Shift` in the debugger? It would have told you immediately that the contents of `Shift` are not just [ssCtrl] even when only one of the Ctrl keys is pressed. – MartynA Feb 03 '17 at 15:59

2 Answers2

9

The TShiftState type is defined like this:

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

As you can see, is contains a lot more information than just the modifier key state.

When you hold down the CTRL key and click on the form, Shift has this value: [ssCtrl,ssLeft]. That tells you that the CTRL key is down, and the left mouse button is down. Note that this information is easy to obtain by using the debugger. Learning how to use the debugging to inspect the state of your program during execution is a very important skill.

If you wish to test for the state of the modifier keys, you need to mask out everything that is not a modifier key. Do that using the * operator, which is set intersection. This allows you to cut the information down to just the enumeration values of interest.

if Shift*[ssShift, ssAlt, ssCtrl] = [ssCtrl] then
  ....
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Brilliant! The answer from Jerry Dodge is correct and good but this is more elegant. – user1580348 Feb 03 '17 at 15:34
  • Because `ssCtrl in Shift` is true when any combination of modifiers is down that includes the control key. But you specifically asked for only the control key. – David Heffernan Feb 03 '17 at 15:38
  • 3
    Original question asks *"which value does Shift have in this case when only the CTRL key is pressed?*", it mentions nothing of any other modifier keys. Testing for ssctrl satisfies the original question. – Sertac Akyuz Feb 03 '17 at 15:47
  • @SertacAkyuz That's taking things very literally, but I think it is obvious enough that the asker did not realise that `Shift` reports about keys other than modifiers. Hence my edit to the question. – David Heffernan Feb 03 '17 at 15:52
  • @David - Your edit to the question is quite fine. However an answer not taking into account *the obvious* is not necessarily wrong in my opinion. – Sertac Akyuz Feb 03 '17 at 15:54
  • @SertacAkyuz OK, that's fair. – David Heffernan Feb 03 '17 at 15:57
  • @user1580348 `ssCtrl in Shift` only checks the state of the Ctrl key. if you hold down Shift or Alt along with Ctrl, `ssCtrl in Shift` will still be true even though the Shift/Alt key is down. If you want to make sure only Ctrl by itself is down, you have to take the states of the other keys into account. – Remy Lebeau Feb 03 '17 at 16:06
  • @SertacAkyuz: Your comment "Original question asks ..." reminds me a bit of answering the q "Would you like tea or coffee?" with "Yes." ;=) – MartynA Feb 04 '17 at 10:22
3

TShiftState is an enum set, meaning there could be more than one value. When you do if Shift = [ssCtrl] you are checking if it's exactly equal to that. But, there may be other values.

So instead, do this:

if ssCtrl in Shift then
  ...
Jerry Dodge
  • 26,858
  • 31
  • 155
  • 327
  • 1
    This is also `True` when I hold both `Ctrl` and `Shift` modifier keys down. But the question was: "So which value does Shift have in this case when only the CTRL key is pressed?" – user1580348 Feb 03 '17 at 15:16
  • @user1580348 You already had it correct. The problem was how you were doing your check. – Jerry Dodge Feb 03 '17 at 15:20
  • @user - It's ssCtrl of course. But in the question you state you click on the form, that's no more *only* the control key. Your question is inconsistent. – Sertac Akyuz Feb 03 '17 at 15:20
  • Of course when I ask "only the control key" everybody understands that I mean "only the control modifier key". – user1580348 Feb 03 '17 at 15:24