控件'xxx'没有父窗口

Mar*_*mke 10 delphi dll tframe

我正在尝试在Delphi中编写一个dll库,该函数创建一个TFrame后代的实例并返回它.但是当我在一个应用程序中导入这个函数时,每次调用它时我都会得到一个例外,例如"'xxx'控件没有父窗口".我不是百分百肯定,但是当访问任何GUI控件时,该类的构造函数中出现异常.

你能告诉我这种行为的原因是什么吗?我应该只使用TForm后代还是有更好的解决方案?

谢谢!

Cos*_*und 8

关于错误

从该TWinControl.CreateWnd方法从Controls.pas单元引发该错误消息.本质上,该代码用于为您的TWinControl后代创建Window句柄(TFrame,TButton,TEdit ......如果它可以有键盘焦点,它是一个TWinControl后代),它实际上是一个非常明智的错误消息:你不能有一个没有WindowParent的窗口,因为我们在这里谈论VCL,尝试从TWinControl.Parent获取父窗口句柄是很有意义的; 那并没有分配.

这不是为什么弹出错误消息.您将看到该错误消息,因为您用于设置框架的某些代码需要一个Window句柄来执行某些操作.它可以是任何东西,比如设置某个组件的Caption(内部需要一个窗口句柄来进行某些计算).当发生这种情况时,我个人真的很讨厌它.当我从代码创建GUI时,我试图尽可能地延迟Parent的赋值,试图延迟窗口的创建,所以我被这多次咬了.

特定于您的DLL使用,可能的修复

我打算戴上心理读者的帽子.因为你需要从你的DLL中返回一个FRAME,并且你不能返回实际的Frame,因为那是一个特定于Delphi的对象而且你不允许在DLL边界上返回特定于Delphi的对象,我猜你正在返回一个Window Handle,就像所有很好的API一样,使用这样的函数定义:

function GiveMeTheNiceFrame:HWND;
Run Code Online (Sandbox Code Playgroud)

麻烦的是,该例程需要创建实际的Window Handle,通过调用TWinControl.CreateWnd,反过来该调用需要父窗口句柄来设置调用Windows.CreateWindowEx,并且例程不能获得父窗口句柄,所以它错了.

尝试使用以下内容替换您的函数:

function GiveMeTheNiceFrame(OwnerWindow:HWND):HWND;
begin
  Result := TMyNiceFrame.CreateParanted(OwnerWindow).Handle;
end;
Run Code Online (Sandbox Code Playgroud)

... ie:使用CreateParented(AParentWindow:HWND)构造函数,而不是通常的Create(AOwner:TComponent)并将所有者HWND传递给您的DLL.