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:
'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"
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 $80
as 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.