简体   繁体   English

如何从Delphi 5 ActiveX dll创建MDI子窗口,并将其嵌入Delphi XE MDI父级?

[英]How do I create an MDI child window from a Delphi 5 ActiveX dll, and embed it in a Delphi XE MDI parent?

Is there a way to create an MDI child window from an ActiveX dll written in Delphi 5, and to embed it in a MDI parent window created from a Delphi XE windows client application? 有没有办法从Delphi 5中编写的ActiveX dll创建MDI子窗口,并将其嵌入从Delphi XE Windows客户端应用程序创建的MDI父窗口中? If not, is there a way to mimic the behavior? 如果没有,有没有办法模仿这种行为?

Background 背景

There is an application written entirely in Delphi 5. The main form of the application is an MDI parent window. 有一个完全用Delphi 5编写的应用程序。该应用程序的主要形式是MDI父窗口。 All other forms in the application are MDI child forms, and every one of them is created from an ActiveX library. 应用程序中的所有其他表单都是MDI子表单,并且每个表单都是从ActiveX库创建的。 The parent application creates the ActiveX, after which is calls a method of the ActiveX interface. 父应用程序创建ActiveX,之后调用ActiveX接口的方法。 From this method a form is created and it's FormStyle is set to fsMDIChild. 从这个方法创建一个表单,它的FormStyle设置为fsMDIChild。 At this point the form is an MDI child of the MDI parent. 此时,表单是MDI父级的MDI子级。 This works because both the application and the ActiveX libraries are compiled using runtime packages. 这是有效的,因为应用程序和ActiveX库都是使用运行时包编译的。 As a result, all forms share the same instance of TApplication. 因此,所有表单共享相同的TApplication实例。

The Problem 问题

The application is very large, and needs to be migrated to Delphi 2010 or Delphi XE. 该应用程序非常庞大,需要迁移到Delphi 2010或Delphi XE。 It would be fantastic if the application could be migrated systematically, by first migrating the application, and then migrating the ActiveX libraries one at a time (there are about 50 of them). 如果可以系统地迁移应用程序,首先迁移应用程序,然后一次迁移一个ActiveX库(其中大约有50个),这将是非常棒的。

The problem is that if the console application is compiled in XE, it will no longer be using the same TApplication instance as those libraries still compiled in Delphi 5. 问题是,如果控制台应用程序是在XE中编译的,它将不再使用与仍在Delphi 5中编译的库相同的TApplication实例。

Even if the forms in the ActiveX library cannot be true MDI child windows, it seems like I should be able to return the handle of the form that is created from the ActiveX and grab it from the main form and make the form appear to be an MDI child. 即使ActiveX库中的表单不能是真正的MDI子窗口,似乎我应该能够返回从ActiveX创建的表单的句柄并从主表单中获取它并使表单看起来像是MDI孩子。 I could then create my own layer for handling events. 然后我可以创建自己的图层来处理事件。

Any ideas? 有任何想法吗?


Update: The approach currently being taken with this application is that it is being migrated from MDI to an SDI interface. 更新:此应用程序当前采用的方法是将其从MDI迁移到SDI接口。 It is perfectly possible to instantiate TForms from a Delphi 5 ActiveX DLL from a Delphi XE application, so long as the first form from each DLL can take care of it's own data (loading, saving, displaying additional forms, etc). 完全可以从Delphi XE应用程序中的Delphi 5 ActiveX DLL实例化TForms,只要每个DLL的第一个表单可以处理它自己的数据(加载,保存,显示其他表单等)。 The problem was in keeping the original MDI design. 问题在于保持原始的MDI设计。 If the SDI design proves acceptable, there will be no need for an MDI solution. 如果SDI设计被证明是可接受的,则不需要MDI解决方案。 Still, if someone knows how to accomplish the MDI solution, I'd like to know. 不过,如果有人知道如何完成MDI解决方案,我想知道。

Originally, I said that you cannot create do so. 最初,我说你不能创造这样做。 I researched some more and found out that it's possible to do it. 我研究了一些,发现可以做到这一点。 You have to be very careful though. 你必须非常小心。

Here's some source I created recently to test out the idea: http://cc.embarcadero.com/item/28168 这是我最近创建的一些来源,用于测试这个想法: http//cc.embarcadero.com/item/28168

The code spawns the Windows Calculator and Notepad app, then MDIize the external windows into the MDI Form. 该代码生成Windows计算器和记事本应用程序,然后将外部窗口MDI化为MDI窗体。

Click Launch Notepad after starting the app, and see what happens. 启动应用程序后单击启动记事本,看看会发生什么。

You should be able to modify the work further so that you can achieve what you need. 您应该能够进一步修改工作,以便您可以实现所需。

Note that you need to ensure that your MDI Child in the ActiveX DLL is entirely self-contained. 请注意,您需要确保ActiveX DLL中的MDI Child完全是自包含的。

Even if the forms in the ActiveX library cannot be true MDI child windows, it seems like I should be able to return the handle of the form that is created from the ActiveX and grab it from the main form and make the form appear to be an MDI child. 即使ActiveX库中的表单不能是真正的MDI子窗口,似乎我应该能够返回从ActiveX创建的表单的句柄并从主表单中获取它并使表单看起来像是MDI孩子。 I could then create my own layer for handling events. 然后我可以创建自己的图层来处理事件。

I'd try something like this (inspired by Marjan's comment): 我会尝试这样的事情(灵感来自Marjan的评论):
in the Delphi 5 MDI windows, split the Window in two layers for each of forms: 在Delphi 5 MDI窗口中,为每种形式将Window拆分为两层:

  • a set of frameless TForms/TFrames having the content (maybe expose this as an ActiveX forms) 一组具有内容的无框架TForms / TFrame(可能将其公开为ActiveX表单)
  • for each frameless content, one MDI child that handles the MDI 对于每个无框架内容,一个处理MDI的MDI子项

in the Delphi XE host: 在Delphi XE主机中:

  • obtain the handle for each of the Delphi 5 frameless TForms/TFrames 获取每个Delphi 5无框架TForms / TFrames的句柄
  • embed that handle in an MDI child form 将该句柄嵌入MDI子表单中

It probably means you have to duplicate part of the Delphi 5 MDI handling in Delphi XE. 这可能意味着您必须在Delphi XE中复制部分Delphi 5 MDI处理。

--jeroen --jeroen

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM