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

pkmbmrz7  于 2023-04-20  发布在  其他
关注(0)|答案(2)|浏览(166)

我用BorderStyle=bsDialog在C++Builder的IDE中创建了一个TForm,并在本教程之后使其可用:
Dynamically Creating a VCL Modal Form
然后,我在MainForm::OnShow()事件中发布一条自定义消息,然后将FireDAC连接设置为启用了LoginPrompt属性的true,并使用OnLogin()事件,然后打开我的表单。
我的问题是,当对话框打开时,我的TEdit字段没有获得焦点。表单包含一个使用图标的TImage、一个TGradientLabel、一个TEdit、一个TStaticText和两个TButtons,用于确定(默认)和【取消】,第一次打开表单时,按Tab键会将焦点转到【确定】按钮,但没有虚线表示输入焦点;使用Shift-Tab转到取消按钮,但没有虚线表示输入焦点。按Tab或Shift-Tab后,下一个Tab或Shift-Tab工作并具有虚线(当在按钮上时)。当表单第一次打开时,如果您先Tab然后Shift-Tab,或Shift-Tab然后Tab,则TEdit字段具有光标和输入,就像它从一开始就应该具有的那样。
下面是我如何设置/启动表单的基本方法:

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

我发现,如果我点击另一个窗口,然后点击回到我的主窗口(或者即使我只是点击任务栏上的本身),它也能工作,TEdit控件有光标。
我甚至尝试为对话框设置OnShow的事件,并为Form使用::SetForegroundWindow()::SetActiveWindow(),并再次尝试设置ActiveControl,甚至使用MyForm->SetFocus(),但没有任何工作。
我正在使用Windows 10,是否还有其他需要做的事情(显然有)?

a2mppw5e

a2mppw5e1#

如果您已经正确设计了窗体对话框,则不需要手动将焦点设置到TEdit控件。
您可以看到,在设计时,您通过设置TabOrder属性来控制可聚焦组件之间的访问顺序。
默认情况下,表单设计器根据您在表单上放置组件的顺序设置TabOrder属性。例如,如果您先放置两个按钮,然后再放置编辑控件,则其TabOrder将设置为2。
因此,要解决这个问题,您所要做的就是将TEdit组件的TabOrder属性更改为0,这将确保在显示表单时它是焦点。
如果您有多个TEdit控件(用户名和密码),请将username edit TabOrder属性设置为0,并将password edit TabOrder属性设置为1。这样,用户可以使用Tab键从用户名移动到密码控件。

elcex8rz

elcex8rz2#

我不确定内部发生了什么的细节(不知道如何让spy++在窗口存在之前查看窗口的消息),但我通过简单地重试自定义消息(UWM_MAINDIALOGSHOWN)再次多次解决了这个问题,我得到了它,即使是1次也足够了.我把这个放在我的自定义消息的顶部:

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

如果有人有更多的细节,对内部,这是伟大的,但至少有一些工作,如果别人运行到这一点。

相关问题