动态创建的 TForm 在调用 ShowModal() 时不会将焦点设置为编辑控件

问题描述 投票:0回答:2

我使用

TForm
在 C++Builder 的 IDE 中创建了一个
BorderStyle=bsDialog
并按照本教程使其可用:

动态创建 VCL 模态形式.

然后我在

MainForm::OnShow()
事件中发布自定义消息,然后将 FireDAC 连接设置为
true
启用了
LoginPrompt
属性并使用
OnLogin()
事件,然后打开我的表单。

我的问题是,当对话框打开时,我的

TEdit
字段没有获得焦点。该表单包含一个使用图标的
TImage
、一个
TGradientLabel
、一个
TEdit
、一个
TStaticText
,以及两个
TButtons
用于 Ok(默认)和 Cancel。首次打开窗体时,按Tab使焦点转到Ok按钮,但没有虚线指示输入焦点;使用 Shift-Tab 转到 Cancel 按钮,但没有虚线指示输入焦点。按下 TabShift-Tab 后,下一个 TabShift-Tab 起作用并有虚线(当在按钮上时)。首次打开表单时,如果您按 Tab 然后按 Shift-Tab,或按 Shift-Tab 然后按 Tab,则
TEdit
字段有光标和输入,就像它从一开始就应该有的那样。

这基本上是我设置/启动表单的方式:

MyForm=new TMyForm(MainForm);
MyForm->ActiveControl=MyForm->EditName;
MyForm->ShowModal();
MyForm->Free();

我发现,如果我单击另一个窗口然后单击回到我的主窗口(或者即使我只是在任务栏上单击它自己),它也可以工作并且

TEdit
控件有光标。

我什至尝试为对话设置

OnShow
的事件,并使用
::SetForegroundWindow()
::SetActiveWindow()
作为表格,并再次尝试设置
ActiveControl
,甚至使用
MyForm->SetFocus()
,但没有任何效果。

我正在使用 Windows 10,还有什么需要做的吗(显然有)?

delphi c++builder
2个回答
3
投票

如果您正确设计了表单对话框,则无需手动将焦点设置到您的

TEdit
控件。

您会在设计时看到,您可以通过设置其 TabOrder 属性来控制可聚焦组件之间的访问顺序。

默认情况下,表单设计器根据您已经放置在表单上的组件的顺序设置

TabOrder
属性。因此,例如,如果您先放置两个按钮,然后放置编辑控件,它的
TabOrder
将设置为 2.

因此,解决问题所需要做的就是简单地将

TabOrder
组件的
TEdit
属性更改为 0,这将确保它在显示表单时获得焦点。

如果您有多个

TEdit
控件(用户名和密码),请将用户名编辑
TabOrder
属性设置为0,将密码编辑
TabOrder
属性设置为1。这样用户就可以使用Tab键从用户名切换到密码控件。


-2
投票

我不确定内部发生的事情的细节(不确定如何让间谍++在窗口存在之前观看窗口的消息),但我通过简单地重试自定义消息解决了这个问题(

UWM_MAINDIALOGSHOWN
) 又多次,我记下了即使 1 次就足够了。我把它放在我的自定义消息的顶部:

static int redo=1;
if (redo) {
    redo--;
    PostMessage(Handle, UWM_MAINDIALOGSHOWN, 0, 0);
    return;
}

如果有人有更多关于内部结构的细节,那很好,但如果其他人遇到这个问题,至少有一些有用的东西。

© www.soinside.com 2019 - 2024. All rights reserved.