Delphi中没有VCL表单的组件

Delphi中没有VCL表单的组件,delphi,winapi,vcl,Delphi,Winapi,Vcl,这可能是一个关于现实世界中不需要的东西的问题 . 但我想知道我们能做到吗(仅仅为了知识) 我可以在没有vcl表单的情况下显示vcl组件吗。我们可以创建和使用非可视vcl,但我们可以在可视vcl中创建并使其在屏幕上可见 或者至少我们可以在使用windows API创建的表单中放置VCL,是-如果我很理解您的问题。我已经完成了完整的安装程序,没有形式,视觉和非视觉vcl,和api。当然,要使其可视化(无控制台),您需要一个窗口 示例代码-无表单(打开以下.dpr文件并编译): 对于VCL组件,答案显

这可能是一个关于现实世界中不需要的东西的问题 . 但我想知道我们能做到吗(仅仅为了知识)

我可以在没有vcl表单的情况下显示vcl组件吗。我们可以创建和使用非可视vcl,但我们可以在可视vcl中创建并使其在屏幕上可见


或者至少我们可以在使用windows API创建的表单中放置VCL,

是-如果我很理解您的问题。我已经完成了完整的安装程序,没有形式,视觉和非视觉vcl,和api。当然,要使其可视化(无控制台),您需要一个窗口

示例代码-无表单(打开以下.dpr文件并编译):


对于VCL组件,答案显然是肯定的组件可以在形式外上下文中使用,无需任何麻烦,只需通过指定
nil
绕过所有权机制,并在完成后手动销毁实例即可

NoLongerDependsOnForm := TSomeComponent.Create(nil);
NoLongerDependsOnForm.This;
NoLongerDependsOnForm.That;
FreeAndNil(NoLongerDependsOnForm);
使用VCL控件时,事情会变得更加复杂,因为任何子窗口都需要父窗口。因此,在通用窗口中重用TWinControl仅在理论上是可能的(必须编写VCL存根才能使其工作)。所以,答案几乎是否定的


我求求你们,请不要把表单和窗口的术语弄混了。(进一步阅读:顶级窗口和子窗口)

控件可以在所有者和父容器中查找和访问属性,并将其作为VCL类访问。如果没有,VCL控制很有可能无法工作

避免这种情况的一种方法是将它们包装为ActiveX控件。然后,您可以在支持ActiveX控件的任何语言中使用Then。

不,VCL控件(可视组件)不能存在于VCL窗体之外。但是,您可以将VCL控件放置在VCL窗体中,然后将VCL窗体托管在其他类型的窗口中。Delphi对创建ActiveX控件的支持做到了这一点——VCL表单(我认为是TCustomActiveForm)提供了分发给ActiveX的窗口句柄。您的VCL组件位于该TCustomActiveForm或该类的后代内部,永远不知道它们之间的区别

如果您愿意进行一些挖掘和提升,您可能可以避免ActiveX的开销。首先,检查TCustomForm上的ParentHwnd属性或CreateParented方法。这可能就是你所需要的——我一时想不起来了,我已经好几年没有看到代码了

如果不是,则可以重写TCustomForm子代中的CreateParams方法,并将非VCL窗口句柄分配给Params.WndParent字段。在调用继承的CreateParams后执行此操作,以便获得其他所有内容的所有正常设置。您可能还需要调整样式和exstyle标志,以删除表单的边框、标题等

在此自定义窗体中构造VCL控件,并调整其大小以占据整个窗体区域


您可能可以使用比TCustomForm更低级别的控件(如TCustomWinControl)来执行此操作,但可能会丢失一些击键/加速器窗口消息处理。我知道这可以在TCustomForm级别完成。

这不仅仅是我自己的代码,而是你为我工作的所有代码的混合体

只需为volvox的答案添加这些代码(我已接受并在顶部)


是的,这可能是可能的,但可能不是很方便。这是一个很好的评论,因为你说是的!但是你为什么在评论中问how?在Q中,你说你不需要这样做。我希望这是可以做到的。就我个人而言,我会将其托管在TForm子代中,并使用ParentWnd属性将其作为父对象。您误解了OP。他有一个自定义控件
TMyCustomControl
,他希望使用该控件。但我的问题是,我可以在win api表单(非vcl表单)上显示vcl吗?如果您注册所有vcl类、父类等,为什么不可以呢?您需要(可能正在包装其中一些)在窗口程序内。我认为使用复杂的vcl类不是一件容易的任务。你接受了一个不回答你问题的答案!奇怪。我在这里根本没有看到任何vcl。它只使用窗口和消息。这是一个典型的Petzold风格的Windows程序。@David Heffernan是的,但我在自己的回答中添加了一些代码answer@dthorpe难道你不能只使用ParentWindow或CreateParented吗?编辑:我现在看到我在质疑Danny thorpe的Delphi知识,所以我想你是对的!!CreateParented可能会这样做。我以为我们已经实现了某种更自动化的方式来实现这一点,但我手头没有任何VCL源,在线文档仍然有很多需要编辑esired.@dthorpe“在线文档仍有很多需要改进的地方”“nuff说!CreateParented接受了一个HWND,它在Params.WndParent中结束。我不确定您是否需要对样式标志做很多工作,我认为您可以只设置表单。Align:=alClient。我这样做是为了将VCL表单放在其他VCL表单中。您确定不喜欢返回Delphi产品开发吗?!您和Barry将是一个非常强大的团队!!!@Da!”vid:再次使用Delphi代码将是一种享受,但一旦你离开家,你就永远无法真正回来。@dthorpe:你当然是对的,但我们用户只能梦想!如果你留下来,我相信我们现在已经有64位Delphi了,这是我的一个特别的bug熊。至少听起来好像这方面终于取得了很好的进展。T公平地说,微软很容易将它们混淆,因为操作系统称为Windows,99.99%的用户将窗体称为窗口!更简单的是abtn:=TButton.CreateParented(hEdit)
NoLongerDependsOnForm := TSomeComponent.Create(nil);
NoLongerDependsOnForm.This;
NoLongerDependsOnForm.That;
FreeAndNil(NoLongerDependsOnForm);
uses
  Windows,
  Messages,buttons,stdctrls;


var
abtn:TButton ;


begin
//  after all declaration
 abtn := TButton.Create(nil) ;
 abtn.ParentWindow := hEdit ; // use window handle but i use hedit because my button     will be hidden by another button in example
end