Delphi 中没有 VCL 表单的组件
这可能是关于现实世界中不需要的东西的问题 。但我想知道我们可以这样做吗(只是为了知识)
我可以在没有VCL形式的情况下显示vcl组件吗?我们可以创建和使用非可视化 vcl,但我们可以在可视化 vcl 中创建并使用它并使其在屏幕上可见吗?
或者至少我们可以将 VCL 放置在使用 Windows API 创建的 Form 中,
This may be a question about something not need in the real world
. but i want to know can we do it (just for knowledge)
Can i show vcl components without VCL form . We can create and use non visual vcl but can we do it in visual vcl and make it visible on screen.
Or at least can we place a VCL in side a Form created using windows API,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不可以,VCL 控件(可视组件)不能存在于 VCL 表单之外。但是,您可以将 VCL 控件放置在 VCL 窗体中,然后将 VCL 窗体托管在其他类型的窗口内。 Delphi 对创建 ActiveX 控件的支持就是这样做的 - VCL 表单(我认为是 TCustomActiveForm)提供了分发给 ActiveX 的窗口句柄。您的 VCL 组件位于 TCustomActiveForm 或该类的派生类中,并且永远不知道其中的区别。
如果您愿意进行一些挖掘和提升,您也许能够避免 ActiveX 的开销。首先,检查 TCustomForm 上的 ParentHwnd 属性或 CreateParented 方法。这可能就是您所需要的 - 我记不清了,自从我看到代码以来已经有好几年了。
如果没有,您可以重写 TCustomForm 后代中的 CreateParams 方法,并将非 VCL 窗口句柄分配给 Params.WndParent 字段。在调用继承的 CreateParams 之后执行此操作,以便您获得其他所有内容的所有正常设置。您可能还需要调整 style 和 exstyle 标志,以删除表单的边框、标题等。
在此自定义表单中构造您的 VCL 控件,并调整其大小以占据整个表单区域。
您也许可以使用比 TCustomForm 更低级别的控件(例如 TCustomWinControl)来完成此操作,但您可能会丢失一些击键/加速器窗口消息处理。我知道这可以在 TCustomForm 级别完成。
No, a VCL control (visual component) cannot exist outside of a VCL form. However, you can place VCL control(s) in a VCL form, and then host the VCL form inside of some other kind of window. Delphi's support for creating ActiveX controls does this - the VCL form (TCustomActiveForm, I think) provides the window handle that is handed out to ActiveX. Your VCL components live inside that TCustomActiveForm or a descendent of that class and never know the difference.
You might be able to avoid the overhead of ActiveX if you're willing to do some digging and hoisting. First, check out the ParentHwnd property or CreateParented method on TCustomForm. That might be all you need - I can't recall off the top of my head, and it's been several years since I've seen the code.
If not, you can overridie the CreateParams method in a TCustomForm descendent and assign the non-VCL window handle to the Params.WndParent field. Do this after calling the inherited CreateParams so that you get all the normal settings on everything else. You will probably want to adjust the style and exstyle flags as well to remove the form's border, caption, etc.
Construct your VCL control in this custom form and size it to occupy the entire form area.
You might be able to do this with a lower level control than TCustomForm such as TCustomWinControl, but you may lose some keystroke / accelerator window message processing. I know it can be done at the TCustomForm level.
是的 - 如果我很好地理解你的问题。我已经完成了完整的安装程序,没有表单、可视和非可视vcl以及api。当然,为了使其可视化(没有控制台),您需要一个窗口。
示例代码 - 无表单(打开以下 .dpr 文件并编译):
yes - if i understand your question well. I have done full installation program with no form, visual and non visual vcl, and api. Of course to make it visual (no console) you need a window.
Example code - no form (open the following .dpr file and compile):
对于 VCL 组件,答案显然是肯定的。 组件可以脱离表单上下文使用,没有任何麻烦,只需通过指定
nil
绕过所有权机制,并在完成后手动销毁实例。对于 VCL 控件,事情变得更加复杂,因为任何子窗口都需要父窗口。因此,在通用窗口中重用 TWinControl 仅在理论上可行(必须编写 VCL 存根才能使其工作)。所以,答案是否定的。
我恳求您,请停止混淆术语“表单”和“窗口”。 (延伸阅读:顶级窗口和子窗口)
For VCL components answer is clearly yes. Components are usable out of form context w/o any hassle, just bypass ownership mechanism by specifying
nil
and destroy instance manually when finished.With VCL controls things are waaay more complex because any child window needs parent window. Thus, reusing TWinControl within generic window is possible only theoretically (have to write VCL stub to make it work). So, answer is marginally no.
And i'm begging you, please stop mixing up terms form and window. (Further reading: top-level and child windows)
控件可以查找并访问所有者和父容器中的属性,将它们作为 VCL 类进行访问。如果不是,VCL 控件很可能无法工作。
避免这种情况的一种方法是将它们包装为 ActiveX 控件。然后您可以在任何支持 ActiveX 控件的语言中使用 then。
A control may look for and access properties in the owner and parent container, accessing them as VCL classes. If they are not, there are good chance the VCL control won't work.
One way to avoid that is to wrap them as ActiveX controls. Then you can use then in whatever language that supports ActiveX controls.
这不仅仅是我自己的代码,而是对我有用的所有代码的混合器,
只需为 volvox 的答案添加这些代码(我已接受并在顶部 )
This is not just my own code but a mixer of all your code wich worked for me
Just add these code for volvox 's answer(which i have accepted and on the top)