我在 Delphi 中有一个带有一些面板的表单。这些面板确实包含可以接收文本输入的控件(如
tEdit
和 tMemo
),以及通常不接收文本输入的其他控件(如 tButton
)。主窗体还定义了按下“A”字符键时使用 tActionList
组件的快捷键。
当按下“A”键时,它总是会触发快捷方式。我可以重写表单中的
IsShortCut
方法,并手动检查当前焦点是否位于其中一个输入控件上。但这有一个缺点,我需要明确地遍历每个组件(它们有很多),并且由于某些组件可以具有内部控件(如网格中的查找器),因此很难涵盖所有组件。
是否有一些通用方法来检查表单上具有焦点的控件是否是某些文本输入控件?
通常,如果您的表单具有接受字符输入的控件,则您不会使用纯字符作为操作快捷方式。
您可以使用修饰符(如 Ctrl+S)或功能键(如 F7)。
还值得记住的是,所有按钮(默认的“确定”和“取消”按钮除外)都应该有访问键,例如
&Save
。如果按钮的标题是 &Save
,S 将带有下划线,并且在表单获得焦点时按 S 将“单击”&Save
按钮,即使它本身没有获得焦点 - 只要当前获得焦点的控件没有获得焦点当然,不接受字符输入(如TEdit
)。
话虽如此,我不确定您是否知道测试聚焦控件的class的可能性?
function TForm1.FocusedControlAcceptsChars: Boolean;
begin
var LCtl := ActiveControl;
Result := (LCtl is TCustomEdit) {or (LCtl is TCustomRichEdit) or (LCtl is TCustomListView) or ...};
end;
这样,您就不需要针对 132 个子控件进行测试,而是针对 3 或 4 个控件类进行测试。
如果这仍然不够好,您可能想询问焦点控件本身是否接受字符输入:
function TForm1.FocusedControlAcceptsChars2: Boolean;
begin
var LCtl := ActiveControl;
if LCtl = nil then
Exit(False);
Result := LCtl.Perform(WM_GETDLGCODE, 0, 0) and DLGC_WANTCHARS <> 0;
end;
显然,这两种方法可以结合起来。
另一种检查是否为编辑控件的方法:
function TForm1.FocusedControlAcceptsChars2: Boolean;
begin
var LCtl := ActiveControl;
Result := Assigned(LCtl) and (LCtl.Enabled) and (SendMessage(LCtl.Handle, EM_SETREADONLY, 0, 0) <> 0);
end;