Delphi: Cannot capture Ctrl+C if user pressed the sequence too quickly
I am trying to capture when a user presses Ctrl+C in order to copy some text to the clipboard. If the user deliberately presses and holds Ctrl... then presses C it will register.
procedure <anObject>.K开发者_Go百科eyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if (ssCtrl in Shift) and (upcase(Char(key)) = 'C')
then
begin
//Copy code
end;
end;
Is there a reason why this is happening?
Thanks!
Ctrl+C is translated to a character message. So you better use a OnKeyPress
handler (which is fired in response to a WM_CHAR
):
procedure <anObject>.KeyPress(Sender: TObject; var Key: Char);
begin
if Key = ^C then
begin
// Copy code
end;
end;
update:
I believe what's happening is this: when pressing quickly, the user is pressing 'Ctrl', then pressing 'C', then releasing 'Ctrl', lastly releasing 'C'. As you can see when the OnKeyUp for 'C' is fired the 'Ctrl' key is already released. You won't have this kind of problem with the translated message, if the OS registered the 'copy' key then OnKeyPress will be fired.
It is not a sequence, it is a key combination. This means that Ctrl and C must be pressed at the same time. If the user doesn't do that, it can't be captured as Ctrl+C.
But I am guessing. I can't tell what the user is doing. Perhaps there is also a problem with the keyboard or the driver for it.
To account for what Rob said (accidently accepting other shift keys), change your code to:
if (Shift = [ssCtrl]) and (Upcase(Char(Key)) = 'C') then
Usually, OnKeyDown is more preferable then OnKeyup for such combo. Because users usually know to press those shift key before the char key but don't have a strict sense of which one to release first. Also, you can change the var Key to 0 to prevent the keys to be further interpreted by other levels of key events to override some default behaviour.
Procedure TForm1.StringGrid1KeyPress (Sender: TObject; var Key: Char);
Var
Sel: TGridRect; // Selecting the Scenes
St: String; // Stroke
R, c: word; // Row-Stroke, Col-Column
Begin
If Key = ^ C then
Begin
St: = ''; / / A full explanation of the structure
Sel: = StringGrid1.Selection; // Wait a while for a loose ticket
For r: = Sel.Top to Sel.Bottom do // query the lines of the first row
Begin
For c: = Sel.Left to Sel.Right do // query the number of lines in the foreground
// Scribble in the Stroke of a Distributor
If c = Sel.Right then St: = St + StringGrid1.Cells [c, r] else St: = St + StringGrid1.Cells [c, r] + # 9;
St: = St + # 13 # 10; // the pattern of the stencil
End;
ClipBoard.AsText: = St; // Displays the alarm
End;
End;
精彩评论