Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

KeyDown in delphi XE7 requires shift to register

Tags:

UPDATE: Another process on my machine was interfering with shortcut detections.

In a VCL TStringgrid I want to copy the contents using “Ctrl+C" and/or "Ctrl+c”

Code snippet:

procedure TEditWaterFrame.sgSSPKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
    if (ssCtrl in Shift) AND ((Key = Ord('c')) OR (key = Ord('C'))) then  // this just won't work without me holding ssShift as well, I'm clueless...!
    begin
        ShowMessage('Ctrl+C pressed as keys');
        try
            Clipboard.AsText    := writeSSPToCSVString(#9);
        finally
            Clipboard.Free;
        end;
    end;

end;

// trying with keypress
procedure TEditWaterFrame.sgSSPKeyPress(Sender: TObject; var Key: Char);
begin
    if (Key = ^c) then  // this just won't work without me holding ssShift as well, I'm clueless...!
    begin
        ShowMessage('Ctrl+C pressed as char');
        try
            Clipboard.AsText    := writeSSPToCSVString(#9);
        finally
            Clipboard.Free;
        end;
    end;
end;

The two procedures above only run if ssCtrl + ssShift + c/C is pressed. It does not trigger when ssShift is not pressed (i.e. Ctrl+c or Ctrl+C).

I am mystified!

like image 795
Rasmus Avatar asked Jun 21 '17 15:06

Rasmus


1 Answers

I created an empty VCL forms application, added a string grid to the main form, and implemented an event handler for its OnKeyDown event:

procedure TForm1.StringGrid1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if (ssCtrl in Shift) and (key = Ord('C')) then
    Beep;
end;

The computer sounded a beep when I pressed CTRL + C.

Something else in your program is handling that key press in your application.

Returning to the condition above, this will fire if CTRL is down, irrespective of the state of the other modifier keys. So you will also respond to CTRL + SHIFT C, CTRL + ALT C and CTRL + SHIFT + ALT C. I doubt that you want to do that. So you might write the condition as:

if (Shift*[ssCtrl,ssShift,ssAlt]=[ssCtrl]) and (key = Ord('C')) then

Note that there were a number of errors in your code:

  • The calls to Clipboard.Free will destroy a shared object that you don't own. You must not do this. Remove those calls.
  • The logic of your if statement was wrong. The test Key = Ord('c') is always false. When the key is pressed, irrespective of the state of the modifier keys, you must test for the upper case ordinal, Key = Ord('C').
  • Your condition is of the form if a and b or c. Operator precedence means this is evaluated as if (a and b) or c. That's not what you intended.

All of this is moot, since your condition evaluates True when the C key is pressed irrespective of the modifier state. The conclusion remains the same: something else is handling CTRL + C and stopping that key down event reaching your code.

like image 97
David Heffernan Avatar answered Sep 22 '22 05:09

David Heffernan