在MFC对话框中嵌入JavaBeans的实践

在探索如何将JavaBeans嵌入MFC对话框的过程中,发现现有的资料并没有提供一个完整的、可工作的示例。因此,决定自己编写一个JavaBridge,以下是努力的成果。

首先,请原谅英语写作或文章结构上可能存在的错误,因为这是在CodeProject上发表的第一篇文章。

使用代码

在运行示例项目之前,请确保已经正确安装了Java软件开发工具包(SDK)版本1.4.2或更高版本。可以从获取SDK。

同时,请确保系统环境变量JAVA_HOME设置为适当的目录。

使用Java Native InterfaceJNI)来加载Java虚拟机并实例化JavaBean。为了更好地理解,将类分为两组。第一组包括处理JNI问题的类,可以在JBridge子文件夹中找到它们。不要过多关注这些类,因为本文不打算介绍JNI。可以在网络(参见下面的)上找到相关论文。

另一组类处理MFC问题。特别是CEmbeddedJFrame将是关注的重点。

当启动应用程序时,将创建一个CEmbeddedJFrame实例,并在CGUIBeanDlg::OnInitDialog()中调用其init()成员函数。

想法是创建一个JavaBean,将其嵌入到JFrame实例中,并将这个框架对象作为对话框的子窗口。下面的代码片段显示了这是如何实现的。

在第9行加载Java虚拟机和bean。如所见,bean由一个名为bean.jar的Java归档文件提供。可以在项目的工作目录的bean子目录中找到这个文件。实例化bean后,创建了JFrame对象。因为不想让为JNI细节烦恼,将相应的JNI调用包装在JBridge子文件夹中的JFrame类中。在框架首次显示之前,将bean实例添加到该框架的内容窗格中(见第23行)。

要将框架作为对话框的子窗口,关键是获取其HWND。有两种方法(让更好地说:知道的两种方法)可以从本地应用程序获取Java对象的HWND。第一种方法是使用JNI获取指向JAWT接口的指针。这个接口提供了一些函数,用于获取像JFrame这样的图形对象的绘图表面。可以从这个绘图表面识别HWND。但是当实现这个时,它是一个非常不稳定且容易出错的解决方案。所以决定用一种不太优雅的方式,通过搜索框架的适当标题来实现。这是在操作Attach_JavaFrame()中完成的。

最后,通过设置WS_CHILDWINDOW样式和正确的父窗口,将这个Java框架作为对话框的子窗口。请仔细查看dockundock()成员函数。

已知问题(欢迎帮助;)

在这个示例中,JavaBean直接嵌入到对话框中,一切都很好。但是如果将CEmbeddedJFrame放入CTabCtrl中,那么AWT每秒会向该容器发送数百个WM_NCHITTESTWM_GETDLGCODE消息!由于这个消息泛滥,CPU使用率上升到100%,整个系统挂起。

第一个假设是这种效果与容器有关,在这种情况下是CTabCtrl。决定在任何时候都将CEmbeddedJFrame嵌入到CDialog中,使用CDialog作为中间层。但是当强制CDialog成为CTabCtrl的子窗口时,最终导致系统死锁。

如果想看到这种效果,请尝试将CEmbeddedJFrame嵌入到CTabCtrl中。可以在MSVC资源编辑器中轻松做到这一点。但要小心。当使用Spy++并在调试会话中启动应用程序时,系统可能会在InitApplication()的开始时挂起。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485