【问题标题】:Change Ctrl-Ins to Ctrl-C in keydown handler在 keydown 处理程序中将 Ctrl-Ins 更改为 Ctrl-C
【发布时间】:2014-12-12 09:08:34
【问题描述】:

我有一个第 3 方控件 (DevExpress TcxVirtualTreeList),它讨厌接收 Ins 按键(访问冲突),它处理老式的 Ctrl-Ins(复制到剪贴板)也作为 Ins

所以我想在其 OnKeyDown 处理程序中将 Ctrl-Ins 更改为 Ctrl-C

 if (Key=VK_INSERT) and (Shift=[]) then              // Insert
 begin  
    // Handle insert ourselves
    ...
    Key := 0;
 end
 else if (Key=VK_INSERT) and (Shift=[ssCtrl]) then   // Ctrl-Ins
 begin
    Key := 67; // 'C'   
 end

但这不起作用。所选文本(在TcxVirtualTreeList 的内部编辑器中)不会像 Ctrl-C 那样复制到剪贴板。

我做错了什么以及如何获得预期的结果?

  • 我已验证 C 确实是 67(顺便说一句,VK_C 是否在任何单元中定义?)
  • 在带有KeyPreview=false 的表单上有一个 OnKeydown 处理程序,用于处理 Ctrl-Shift-CCtrl kbd>-Shift-V。禁用该处理程序没有任何影响(如预期的那样)。

[使用普通 TEdit 编辑测试用例]
抱歉,我提到它是一个 DevEx 控件,这让我很困惑。这与问题无关。

我设法在一个带有 TEdit 的小应用程序中对其进行了测试,反过来(从表单到编辑)使用 Form.KeyPreview=true

procedure TFrmChangeKeyInDown.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
   if (Key=VK_INSERT) and (Shift=[]) then
   begin
      Memo1.Lines.Add('FormKeyDown: Ins detected');
   end
   else if (Key=VK_INSERT) and (Shift=[ssCtrl]) then
   begin
      Memo1.Lines.Add('FormKeyDown: Ctrl-Ins detected, changing to Ctrl-C');
      Key := 67;
   end;
end;

procedure TFrmChangeKeyInDown.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
   if (Key=VK_INSERT) and (Shift=[]) then
   begin
      Memo1.Lines.Add('EditKeyDown: Ins detected');
   end
   else if (Key=VK_INSERT) and (Shift=[ssCtrl]) then
   begin
      Memo1.Lines.Add('EditKeyDown: Ctrl-Ins detected');
   end
   else if (Key=67) and (Shift=[ssCtrl]) then
   begin
      Memo1.Lines.Add('EditKeyDown: Ctrl-C detected');
   end;
end;

在编辑控件中输入一些东西,选择一个单词,按Ctrl-Ins,备忘录显示:

FormKeyDown: Ctrl-Ins detected, changing to Ctrl-C
EditKeyDown: Ctrl-C detected

但我的剪贴板缓冲区的内容现在不是那个词了。使用 Ctrl-C 执行此操作,效果很好。

【问题讨论】:

  • 这似乎有点奇怪。肯定会有其他人注意到的。 devExpress 怎么说?我希望他们能修复如此严重的错误。另外,我猜你有源代码,所以你可以很容易地自己修复它。
  • 这很微妙。我实际上是在谈论将 TcxVirtualTreeList 转换为他们的 TcxScheduler.GanttView.TreeBrowser 你不应该有 OptionsData.Inserting := true 的地方。我确实设置了它,因为我想要其他功能(带有 Insert 键的 NavBar),结果是我必须处理一些事情,比如阻止 Ins,并在您向下移过最后一行时阻止自动附加。我不怪他们,因为他们的控制似乎不再听老式的 Ctrl-Ins。我是一个老式的用户,我的手指已经长出了这种组合。
  • @david 欢迎您提出关于深入研究其源代码的建议。让我们看看结果如何。
  • 哦,你想处理这种对标准快捷方式的虚假处理是绝对正确的。我不同意这一点。

标签: delphi delphi-xe2


【解决方案1】:

不知道这是否是一个可接受的解决方案,但如果你添加

Edit.CopyToClipboard;

到 EditKeyDown 处理程序,就在(或代替)

Memo1.Lines.Add('EditKeyDown: Ctrl+C 检测到');

然后它将文本复制到剪贴板,就像您自己按了 Ctrl+C 一样。如果您使用的 TreeList 控件上没有 CopyToClipboard,则可以使用

Clipboard.AsText:=<Text to copy to clipboard>

如果您可以从 ListView 访问当前选定的文本。

Ctrl+C 处理不是由 VCL 完成的,而是由 Windows、AFAIK、所以你不能只是“喂”Ctrl kbd>+C/Ctrl+V 进入VCL控件并期望它执行剪贴板操作

【讨论】:

  • 我还没有尝试过,但它应该是要走的路。你最后的话当然是对的,我已经编辑了它以强调。
  • 由于我使用的是 DevEx TcxVirtualTreeList,我的 OnKeyDown 处理程序中的代码现在是(如果 (Key=VK_INSERT) 和 (Shift=[ssCtrl])):如果 FTreeList.InplaceEditor 是 TcxCustomTextEdit然后 Clipboard.AsText := TcxCustomTextEdit(FTreeList.InplaceEditor).SelText;
  • @JanDoggen:我建议您使用 (Shift*[ssShift,ssAlt,ssCtrl]=[ssCtrl]) 来检查是否按下了 Ctrl,因为 TShiftState 可能包含的信息不仅仅是当前各种 shift 键的按下 shift 状态...
猜你喜欢
  • 2018-11-26
  • 1970-01-01
  • 1970-01-01
  • 2013-08-19
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多