英文:
TForm created dynamically won't set focus to edit control when calling ShowModal()
问题
I created a TForm
in the IDE of C++Builder with BorderStyle=bsDialog
and made it available following this tutorial:
Dynamically Creating a VCL Modal Form.
I then POST a custom message in the MainForm::OnShow()
event, which then sets a FireDAC connection to true
which has the LoginPrompt
property enabled and uses the OnLogin()
event, which then opens up my form.
My issue is that my TEdit
field does not get the focus when the dialog is opened. The form contains a TImage
using an icon, a TGradientLabel
, a TEdit
, a TStaticText
, and two TButtons
for Ok (default) and Cancel. When the form is first opened, pressing Tab makes the focus go to the Ok button, but without the dashed line to indicate input focus; using Shift-Tab goes to the Cancel button, but without the dashed line to indicate input focus. After pressing Tab or Shift-Tab, the next Tab or Shift-Tab works and has the dashed line (when on a button). When the form is first opened, if you Tab then Shift-Tab, or Shift-Tab then Tab, the TEdit
field has the cursor and input like it should have from the start.
Here's basically how I set up / start the form:
MyForm=new TMyForm(MainForm);
MyForm->ActiveControl=MyForm->EditName;
MyForm->ShowModal();
MyForm->Free();
I found that if I click another Window then click back to my Main Window (or even if I just click on itself on the Taskbar), it also works, and the TEdit
control has the cursor.
I even tried setting up an event for OnShow
for the dialog and used ::SetForegroundWindow()
, ::SetActiveWindow()
for the Form, and tried again setting ActiveControl
, and even using MyForm->SetFocus()
, but nothing is working.
I'm using Windows 10, is there something else that needs to be done (clearly there is)?
英文:
I created a TForm
in the IDE of C++Builder with BorderStyle=bsDialog
and made it available following this tutorial:
Dynamically Creating a VCL Modal Form.
I then POST a custom message in the MainForm::OnShow()
event, which then sets a FireDAC connection to true
which has the LoginPrompt
property enabled and uses the OnLogin()
event, which then opens up my form.
My issue is that my TEdit
field does not get the focus when the dialog is opened. The form contains a TImage
using an icon, a TGradientLabel
, a TEdit
, a TStaticText
, and two TButtons
for Ok (default) and Cancel. When the form is first opened, pressing <kbd>Tab</kbd> makes the focus go to the Ok button, but without the dashed line to indicate input focus; using <kbd>Shift-Tab</kbd> goes to the Cancel button, but without the dashed line to indicate input focus. After pressing <kbd>Tab</kbd> or <kbd>Shift-Tab</kbd>, the next <kbd>Tab</kbd> or <kbd>Shift-Tab</kbd> works and has the dashed line (when on a button). When the form is first opened, if you <kbd>Tab</kbd> then <kbd>Shift-Tab</kbd>, or <kbd>Shift-Tab</kbd> then <kbd>Tab</kbd>, the TEdit
field has the cursor and input like it should have from the start.
Here's basically how I setup / start the form:
MyForm=new TMyForm(MainForm);
MyForm->ActiveControl=MyForm->EditName;
MyForm->ShowModal();
MyForm->Free();
I found that if I click another Window then click back to my Main Window (or even if I just click on itself on the Taskbar), it also works and the TEdit
control has the cursor.
I even tried setting up an event for OnShow
for the dialog, and used ::SetForegroundWindow()
, ::SetActiveWindow()
for the Form, and tried again setting ActiveControl
, and even using MyForm->SetFocus()
, but nothing is working.
I'm using Windows 10, is there something else that needs to be done (clearly there is)?
答案1
得分: 3
无需手动将焦点设置到您的 TEdit
控件,如果您已经正确设计了您的表单对话框。
在设计时,您可以通过设置它们的 TabOrder 属性来控制可接受焦点组件的访问顺序。
默认情况下,表单设计器根据您已经放置在表单上的组件的顺序设置 TabOrder
属性。例如,如果您先放置了两个按钮,然后放置编辑控件,它的 TabOrder
将设置为 2。
因此,要解决您的问题,您只需简单地将 TEdit
组件的 TabOrder
属性更改为 0,这将确保在显示表单时它获得焦点。
如果您有多个 TEdit
控件(用户名和密码),请将用户名编辑的 TabOrder
属性设置为 0,将密码编辑的 TabOrder
属性设置为 1。这样,用户可以使用 Tab 键从用户名移动到密码控件。
英文:
There is no need for manually setting focus to your TEdit
control if you have designed your form dialog properly.
You see at Design time you control the order of visiting between focusable components by setting their TabOrder propery.
By default form designer sets TabOrder
property based on the order of components you already placed on your form. So for instance if you have placed the two buttons first and then the edit control it will have its TabOrder
set to 2.
So all you have to do to solve your problem is to simply change the TabOrder
property of your TEdit
component to 0 which will make sure it is focused when the form is shown.
If you have multiple TEdit
controls (username and password) set username edit TabOrder
property to 0 and password edit TabOrder
property to 1. This way user can move from username to password control using Tab key.
答案2
得分: -2
我对内部情况的细节不太确定(不确定如何让spy++在窗口存在之前监视窗口的消息),但我通过简单地多次重试自定义消息(`UWM_MAINDIALOGSHOWN`)来解决了这个问题,我发现即使一次也足够了。我将这个放在我的自定义消息的顶部:
```c++
static int redo=1;
if (redo) {
redo--;
PostMessage(Handle, UWM_MAINDIALOGSHOWN, 0, 0);
return;
}
如果有人对内部情况有更多细节,那将是很棒的,但至少现在有一些可以解决这个问题的方法。
<details>
<summary>英文:</summary>
I'm not sure of the details of what is going on internally (not sure how to get spy++ to watch the messages of a Window before the Window exist), but I solved the issue by simply retrying the custom message (`UWM_MAINDIALOGSHOWN`) again multiple times, I got it down that even 1 time is enough. I put this at the top of my custom message:
```c++
static int redo=1;
if (redo) {
redo--;
PostMessage(Handle, UWM_MAINDIALOGSHOWN, 0, 0);
return;
}
If someone has more details on the internals, that be great, but at least there is something that works if someone else runs in to this.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论