一个Application程序,所要做的工作,是处理数据,然后通过一些特定的界面将处理结果显示出来,所以Application可以分为两个部分:数据处理部分和界面显示处理部分。当应用程序在纯JAVA环境中无法获得其要处理的数据后,那么就涉及到调用本地化资源的问题。
JAVA的awt组件是一个包含对等体接口类的组件类集合;每一个AWT类都存在一个对等体(Peer),java的平台无关反映在awt上是指awt的组件类和它的对等类是平台无关的,但是底层的对等体类(是Peer接口的具体实现类)和JNI代码是平台相关的。例如一个就一个Label组件为例,它由java.awt.Label和java.awt.peer. LabelPeer两个类组成,在不同平台上,AWT提供不同的对等体类来实现LabelPeer,如Windows环境下的对等实体类是sun.awt.windows.WLabelPeer。
本文主要是JAVA窗体类中,实现IE控件的调用。首先给出MyWindow的JAVA类,定义了两个本地化方法:
public native void initialize(String strURL);
public native void initialize(String strURL);
编译后生成class文件;
其次使用javah 生成c++的头文件,然后启动VS2005创建工程,实现这两个本地化方法。
(附代码)
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.peer.*;
import sun.awt.*;
public class MyWindow extends Canvas
{
static
{
// Load the library that contains the JNI code.
System.loadLibrary("MyWindow");
}
String m_strURL = "http://www.javasoft.com";
// native entry point for initializing the IE control.
public native void initialize(String strURL);
// native entry point for resizing
public native void resizeControl(int nWidth, int nHeight);
public void addNotify()
{
super.addNotify();
initialize(m_strURL);
}
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);
TextField field = new TextField();
field.setText (strText);
f.add (field,BorderLayout.NORTH);
f.setBounds(300,300,500,300);
f.setVisible(true);
}
public void setSize( int width, int height )
{
super.setSize(width,height);
resizeControl(width,height);
}
public void setSize( Dimension d )
{
super.setSize(d);
resizeControl( d.width, d.height);
}
public void setBounds( int x, int y, int width, int height )
{
super.setBounds(x,y,width,height);
resizeControl(width,height);
}
public void setBounds( Rectangle r )
{
super.setBounds(r);
resizeControl( r.width, r.height);
}
}
#include
"stdafx.h"
#include
"MyWindow.h"
#include
"ASSERT.H"
#include
"process.h"
#include
"string.h"
#include
"atlbase.h"
#include
"Exdisp.h"
// Structure for Thread Parameters.
typedef
struct
{
char szURL[1024];
HWND hwnd;
} ThreadParam;
void
WINAPIV StartATL(LPVOID lpVoid);
VOID CreateIEControl(ThreadParam *pThreadParam);
JNIEXPORT void JNICALL Java_MyWindow_initialize
(JNIEnv *pEnv, jobject canvas, jstring url)
{
JAWT awt;
JAWT_DrawingSurface* ds;
JAWT_DrawingSurfaceInfo* dsi;
JAWT_Win32DrawingSurfaceInfo* dsi_win;
jboolean result;
jint lock;
// Get the AWT
awt.version = JAWT_VERSION_1_3;
result = JAWT_GetAWT(pEnv, &awt);
assert(result != JNI_FALSE);
// Get the drawing surface
ds = awt.GetDrawingSurface(pEnv, canvas);
assert(ds != NULL);
// Lock the drawing surface
lock = ds->Lock(ds);
assert((lock & JAWT_LOCK_ERROR) == 0);
// Get the drawing surface info
dsi = ds->GetDrawingSurfaceInfo(ds);
// Get the platform-specific drawing info
dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;
const char *str = pEnv->GetStringUTFChars(url, 0);
ThreadParam *pThreadParam = new ThreadParam;
pThreadParam->hwnd = dsi_win->hwnd;
strcpy_s(pThreadParam->szURL,str);
pEnv->ReleaseStringUTFChars(url, str);
// Launch the Thread.
_beginthread(StartATL, 0, pThreadParam);
// Free the drawing surface info
ds->FreeDrawingSurfaceInfo(dsi);
// Unlock the drawing surface
ds->Unlock(ds);
// Free the drawing surface
awt.FreeDrawingSurface(ds);
return;
}
// 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)
{
void* init = GetProcAddress(LoadLibrary(L"atl"),"AtlAxWinInit");
_asm call init;
AtlAxWinInit();
// printf("Create AtlAxWin Begin...[0x%x][%s]/n",pThreadParam->hwnd,pThreadParam->szURL);
DWORD err=GetLastError();
printf("Error ...[0x%x]/n",err);
// In the 2nd Param you can use ProgID or UUID of any activex control.
HWND hwndChild = ::CreateWindow(L"AtlAxWin",
L"Shell.Explorer.1",
WS_CHILD|WS_VISIBLE,
0,0,200,200,
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 *pEnv, jobject canvas, jint width, jint height)
{
JAWT awt;
JAWT_DrawingSurface* ds;
JAWT_DrawingSurfaceInfo* dsi;
JAWT_Win32DrawingSurfaceInfo* dsi_win;
jboolean result;
jint lock;
// Get the AWT
awt.version = JAWT_VERSION_1_3;
result = JAWT_GetAWT(pEnv, &awt);
assert(result != JNI_FALSE);
// Get the drawing surface
ds = awt.GetDrawingSurface(pEnv, canvas);
assert(ds != NULL);
// Lock the drawing surface
lock = ds->Lock(ds);
assert((lock & JAWT_LOCK_ERROR) == 0);
// Get the drawing surface info
dsi = ds->GetDrawingSurfaceInfo(ds);
// Get the platform-specific drawing info
dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;
HWND hwnd = dsi_win->hwnd;
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);
}
// ds->FreeDrawingSurfaceInfo(dsi);
// Unlock the drawing surface
// ds->Unlock(ds);
// Free the drawing surface
//awt.FreeDrawingSurface(ds);
}