Delphi:在dll中定位表单

发布于 2024-12-11 08:30:02 字数 589 浏览 0 评论 0原文

我正在 dll 中创建一个表单。没有包裹。使用导出的过程调用dll中的窗体:

procedure ShowAbout(const AppHandle: THandle); stdcall;
  var
    aHandle: THandle;
    form:  TfrmAbout;  / my form in some other unit in the dll
  begin

    aHandle:= Application.Handle;
    Application.Handle:= AppHandle;

    form :=TfrmAbout.Create(Application);
    form.ShowModal;
    form.Free;
    Application.Handle:= aHandle;
  end;

窗体显示良好,没有问题。现在,我唯一希望它做的就是将其定位为 poMainFormCenter (我希望它始终显示在主窗体(调用 dll 的窗体)上)。

我尝试使用 form :=TfrmAbout.Create(Application .MainForm);等等,但没有

什么技巧可以帮助这里?

I am creating a form in a dll. No packages. The form in the dll is called by using the exported procedure:

procedure ShowAbout(const AppHandle: THandle); stdcall;
  var
    aHandle: THandle;
    form:  TfrmAbout;  / my form in some other unit in the dll
  begin

    aHandle:= Application.Handle;
    Application.Handle:= AppHandle;

    form :=TfrmAbout.Create(Application);
    form.ShowModal;
    form.Free;
    Application.Handle:= aHandle;
  end;

The form displays well and there are no problems. Now, the only thing I would like it to do is to behave positioning as poMainFormCenter (I want it to display always over the main form (the form that is calling the dll).

I have tried using form :=TfrmAbout.Create(Application.MainForm); etc but no luck.

Any tricks which would help here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怪异←思 2024-12-18 08:30:02

VCL Position 机制依赖于应用程序中所有使用相同版本的 VCL 运行的其他表单。显然这里的情况并非如此,您必须手动定位表单。

通过调用 找出主窗体的位置GetWindowRect() 传递主窗体句柄。然后,您需要计算出您的表单需要位于该表单中心的位置。

procedure PositionForm(Form: TForm; MainWindow: HWND);
var
  MainBounds: TRect;
  MainWidth, MainHeight: Integer;
begin
  if GetWindowRect(MainWindow, MainBounds) then
  begin
    MainWidth := MainBounds.Right-MainBounds.Left;
    MainHeight := MainBounds.Bottom-MainBounds.Top;
    Form.Left := MainBounds.Left + (MainWidth - Form.Width) div 2;
    Form.Top := MainBounds.Top + (MainHeight - Form.Height) div 2
  end;

顺便说一句,您传递的句柄是 HWND 而不是 THandle。您应该相应地更改代码。它不会改变行为,但这样做在逻辑上是正确的。

The VCL Position mechanism relies on the other forms in the application all running with the same version of the VCL. This is clearly not the case here and you will have to position the form manually.

Find out the position of the main form by calling GetWindowRect() passing the main form handle. Then you need to work out where your form needs to go to be in the center of that form.

procedure PositionForm(Form: TForm; MainWindow: HWND);
var
  MainBounds: TRect;
  MainWidth, MainHeight: Integer;
begin
  if GetWindowRect(MainWindow, MainBounds) then
  begin
    MainWidth := MainBounds.Right-MainBounds.Left;
    MainHeight := MainBounds.Bottom-MainBounds.Top;
    Form.Left := MainBounds.Left + (MainWidth - Form.Width) div 2;
    Form.Top := MainBounds.Top + (MainHeight - Form.Height) div 2
  end;

By the way, the handle you are passing is an HWND rather than a THandle. You should change you code accordingly. It won't change behaviour, but it is logically correct to do so.

残月升风 2024-12-18 08:30:02

由于您不使用软件包,因此您的 EXE 和 DLL 都有一个单独的 TApplication 实例。 EXE 中的 TApplication.MainForm 在 DLL 中看不到。更改 TApplication.Handle 不会使 MainForm 发生更改。找到其他方法来正确定位表单,但更好的是:使用包,如果不这样做,您将遇到更多问题。

Since you don't use pacakges, your EXE and your DLL both have a seperate TApplication instance. TApplication.MainForm in your EXE is not seen in your DLL. Changeing TApplication.Handle does not make the MainForm change. Find other ways to position the form right, but better yet: Use packages, you will run into more problems if you don't.

拿命拼未来 2024-12-18 08:30:02

您是否尝试过将 form.ParentWindow 设置为父窗口的句柄?您应该将其作为参数传递给 ShowAbout,或者您可以从 Application 对象(例如 Application.ActiveForm)中挖掘它,但我不确定它是否有效。

调用 TfrmAbout.Create(Application.MainForm) 只是指定 Application.MainForm 负责销毁表单,它应该与窗口层次结构无关,而且我不确定您应该使用如果您在单独的 dll 中创建表单,则会自动销毁。

Have you tried setting form.ParentWindow to the handle of the parent window? You should pass it as a param to ShowAbout, or you could dig it up from Application object (something like Application.ActiveForm) but I'm not sure it would work.

Calling TfrmAbout.Create(Application.MainForm) just specifies that Application.MainForm is responsible for destruction of the form, it should have nothing to do with window hierarchy, also I'm not sure you should be using auto destruction if you create form in a separate dll.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文