|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV |
TOP THREE LINKS YOU MUST CLICK ON General Java Hosting ActiveX/.NET Controls in a Java Application...the Direct Way
"Care For Some .NET With Your Java...?"
By: Stanley Wang
Feb. 9, 2005 12:00 AM
This article describes how to host an ActiveX/.NET control in a Java application that is targeted for the Microsoft Windows Platform. I'll assume you know the fundamentals of Java, C++, JNI (Java Native Interface), Win32, COM (Component Object Model), and ATL (Active Template Library). Because a .NET control can be exposed as a COM component by using the COM interoperability services provided by the .NET Framework, I'll start by hosting the ActiveX control. I'll be using the control, the ActiveX control, and the COM component interchangeably.
The ActiveX Control and Its Container Review
Creating the ActiveX Control and Its Container in C++ CJavaCOMBridge is a class derived from an ATL CWindowImpl class template, which provides its derived classes with Windowing functionality. CJavaCOMBridge is defined in Listing 2. All the dirty work of creating the container and control is done by axwnd_, whose type is CAxWindow, which is one of the greatest classes from ATL.
ActiveX Control Java Wrapper, Hooking an ActiveX Control to an AWT Native Interface However, in Listing 1 there is a HWND typed parameter parentWnd, which is the parent window of the control container. Where does this native window handle come from? Remember that for any AWT/Swing heavyweight component, there is a native peer associated with it. So the aforementioned native window handle could be an AWT/Swing heavyweight component's native window and it is. How to obtain it? Until Java 1.5 the only documented way to get a native window handle was through the java.awt.Canvas class (please refer to jawt.h file, which is under the %jdkhome%\include directory). Listing 3 shows the relevant code. This means that the JAxControl has to be a derived class of java.awt.Canvas and Listing 1 will be modified as shown in Listing 4. Though the native handle can be obtained anytime after the Canvas is realized, a reasonable place is the addNotify method in which the native peer will be created. Then the JAxControl could be something like Listing 5. Unfortunately Listing 5 won't work. The addNotify method is executed in the Main-Method thread while the Canvas native window is created in the Toolkit thread in which the native Windows message loop is served. (See below for more discussion about Sun Hotspot JVM threads.) This means the control created this way is useless because it can't process Windows messages. (For more information about Windows programming, please see Win32 Programming.) To fix this problem, the control could be created in its own native thread. Listing 6 shows one way to do it. (Listings 6-13 can be downloaded from www.sys-con.com/java/sourcec.cfm.) Please notice that the native thread should be attached to the existing JVM to enable it to work with the JVM's synchronization scheme. This approach solves the messaging problem, however, it has several drawbacks. First, it increases the interthread communication. Second, it violates the basic Win32 GUI programming rule because the control is created in a different thread from its parent. This could easily cause deadlock. A better approach is subclassing an AWT Canvas native window class. A native window class is just a WNDCLASSEX structure containing all the information to describe a window. The most important member of WNDCLASSEX is the window procedure function (often called WndProc) pointer. A window procedure function is used to handle Windows messages. Remember that most of the Win32 APIs are written in C, which is not an object-oriented language. There is no Win32 API to let you derive a window class from an existing one. However, it does use object modeling to some extent. It provides some sort of polymorphic behavior for a window class by replacing its window procedure function pointer with the subclass's function pointer. If the subclass function doesn't handle a Windows message, it will pass the message to the super-class function. This is the so-called subclassing. To subclass an AWT Canvas window class (it's named as SunAwtCanvas, however, the class name is not important here), a native subclassNativePeer method is added to the JAxControl class. Listing 7 shows the magic. Note how a user-defined Windows message is used to create the control in the Toolkit thread. (For more information about how to define a user-defined Windows message, please see "Message Management.") Subclassing the AWT Canvas native window class opens the back door to a mixed usage of the native window and a Java AWT/Swing component. It is efficient and powerful. The only downside is that it's relying on the AWT implementation detail.
Garbage Collection and Resource Management The solution is to provide an explicit termination method. Here, I'm applying the Dispose pattern that the .NET Framework has promoted, i.e., all the classes that intend to manage resources specially should implement the IDisposable interface, which has a dispose method. The dispose method will clean all the native resources, such as close a database connection and terminate child threads. Actually this pattern is applied internally by Sun; java.awt.Window, java.awt.Graphics, and some other classes all have a dispose method. Unfortunately this pattern is not abstracted to a higher level. In addition to applying the Dispose pattern, it's necessary to override the removeNotify method. removeNotify is called by the toolkit internally to destroy the native peer. The ActiveX control and other native resources need to be reclaimed before the native peer is destroyed. To summarize, the Java ActiveX control wrapper should look similar to Listing 8. The ComponentListener is used to adjust the control's size accordingly. YOUR FEEDBACK
LATEST JAVA STORIES & POSTS
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK SPONSORED BY INFRAGISTICS
BREAKING JAVA NEWS |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||