Click here to Skip to main content
15,894,017 members
Articles / Desktop Programming / ATL
Article

Embed ActiveX controls inside Java GUI

Rate me:
Please Sign up or sign in to vote.
4.78/5 (18 votes)
8 May 2000 448.6K   859   39   106
With this your Java projects can take advantage of ActiveX controls and Office documents such as spreadsheets, charts, calendars, word processors, specialized graphics, and many more.
  • Download source and binary files - 6.9 Kb
  • Sample Image - javacom.gif

    Introduction

    This article provides a skeleton for embedding ActiveX controls within your Java Applications. The sample project shows how to embed the Internet Explorer 5.0 just like any other Java Widget.

    There are two major problems that needed to be solved to be able to do this.

  • Problem #1 - Get the HWND of a Java Heavy Weight component.
  • Problem #2 - How to attach an activex control as a child of the HWND above.
  • Problem #1 was solved by an undocumented API present in all versions of JDK's from Sun, for example JDK 1.1.8, JDK 1.2.2 and JDK 1.3. Here's the URL which explains how to get the HWND of a java.awt.Canvas object and an extract from the project which shows the implementation.

    http://www.jguru.com/jguru/faq/view.jsp?EID=44507

    // Returns the HWND for panel. This is a hack which works with
    // JDK1.1.8, JDK1.2.2 and JDK1.3. This is undocumented. Also 
    // you should call this only after addNotify has been called.
    public int getHWND() 
    {
        int hwnd = 0;
        DrawingSurfaceInfo drawingSurfaceInfo = ((DrawingSurface)(getPeer())).getDrawingSurfaceInfo();
        if (null != drawingSurfaceInfo) 
        {
            drawingSurfaceInfo.lock();
            Win32DrawingSurface win32DrawingSurface = (Win32DrawingSurface)drawingSurfaceInfo.getSurface();
            hwnd = win32DrawingSurface.getHWnd();
            drawingSurfaceInfo.unlock();
        }
        return hwnd;
    }

    Problem #2 was a bit more complicated but MSDN's Online KB was of great help in solving this. Here's the URL which explains how to add an ActiveX control as a child of any HWND using ATL and an extract from the project which shows how the concept is implemented.

    http://support.microsoft.com/support/kb/articles/Q192/5/60.ASP

    // Creates IE control
    VOID CreateIEControl(ThreadParam *pThreadParam)
    {
        AtlAxWinInit();
        printf("Create AtlAxWin Begin...[0x%x][%s]\n",pThreadParam->hwnd,pThreadParam->szURL);
        // In the 2nd Param you can use ProgID or UUID of any activex control.
        HWND hwndChild = ::CreateWindow("AtlAxWin",
                                        "Shell.Explorer.1", 
                                        WS_CHILD|WS_VISIBLE,
                                        0,0,0,0,
                                        pThreadParam->hwnd,NULL,
                                        ::GetModuleHandle(NULL),
                                        NULL);
    
        IUnknown *pUnk = NULL;
        AtlAxGetControl(hwndChild,&pUnk);
        printf("Create AtlAxWin Done...[0x%x]\n",pUnk);
    
        // get an interface to set the URL.
        CComPtr<IWebBrowser2> spBrowser;
        pUnk->QueryInterface(IID_IWebBrowser2, (void**)&spBrowser);
        if (spBrowser)
        {
            CComVariant ve;
            CComVariant vurl(pThreadParam->szURL);
    #pragma warning(disable: 4310) // cast truncates constant value
            spBrowser->put_Visible(VARIANT_TRUE);
    #pragma warning(default: 4310) // cast truncates constant value
            spBrowser->Navigate2(&vurl, &ve, &ve, &ve, &ve);
        }
    }
    To Build the Project edit and use Build.BAT present in the downloadable Zip file above.

    To run the Java Application, use "java MyWindow http://www.codeproject.com" from the command line.

    That's it! Have Fun.

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here


    Written By
    United States United States
    This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

    Comments and Discussions

     
    GeneralRe: VB Dll from Java Pin
    5-Apr-02 10:03
    suss5-Apr-02 10:03 
    GeneralProblem during program termination Pin
    Gan3-Jul-01 22:36
    Gan3-Jul-01 22:36 
    GeneralRegarding an Error Pin
    Krithivasan M. S24-Jun-01 19:27
    Krithivasan M. S24-Jun-01 19:27 
    Generaljava and SOAP Pin
    16-May-01 5:08
    suss16-May-01 5:08 
    GeneralUsing in an internalframe Pin
    4-Apr-01 6:45
    suss4-Apr-01 6:45 
    GeneralRe: Using in an internalframe Pin
    Soundari11-Oct-01 0:46
    Soundari11-Oct-01 0:46 
    Questionhow to show ohter URL? Pin
    14-Mar-01 19:42
    suss14-Mar-01 19:42 
    AnswerRe: how to show ohter URL? Pin
    3-Feb-02 2:31
    suss3-Feb-02 2:31 
    I modified the source code of MyWindow.java and MyWindow.CPP of Davanum Srinivas to support the method

    // native entry point for showing a URL
    public native void showURL(String strURL);

    The new files are:

    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    import java.awt.*;
    import java.awt.peer.*;
    import sun.awt.*;

    public class MyWindow extends Canvas
    {
    static
    {
    // Load the library that contains the JNI code.
    System.loadLibrary("MyWindow");
    }

    // native entry point for initializing the IE control.
    public native void initialize(int hwnd, String strURL);

    // native entry point for showing a URL
    public native void showURL(String strURL);

    // native entry point for resizing
    public native void resizeControl(int hwnd, int nWidth, int nHeight);

    // Returns the HWND for panel. This is a hack which works with
    // JDK1.1.8, JDK1.2.2 and JDK1.3. This is undocumented. Also
    // you should call this only after addNotify has been called.
    public int getHWND()
    {
    int hwnd = 0;
    DrawingSurfaceInfo drawingSurfaceInfo = ((DrawingSurface)(getPeer())).getDrawingSurfaceInfo();
    if (null != drawingSurfaceInfo)
    {
    drawingSurfaceInfo.lock();
    Win32DrawingSurface win32DrawingSurface = (Win32DrawingSurface)drawingSurfaceInfo.getSurface();
    hwnd = win32DrawingSurface.getHWnd();
    drawingSurfaceInfo.unlock();
    }
    return hwnd;
    }

    public void addNotify()
    {
    super.addNotify();
    m_hWnd = getHWND();
    initialize(m_hWnd, m_strURL);
    }

    String m_strURL = "http://www.javasoft.com";
    int m_hWnd = 0;

    public static void main( String[] argv )
    {
    Frame f = new Frame();
    f.setLayout(new BorderLayout());
    f.setTitle("Internet Explorer inside Java Canvas");

    MyWindow w = new MyWindow();
    if(argv.length>0)
    w.m_strURL = argv[0];

    String strText = "URL:" + w.m_strURL;
    f.add(w,BorderLayout.CENTER);
    f.add(new Label(strText),BorderLayout.NORTH);
    f.setBounds(300,300,500,300);
    f.setVisible(true);
    }

    public void setSize( int width, int height )
    {
    super.setSize(width,height);
    if(m_hWnd!=0)
    resizeControl(m_hWnd, width, height);
    }

    public void setSize( Dimension d )
    {
    super.setSize(d);
    if(m_hWnd!=0)
    resizeControl(m_hWnd, d.width, d.height);
    }

    public void setBounds( int x, int y, int width, int height )
    {
    super.setBounds(x,y,width,height);
    if(m_hWnd!=0)
    resizeControl(m_hWnd, width, height);
    }

    public void setBounds( Rectangle r )
    {
    super.setBounds(r);
    if(m_hWnd!=0)
    resizeControl(m_hWnd, r.width, r.height);
    }
    }

    #include <windows.h>
    #include <assert.h>
    #include <process.h>
    #include "MyWindow.h"

    // Includes for ATL
    #pragma comment(lib,"atl.lib")
    #include <atldef.h>
    #define _ATL_DLL_IMPL
    #include <atliface.h>
    #include <atlbase.h>
    #include <exdisp.h>



    // Structure for Thread Parameters.
    typedef struct {
    char szURL[1024];
    HWND hwnd;
    } ThreadParam;

    HWND hwndChild;

    // Helper functions.
    VOID CreateIEControl(ThreadParam *);
    static void WINAPIV StartATL(LPVOID);

    // native method for initializing the control.
    JNIEXPORT void JNICALL Java_MyWindow_initialize
    (JNIEnv *pEnv, jobject, jint hwndIn, jstring string)
    {
    // Fill up the params.
    const char *str = pEnv->GetStringUTFChars(string, 0);
    ThreadParam *pThreadParam = new ThreadParam;
    pThreadParam->hwnd = (HWND) hwndIn;
    strcpy(pThreadParam->szURL,str);
    pEnv->ReleaseStringUTFChars(string, str);

    // Launch the Thread.
    _beginthread(StartATL, 0, pThreadParam);
    }

    JNIEXPORT void JNICALL Java_MyWindow_showURL
    (JNIEnv *pEnv, jobject, jstring string)
    {
    const char *str = pEnv->GetStringUTFChars(string, 0);

    IUnknown *pUnk = NULL;
    AtlAxGetControl(hwndChild,&pUnk);
    printf("Create AtlAxWin Done...[0x%x]\n",pUnk);

    // get an interface to set the URL.
    CComPtr<iwebbrowser2> spBrowser;
    pUnk->QueryInterface(IID_IWebBrowser2, (void**)&spBrowser);
    if (spBrowser)
    {
    CComVariant ve;
    CComVariant vurl(str);
    #pragma warning(disable: 4310) // cast truncates constant value
    spBrowser->put_Visible(VARIANT_TRUE);
    #pragma warning(default: 4310) // cast truncates constant value
    spBrowser->Navigate2(&vurl, &ve, &ve, &ve, &ve);
    }
    pEnv->ReleaseStringUTFChars(string, str);
    }

    // Thread for creating the control
    void WINAPIV StartATL(LPVOID lpVoid)
    {
    ThreadParam *pThreadParam = (ThreadParam *)lpVoid;
    CreateIEControl(pThreadParam);
    delete pThreadParam;
    MSG msg;
    // Windows message loop.
    while(GetMessage(&msg, NULL, NULL, NULL))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    }

    // Creates IE control
    VOID CreateIEControl(ThreadParam *pThreadParam)
    {
    AtlAxWinInit();
    printf("Create AtlAxWin Begin...[0x%x][%s]\n",pThreadParam->hwnd,pThreadParam->szURL);
    // In the 2nd Param you can use ProgID or UUID of any activex control.
    hwndChild = ::CreateWindow("AtlAxWin",
    "Shell.Explorer.1",
    WS_CHILD|WS_VISIBLE,
    0,0,0,0,
    pThreadParam->hwnd,NULL,
    ::GetModuleHandle(NULL),
    NULL);

    IUnknown *pUnk = NULL;
    AtlAxGetControl(hwndChild,&pUnk);
    printf("Create AtlAxWin Done...[0x%x]\n",pUnk);

    // get an interface to set the URL.
    CComPtr<iwebbrowser2> spBrowser;
    pUnk->QueryInterface(IID_IWebBrowser2, (void**)&spBrowser);
    if (spBrowser)
    {
    CComVariant ve;
    CComVariant vurl(pThreadParam->szURL);
    #pragma warning(disable: 4310) // cast truncates constant value
    spBrowser->put_Visible(VARIANT_TRUE);
    #pragma warning(default: 4310) // cast truncates constant value
    spBrowser->Navigate2(&vurl, &ve, &ve, &ve, &ve);
    }
    }


    // native method for handling resizes.
    JNIEXPORT void JNICALL Java_MyWindow_resizeControl
    (JNIEnv *, jobject, jint hwndIn, jint width, jint height)
    {
    HWND hwnd = (HWND) hwndIn;
    RECT rc;
    if(hwnd!=NULL)
    {
    ::GetWindowRect(hwnd,&rc);
    HWND hwndChild = GetWindow(hwnd, GW_CHILD);
    printf("got resize (0x%x,%d,%d)\n",hwndChild,width,height);
    ::SetWindowPos(hwndChild,NULL,0,0,rc.right-rc.left,rc.bottom-rc.top,SWP_NOZORDER|SWP_NOACTIVATE|SWP_SHOWWINDOW|SWP_NOMOVE);
    }
    }
    GeneralJAVA Pin
    7-Mar-01 17:47
    suss7-Mar-01 17:47 
    GeneralRe: JAVA Pin
    29-May-02 3:44
    suss29-May-02 3:44 
    QuestionHow can i exit this program?? Pin
    19-Dec-00 17:05
    suss19-Dec-00 17:05 
    AnswerRe: How can i exit this program?? Pin
    16-Feb-01 3:55
    suss16-Feb-01 3:55 
    GeneralDeprecation Problems Pin
    Bill21-Sep-00 23:59
    Bill21-Sep-00 23:59 
    GeneralRe: Deprecation Problems Pin
    Davanum Srinivas22-Sep-00 2:06
    Davanum Srinivas22-Sep-00 2:06 
    GeneralRe: Deprecation Problems Pin
    Alex Rose5-Jun-01 8:53
    Alex Rose5-Jun-01 8:53 
    GeneralNice Pin
    blueopera15-Aug-00 11:35
    blueopera15-Aug-00 11:35 
    GeneralAccessing the control's data?! Pin
    Noam Krendel24-Jul-00 4:31
    sussNoam Krendel24-Jul-00 4:31 
    QuestionHow about activeX events? Pin
    enrico15-Jul-00 7:20
    enrico15-Jul-00 7:20 
    AnswerRe: How about activeX events? Pin
    Wolf3-Mar-01 21:15
    Wolf3-Mar-01 21:15 
    GeneralRe: How about activeX events? Pin
    16-May-01 0:34
    suss16-May-01 0:34 
    GeneralRe: How about activeX events? Pin
    sjava28-Feb-03 16:10
    sjava28-Feb-03 16:10 
    GeneralWOW!!! That is very very fantastic! Pin
    Christopher25-May-00 15:30
    Christopher25-May-00 15:30 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.