我有一个模态形式(A),显示另一种模态形式(B)。 B显示数据集并允许用户与其进行交互。我的问题是,一个动作要求A再次成为聚焦形式,这样用户可以输入某些值而不关闭B.我已经尝试了A.BringToFront和A.SetFocus它确实显示在前面,但输入焦点保留在B中当你点击不应该的地方时,A中的任何点击或类似物都会导致窗口“叮”。代码有点像
A.ShowModal; 。 。 。在A事件中: B.ShowModal(); 。 。 。在B事件中:
someobject.someMethodThatRequiresAFocused;
我的猜测是,一些模糊和奇怪的API调用可以再次使A模态¿任何想法?
此致
答案 0 :(得分:5)
当显示模态表单时,所有当前可见的表单包括其他模态表单都将被禁用。因此,不可能在多个模态形式之间切换。您需要重新考虑您的UI设计,以便B
不会返回A
以获取新输入。至少,您可以B
打开一个新的模式表单C
,提示用户输入所需的值并将其提供给B
,然后B
或C
之后可以使用新值更新A
。
答案 1 :(得分:3)
没有API可以在窗口之间切换模态。无论如何,您正在寻找案例的API是EnableWindow
。这就是模态的工作原理,除了用户应该使用的窗口之外的窗口被禁用,以便他/她不能与它们交互。这也是'ding'声音的原因,为用户提供反馈。
因此,虽然让用户使用已禁用另一个模态窗口的窗口在技术上很容易,但处理状态可能不是直截了当的。我在下面提供一个最基本的例子,看看它似乎需要什么。
'FormB'首先。让我们假设您在'Owner'参数中传递'FormA'的引用,而'FormA'正在构建'FormB'。以下是应该使'FormA'模式的代码看起来像:
procedure TFormB.BtnMakeFormAModalAgainClick(Sender: TObject);
begin
Enabled := False; // so that 'A' will behave like it's modal
EnableWindow(TFormA(Owner).Handle, True); // so that 'A' could be interacted
TFormA(Owner).SetFocus;
end;
当这段代码运行时,会发生什么'FormA'被启用并被带到前面,而'FormB'被禁用 - 点击时会产生'ding'。
但我们还没有完成。因为我们已经修改了模态的含义 - 现在我们不希望在用户完成时关闭'FormA'。下面是'FormA的单元中的代码如何看起来像:
type
TFormA = class(TForm)
BtnShowModalB: TButton;
BtnOk: TButton;
procedure BtnShowModalBClick(Sender: TObject);
procedure BtnOkClick(Sender: TObject);
private
FModalB: TForm;
end;
implementation
uses
unitOfFormB;
{$R *.dfm}
procedure TFormA.BtnShowModalBClick(Sender: TObject);
begin
FModalB := TFormB.Create(Self); // so that FormB can find FormA from the Owner
FModalB.ShowModal;
FModalB.Free;
FModalB := nil; // Need this if we're going to decide if FormB is showing
// by testing against this reference
end;
procedure TFormA.BtnOkClick(Sender: TObject);
begin
if Assigned(FModalB) then begin // is FormB the actual modal form?
EnableWindow(Handle, False); // disable this form so it would 'ding'
FModalB.Enabled := True; // enable FormB, so user can interact with it
FModalB.SetFocus;
ModalResult := mrNone; // don't close, FormB is the first one to be closed
end else
ModalResult := mrOk;
end;
我几乎肯定这个例子不完整,但这里是你正在寻找的API。