delphidelphi-10.1-berlinmodifier-key

Shift value when only CTRL key is pressed?


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?


Solution

  • 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
      ....