【问题标题】:Shift value when only CTRL key is pressed?仅按下 CTRL 键时移位值?
【发布时间】:2017-02-03 15:02:45
【问题描述】:

创建一个 VCL Forms 应用程序并在主窗体的 OnMouseDown 事件处理程序中写入:

procedure TForm2.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Shift = [ssCtrl] then
    ShowMessage('CTRL pressed');
end;

然后运行应用程序,按住 CTRL 键,不使用其他修饰键,然后单击表单。不显示任何消息。为什么是现在?

那么Shift 在这种情况下,当仅按下 CTRL 键时,有哪个值?

【问题讨论】:

  • 您为什么不自己通过在调试器中评估Shift 来回答这个问题?它会立即告诉你 Shift 的内容不仅仅是 [ssCtrl] 即使只按下了一个 Ctrl 键。

标签: delphi delphi-10.1-berlin modifier-key


【解决方案1】:

TShiftState 类型定义如下:

type
  TShiftState = set of (ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle, ssDouble, 
    ssTouch, ssPen, ssCommand, ssHorizontal);

如您所见, is 包含的信息远不止修饰键状态。

当您按住 CTRL 键并单击表单时,Shift 具有以下值:[ssCtrl,ssLeft]。这告诉您 CTRL 键已按下,并且鼠标左键已按下。请注意,使用调试器很容易获得此信息。学习如何使用调试来检查程序在执行过程中的状态是一项非常重要的技能。

如果你想测试修饰键的状态,你需要屏蔽掉所有不是修饰键的东西。使用设置交集的* 运算符执行此操作。这使您可以将信息缩减为仅感兴趣的枚举值。

if Shift*[ssShift, ssAlt, ssCtrl] = [ssCtrl] then
  ....

【讨论】:

  • 太棒了! Jerry Dodge 的回答是正确且好的,但这更优雅。
  • 因为ssCtrl in Shift 在包含控制键的任何修饰符组合关闭时为真。但是您特别要求只提供控制键。
  • 原始问题询问“在这种情况下,当仅按下 CTRL 键时,Shift 具有哪个值?”,它没有提及任何其他修饰键。对 ssctrl 的测试满足原始问题。
  • @SertacAkyuz 这是非常字面的意思,但我认为很明显,提问者没有意识到Shift 报告了除修饰符之外的键。因此我对这个问题进行了编辑。
  • @David - 您对问题的编辑很好。但是,在我看来,不考虑显而易见的的答案不一定是错误的。
【解决方案2】:

TShiftState 是一个枚举集,这意味着可能有多个值。当您执行if Shift = [ssCtrl] 时,您正在检查它是否完全 等于那个值。但是,可能还有其他值。

所以,请这样做:

if ssCtrl in Shift then
  ...

【讨论】:

  • 当我同时按住CtrlShift 修饰键时,这也是True。但问题是:“那么在这种情况下,当仅按下 CTRL 键时,Shift 的值是多少?”
  • @user1580348 你已经正确了。问题在于您是如何进行检查的。
  • @user - 当然是 ssCtrl。但是在您声明的问题中,您单击表单,这不再是 only 控制键。您的问题不一致。
  • 当然,当我问“只有控制键”时,每个人都明白我的意思是“只有控制修饰键”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-04
  • 2012-04-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多