1

I can't figure out how to capture the 'any key'(except for CTRL) + 'Deletekey' press. I found out how to validate if CTRL + 'Deletekey'.

The reason is because I need to make 2 actions:

  1. if 'CTRL' + 'Deletekey' is pressed. (Already achieved this one)
  2. ONLY if 'Deletekey' is pressed. (Got problems with it, because I can combine 'any key'(except for CTRL) + Deletekey and it keeps making action 2), but I need to make this action IF AND ONLY IF 'Deletekey' is pressed.

Thanks

EDIT: Thank for your replies, I will show how I accomplished the point 1:

Context first: I have an event called DPaint1KeyUp, what it should do? remove graphically a painted element (if DELETE is pressed) or remove graphically and from the database if CTRL + DELETE pressed Simultaneously.

procedure TfMyClass.DPaint1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  inherited;
  if (Shift = [ssctrl]) and (key = VK_DELETE) then
    //Going to delete graphically and from database

  if (Shift = []) and (key = VK_DELETE) then
    //Going to delete just Graphically
end;

If I press simultaneosly CTRL + DELETE it works perfectly (Delete graphically and from Database.

BUT, if I press simultaneosly whichever combination with DELETE (except for CTRL), it deletes Graphically, WRONG, because if I only need to delete graphically I just need to press DELETE, not any other combination

For example:

@fpiette "A key and DeleteKey simultaneously pressed"

BaldwinIV
  • 147
  • 10
  • Please include the code where you "got problems with it" and why (expectations versus what happens instead). Is what you want bound to a specific event handler? – AmigoJack Jul 26 '21 at 21:43
  • It is not clear to me what you want to do. When you say *any key + DeleteKey*, do you mean for example the A key and DeleteKey simultaneously pressed? Please show the code you have so far in a minimal application. – fpiette Jul 27 '21 at 05:49
  • How are you currently detecting the `CTRL+Delete`. There are multiple ways to achieve this. So if you tell us what way are you using now it will allow us to offer you a compatible way of solving your problem. – SilverWarior Jul 27 '21 at 06:54
  • @AmigoJack, Thank you for your reply, already edited it for better explanation – BaldwinIV Jul 27 '21 at 13:57
  • @fpiette, Thank you for your reply, already edited it for better explanation – BaldwinIV Jul 27 '21 at 13:57
  • @SilverWarior, Thank you for your reply, already edited it for better explanation – BaldwinIV Jul 27 '21 at 13:57
  • 1
    Based on the edit of your question it seems you are interested to find out if any other keys are being pressed down besides Delete key at certain time. That can not be done using OnKeyDown event alone. You need to query the system for keyboard state of each individual key using `GetKeyState` or all keys using `GetKeyboardState` methods. – SilverWarior Jul 27 '21 at 16:43

1 Answers1

2

If you want to make sure that combination of pressed keys does not contain an undesired key you first need to get state of every key using GetKeyboardState function.

The above mentioned function returns an array with 256 items representing state of any possible key in Windows.

You can then iterate through the mentioned array checking if certain unwanted key is being pressed down using

if (KeyState[I] and $80) <> 0 then

Since each key state is stored at position in the above mentioned array that corresponds with Virtual Key value for that specific key you can use Virtual key designations to red the desired key from the above mentioned array.

And since key states are stored in high-order bit we use and logical operator with $80as its second parameter in order to read only the high-order bit value.

If the key is being pressed down such value will be 1 otherwise it will be 0.

So your code would look something like this:

type
  //Define set for all possible keys
  TAllKeys = set of 0..255;

...

implementation

...

procedure TfMyClass.DPaint1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var KeyState: TKeyboardState;
    I: Integer;
    DesiredKeys: TAllKeys;
    UndesiredKeys: TAllKeys;
begin
  //Use desired keys to set all the keys you want to respoond to
  DesiredKeys := [VK_DELETE, VK_CONTROL, VK_LCONTROL, VK_RCONTROL, VK_MENU, VK_LMENU, VK_RMENU, VK_SHIFT, VK_LSHIFT, VK_RSHIFT];
  //Set undesired keys set as all posible keys substracted by desired keys
  UndesiredKeys := [0..255] - DesiredKeys;

  //Retzrieve keyboard state so we can check if one of undesired keys is being pressed down
  GetKeyboardState(KeyState);
  //Loop through all keys
  //NOTE: In modern delphi versions it is possible to loop through elements of individual set using for..in loop
  //      This would allow looping only through undesired keys and not checking every key tro se if it is amongst undesired keys
  for I := 0 to 255 do
  begin
    //If certain key is in undesired keys set check its status
    if I in UndesiredKeys then
    begin
      //If undesired key is pressed down exit the procedure
      if (KeyState[I] and $80) <> 0 then
      begin
        //ShowMessage('Non-desired key pressed');
        Exit;
      end;
    end;
  end;

  //If no undesired key is pressed continue with your old code
  if (Shift = [ssctrl]) and (key = VK_DELETE) then ShowMessage('Ctrl + Delete');
    //Going to delete graphically and from database

  if (Shift = []) and (key = VK_DELETE) then ShowMessage('Delete only');
    //Going to delete just Graphically
end;

While this is probably not most efficient code it will get the job done. Just don't forget to add all desired keys that you do want to react to into DesiredKeys set so them being pressed down wont exit the OnKeyUp procedure.

SilverWarior
  • 7,372
  • 2
  • 16
  • 22