如何在表单显示之前定位?

时间:2009-11-03 13:04:57

标签: delphi forms

我们的应用程序过去常常使用所有表单都要继承的公共基本表单。我想摆脱它有很多原因,从需要警察每个人都使用它到几个与Delphi的VFI实施相关的烦恼。事实证明,它提供的大部分功能都可以通过其他更可靠的方式完成。

我不太确定的是,将所有表单自动定位在其来电者的中心。因此,如果我从主窗体打开Dialog A,它应该放在主窗体的中心。如果我从Dialog A打开Dialog B,它应该放在Dialog A的中心,依此类推。

我们过去通过将基本表单的Position属性设置为poOwnerFormCenter来处理所有这些,并且它运行良好。但是我如何在应用程序范围内执行此操作?

我想过使用Screen.OnActiveFormChange,但我认为每次表单获得焦点时都会发生这种情况。我还想过使用Application.OnModalBegin,但似乎没有一种明显的方法可以在调用它时找到它。

有没有人试过这个?

5 个答案:

答案 0 :(得分:5)

嗯,显然提供了表单继承来解决正好你要解决的问题。任何解决方案都可能以某种方式模仿表单继承。

你能做一些简单的事情,比如全局搜索你的代码“= class(TForm)”,用你现有的基本表单或只有你需要的新的简化基本表单类替换TForm类吗?

如果失败了,您可以尝试修改原始的TForm类本身以获得所需的定位行为。显然,修改提供的类有点危险。

答案 1 :(得分:4)

如果您不打算使用常见的基本表单,那么我建议在每个表单上放置一个非可视组件。该组件可以将您想要的行为注入基本表单。如果您希望在不同的表单上拥有各种不同的行为,那么为您的组件提供一个角色属性,用于定义该表单应具有的角色,然后可以根据该角色注入不同的特征。

顺便说一句,你也可以使用非可视化表单继承,这是我为所有表单创建公共基类的首选方法。它还具有向表单添加属性的优点,然后基于这些属性,您可以更改表单的角色或行为。

答案 2 :(得分:0)

在不了解您的应用程序的情况下,我的建议是将定位代码单独添加到每个表单中 - 没有基类的优点是它可以更容易地使某些表单执行稍微不同的事情,并且它将表单的所有逻辑保存在一个地方。

答案 3 :(得分:0)

我通常使用SetBounds()过程来使用FormShow事件。 使用其他非表单控件,您可以通过覆盖CMShowing消息来执行相同的操作。

答案 4 :(得分:0)

我接受了你对OnModalBegin的看法,并随之运行。以下是“哈克”,但似乎有效。要测试只需拖动表单并单击按钮。

procedure TMainForm.Button1Click(Sender: TObject);
var
  mForm: TForm;
begin
  mForm := TForm.create(self);
  mform.width := 300;
  mform.height := 300;
  mForm.ShowModal;
  mForm.Free;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  application.OnModalBegin := modalbegin;
end;

procedure TMainForm.FormShow(Sender: TObject);
begin
  if Screen.FormCount>1 then begin
    screen.forms[Screen.FormCount-1].left := round((screen.forms[Screen.FormCount-2].left + screen.forms[Screen.FormCount-2].width/2) - screen.forms[Screen.FormCount-1].width/2);
    screen.forms[Screen.FormCount-1].top := round((screen.forms[Screen.FormCount-2].top + screen.forms[Screen.FormCount-2].height/2) - screen.forms[Screen.FormCount-1].height/2);
    application.processmessages;
    screen.forms[Screen.FormCount-1].Caption  := inttostr(screen.forms[Screen.FormCount-1].top)+','+inttostr(screen.forms[Screen.FormCount-1].left);
  end;
end;

procedure TMainForm.ModalBegin(Sender: TObject);
begin
  if Screen.FormCount>=0 then
    screen.forms[Screen.FormCount-1].OnShow := FormShow;
end;