可以允许由Delphi TAction处理的ShortCut-Key进一步传播到其他组件吗?



核心问题:我不喜欢 TcxGrid 删除(由 TcxGrid 的默认 Ctrl+Del 快捷键或 cx-navigator 的删除按钮启动)的工作方式:它是对底层数据集删除的简单直接调用,cxGrid 或 cxGridDataView 没有TcxGrid(/DataController).OnDelete(Sender: TObject, var AHandled: Boolean)事件。从 https://www.devexpress.com/Support/Center/Question/Details/Q308755/tcxgrid-deleting-record 我了解到我只能配置确认消息,但我无法控制删除本身,即我无法实现自定义删除,因此我什至不尝试直接解决此问题。我的问题是关于解决方法。

这就是为什么我拒绝使用 cx-navigator 并且我选择引入处理整个表单的 Ctrl+Del 快捷键的 TAction。我在表单上有多个网格,每个网格都有自己的有问题的删除过程,应由自定义过程以非标准方式处理。

这就是为什么我的DeleteAction最初确定ActiveControl(TcxGridSite,TcxGrid),然后调用相关的删除过程。一切都很好。但是其他一些组件(例如TcxDBTextEdit)也有默认的Ctrl + Del处理,并且处理非常非常好。但是,如果快捷键 Ctrl+Del 由操作处理(即使在找不到活动网格的情况下,它也会标记为已处理,因此即使在 ActionExecute 没有做任何有用操作的情况下也是如此),则进一步传播将停止。这可以从经验上观察到,也可以从理论上从 http://edn.embarcadero.com/article/38447 上看到。

但是,也许仍然有一些解决方法,如果默认组件是活动控件,则ActionExecute处理的快捷键仍然可以进一步传播到默认组件。

我知道TAction用于(表单范围的全局)菜单功能,但TcxGrid的可扩展性不够,这就是为什么也应该尝试扩展Delphi TAction设计的原因。

可能有多种方法可以实现您需要的处理,在密钥处理过程中您可以干预很多地方,正如您已经从 Peter Under 的文章中阅读的那样。

我能想到的一个干预的地方是表单的IsShortCut方法。这种方法的一个可能的缺点可能是,您必须在希望更改其键处理行为的所有窗体上实现它。

通常,仅当快捷键未处理密钥处理时,密钥处理才会继续。下面的解决方案报告由于该原因未处理的快捷方式,但随后必须手动执行操作。如所见,我用常规编辑测试了代码,但我想它应该没有任何区别。

function TForm1.IsShortCut(var Message: TWMKey): Boolean;
begin
if (ActiveControl is TEdit) and (Message.CharCode = VK_DELETE) and
(KeyDataToShiftState(Message.KeyData) = [ssCtrl]) then begin
Result := False; // if you don't require the action to be executed, just exist here 
ActionList1.IsShortCut(Message); // executes the action, ignore result 
// returning false will result in main form's shortcut handler to be called
// below is only required if this is the main form
if Application.MainForm = Self then
Message.CharCode := 0;
end else
Result := inherited IsShortCut(Message);
end;

最新更新