|
|
Re: word + SWT + applet problem [message #443318 is a reply to message #443224] |
Wed, 22 September 2004 14:58 |
Veronika Irvine Messages: 1272 Registered: July 2009 |
Senior Member |
|
|
Building on what Tiberiu has said:
In stop, setting the thread to null is not going to cleanly terminate the
embedded word. You need to dispose of the display. You also need to
dispose of the OleAutomation object ("auot") you have created. Doing both
of these things should result in the reference count of the embedded Ole
Word document going to zero. A way to verify this is to look in the Task
Manager for Windows. If you still see WINWORD.EXE in the process tab of
Task Manager, then you have not properly terminated the embedded Ole Word
Document.
However, you have another problem. If you want to be able to stop and
restart your applet multiple times, you will have a problem with ole
initialization. When the Java class loader loads the COM class,
OS.OleInitialize is called on the current thread. From then on, only that
thread can be used to create OleClientSite objects. Therefore, once you
terminate that thread in stop, you can no longer create any more
OleClientSite objects for that application.
Finally, you need to remove the awtParent Canvas from the applet because
othewise it will try to resize a SWT widget that is disposed.
Embedding SWT Ole objects in applets is not really supported. Some work is
still required to acheive this.
I have modified your example to work below. It involved calling an internal
method on OS which is a hack.
public class MyWordApplet extends Applet implements Runnable {
private Display display = null;
private OleClientSite site = null;
private OleAutomation auto = null;
private Shell swtParent = null;
private Canvas awtParent = null;
public void init () {
Thread swtUIThread = new Thread (this);
swtUIThread.start ();
}
public void run() {
setLayout(new GridLayout(1, 1));
awtParent = new Canvas();
add(awtParent);
// Need this line for Restart support
org.eclipse.swt.internal.win32.OS.OleInitialize(0);
display = new Display();
swtParent = SWT_AWT.new_Shell(display, awtParent);
swtParent.setLayout(new FillLayout());
swtParent.setLayout(new FillLayout());
OleFrame frame = new OleFrame(swtParent, SWT.NONE);
try {
site = new OleClientSite(frame, SWT.NONE, "Word.Document");
auto = new OleAutomation(site);
} catch (SWTException e) {
String str = "Create OleClientSite Error" + "\n" + e.toString();
System.out.println(str);
return;
}
site.doVerb(OLE.OLEIVERB_SHOW);
// Size AWT Panel so that it is big enough to hold the SWT widgets
Point size = swtParent.computeSize (SWT.DEFAULT, SWT.DEFAULT);
awtParent.setSize(size.x + 2, size.y + 2);
// Need to invoke the AWT layout manager or AWT and Swing
// widgets will not be visible
validate();
// The SWT widget(s) require an event loop
while (swtParent != null && !swtParent.isDisposed()) {
if (!display.readAndDispatch()) display.sleep ();
}
}
public void stop(){
if (display != null && !display.isDisposed()){
display.syncExec(new Runnable() {
public void run() {
if (swtParent != null && !swtParent.isDisposed()) swtParent.dispose();
auto.dispose();
display.dispose();
site = null;
auto = null;
swtParent = null;
display = null;
}
});
remove(awtParent);
awtParent = null;
}
}
}
"Tiberiu Caprita" <capritat@hotmail.com> wrote in message
news:circac$5jb$1@eclipse.org...
> Hi Hechengrong,
> I can't help you very much, but please consider the followings:
> 1. Opening Word with OLE.OLEIVERB_SHOW you run a ActiveX in your SWT
> Shell.
> 2. Oles are based on COM architecture. Is not enough to kill the thread
> in order everything to go well. When you request a Com object, it comes
> with a IUnknown.AddRef and is the caller problem to Release the Reference
> to that Com (normally that is done by destructor of OleClientSite).
> 3. Maybe is not a good idea to run Word in other thread. To call Com
> objects, the caller thread should have the Com libraries initialized there
> (take a look on COM class in swt there are initialized in main (UI)
> thread, and read about MSDN CoInitializeEx, OleInitialize).
>
> So, practically if you remain to your solution killing the thread, you
> have to save somewhere the Word process id and to try to kill it too.
>
> Otherwise you should find a clean manner to close connection with Word
> (you can even try to call Application.Quit of Word).
>
> Tiberiu
>
>
|
|
|
Powered by
FUDForum. Page generated in 0.03406 seconds