如果菜单项的快捷方式不会覆盖本地控件的快捷方式,我该怎么办? 想象一下截图中的这个简单的应用程序。它有一个“撤消”菜单项,分配给它的快捷键CTRL + Z(德语为Strg + Z)。当我在备忘录中编辑一些文本并按CTRL + Z时,我假设备忘录中的最后一个输入被还原,而是执行菜单项。
这在这个虚构的应用程序中尤其糟糕,因为撤消功能现在将删除我上次添加的“项目3”,我正在编辑哪些属性。
CTRL + Z只是一个例子。其他流行的快捷方式会导致类似的问题(复制和粘贴:CTRL + X / C / V,全选:CTRL + A)。
答案 0 :(得分:3)
VCL旨在赋予菜单项快捷键优先权。但是,当ActiveControl为TCustomEdit(调用撤消等)时,您可以编写项目单击处理程序(或操作执行处理程序)以执行一些特殊处理。
编辑:我知道您不喜欢在代码中的许多地方处理所有可能的特殊情况(所有菜单项或操作处理程序)。我担心我不能给你一个完全满意的答案,但也许这会帮助你找到更通用的解决方案。在表单上尝试以下OnShortCut事件处理程序:
procedure TMyForm.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
var
Message: TMessage absolute Msg;
Shift: TShiftState;
begin
Handled := False;
if ActiveControl is TCustomEdit then
begin
Shift := KeyDataToShiftState(Msg.KeyData);
// add more cases if needed
Handled := (Shift = [ssCtrl]) and (Msg.CharCode in [Ord('C'), Ord('X'), Ord('V'), Ord('Z')]);
if Handled then
TCustomEdit(ActiveControl).DefaultHandler(Message);
end
else if ActiveControl is ... then ... // add more cases as needed
end;
您也可以以类似的方式覆盖IsShortCut方法,并从这个新的TCustomForm后代派生您的项目表单。
答案 1 :(得分:1)
您可能需要一个类似的解决方案,如下所示。是的,感觉很麻烦,但这是我当时想到的最简单的方法。如果只有Delphi允许鸭子打字!
{ you need to derive a class supporting this interface
for every distinct control type your UI contains }
IEditOperations = interface(IInterface)
['{C5342AAA-6D62-4654-BF73-B767267CB583}']
function CanCut: boolean;
function CanCopy: boolean;
function CanPaste: boolean;
function CanDelete: boolean;
function CanUndo: boolean;
function CanRedo: boolean;
function CanSelectAll: Boolean;
procedure CutToClipBoard;
procedure Paste;
procedure CopyToClipboard;
procedure Delete;
procedure Undo;
procedure Redo;
procedure SelectAll;
end;
// actions....
procedure TMainDataModule.actEditCutUpdate(Sender: TObject);
var intf: IEditOperations;
begin
if Supports(Screen.ActiveControl, IEditOperations, intf) then
(Sender as TAction).Enabled := intf.CanCut
else
(Sender as TAction).Enabled := False;
end;
procedure TMainDataModule.actEditCutExecute(Sender: TObject);
var intf: IEditOperations;
begin
if Supports(Screen.ActiveControl, IEditOperations, intf) then
intf.CutToClipBoard;
end;
....