1

我不知道如何捕捉'any key'(except for CTRL) + 'Deletekey'媒体。我发现了如何验证 if CTRL + 'Deletekey'

原因是因为我需要做 2 个动作:

  1. 如果按下“CTRL”+“Deletekey”。(已经实现了这个)
  2. 仅当'Deletekey'被按下时。(遇到了问题,因为我可以组合'any key'(except for CTRL) + Deletekey 并且它会继续执行操作 2),但我需要在且仅当'Deletekey'按下时才执行此操作。

谢谢

编辑:感谢您的回复,我将展示我如何完成第 1 点:

上下文优先:我有一个名为 DPaint1KeyUp 的事件,它应该做什么?以图形方式删除绘制的元素(如果按下 DELETE)或以图形方式从数据库中删除,如果同时按下 CTRL + DELETE。

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;

如果我同时按 CTRL + DELETE,它会完美运行(以图形方式和从 Database.Delete 中删除)。

但是,如果我同时按 DELETE 的任何组合(CTRL 除外),它会以图形方式删除,错误,因为如果我只需要以图形方式删除,我只需要按 DELETE,而不是任何其他组合

例如:

@fpiette “同时按下了一个键和 DeleteKey”

4

1 回答 1

2

如果要确保按下的键组合不包含不需要的键,则首先需要使用GetKeyboardState 函数获取每个键的状态。

上面提到的函数返回一个包含 256 个项目的数组,表示 Windows 中任何可能键的状态。

然后,您可以遍历提到的数组,检查是否正在按下某些不需要的键

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

由于每个键状态都存储在上述数组中与该特定键的虚拟键值相对应的位置,因此您可以使用虚拟键指定从上述数组中将所需键变为红色。

由于键状态存储在高位中,我们使用and逻辑运算符 with$80作为其第二个参数,以便仅读取高位值。

如果按键被按下,则该值为 1,否则为 0。

所以你的代码看起来像这样:

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;

虽然这可能不是最有效的代码,但它可以完成工作。只是不要忘记将您想要响应的所有所需键添加到DesiredKeys设置中,以便按下它们不会退出该OnKeyUp过程。

于 2021-07-27T18:50:29.050 回答