Skip to content

Commit

Permalink
Improved COM support in com.sun.jna.platform.win32.COM.util.
Browse files Browse the repository at this point in the history
Use of interfaces and annotations to provide easier implementation of COM
interfaces (uses InvocationHandler).
Support for COM event callbacks.
Support for COM interface discovery by iteration over the
RunningObjectTable.
  • Loading branch information
dhakehurst authored and dblock committed Mar 16, 2015
1 parent de3a9ea commit d6675fa
Show file tree
Hide file tree
Showing 84 changed files with 5,579 additions and 36 deletions.
12 changes: 8 additions & 4 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
NOTE: as of JNA 4.0, JNA is now dual-licensed under LGPL and ASL (see LICENSE).
NOTE: as of JNA 4.0, JNA is now dual-licensed under LGPL and ASL (see LICENSE).

NOTE: JNI native support is typically incompatible between minor versions, and almost always incompatible between major versions.

Release 4.2
===========
Release 4.2 (Next)
==================

Features
--------

* [#387](https://github.com/twall/jna/pull/397): Use of interfaces and annotations to provide easier implementation of COM interfaces (with `InvocationHandler`) - [@dhakehurst](https://github.com/dhakehurst).
* [#387](https://github.com/twall/jna/pull/397): Support for COM event callbacks - [@dhakehurst](https://github.com/dhakehurst).
* [#387](https://github.com/twall/jna/pull/397): Support for COM interface discovery by iteration over `RunningObjectTable` - [@dhakehurst](https://github.com/dhakehurst).
* Updated AIX natives and build - [@twall](https://github.com/twall).
* [#290](https://github.com/twall/jna/pull/290): Improved the stacktrace for the exceptions thrown by `com.sun.jna.Structure` - [@ebourg](https://github.com/ebourg).
* [#332](https://github.com/twall/jna/pull/332): Added Win32 Monitor Configuration API in `com.sun.jna.platform.win32.Dxva2` - [@msteiger](https://github.com/msteiger).
Expand Down Expand Up @@ -40,7 +44,7 @@ Bug Fixes
* [#382](https://github.com/twall/jna/pull/382): Fixed memory allocation in `com.sun.jna.platform.win32.WTypes.LPWSTR` and `LPSTR` constructors - [@junak-michal](https://github.com/junak-michal).
* Fix publish doc links - [@bhamail](https://github.com/bhamail).
* [#388](https://github.com/twall/jna/issues/388): Ensure native library always opened with provided flags - [@zolyfarkas](https://github.com/zolyfarkas).
* [#403](https://github.com/twall/jna/pull/403): Make com.sun.jna.platform.win32.COM.COMUtils.SUCCEEDED and FAILED conform to MSDN specification for said macros - [@lwahonen](https://github.com/lwahonen).
* [#403](https://github.com/twall/jna/pull/403): Fix `com.sun.jna.platform.win32.COM.COMUtils.SUCCEEDED` and `FAILED` - [@lwahonen](https://github.com/lwahonen).

Release 4.1
===========
Expand Down
4 changes: 2 additions & 2 deletions contrib/msoffice/.classpath
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry combineaccessrules="false" kind="src" path="/jnalib"/>
<classpathentry kind="var" path="JNA_LIB"/>
<classpathentry combineaccessrules="false" kind="src" path="/com.sun.jna"/>
<classpathentry combineaccessrules="false" kind="src" path="/com.sun.jna.platform"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Binary file modified contrib/msoffice/jnatest.xls
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ public static void main(String[] args) {
+ File.separator;

public MSOfficeDemo() {
this.testMSWord();
// this.testMSExcel();
//this.testMSWord();
this.testMSExcel();
}

public void testMSWord() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package com.sun.jna.platform.win32.COM.util.office;

import java.io.File;

import com.sun.jna.platform.win32.COM.office.MSExcel;
import com.sun.jna.platform.win32.COM.util.AbstractComEventCallbackListener;
import com.sun.jna.platform.win32.COM.util.Factory;
import com.sun.jna.platform.win32.COM.util.office.excel.ComExcel_Application;
import com.sun.jna.platform.win32.COM.util.office.excel.ComIAppEvents;
import com.sun.jna.platform.win32.COM.util.office.excel.ComIApplication;
import com.sun.jna.platform.win32.COM.util.office.excel.ComIRange;
import com.sun.jna.platform.win32.COM.util.office.excel.ComIWorksheet;
import com.sun.jna.platform.win32.COM.util.office.word.ComWord_Application;

public class MSOfficeExcelDemo {

/**
* @param args
*/
public static void main(String[] args) {
new MSOfficeExcelDemo();
}

private String currentWorkingDir = new File("").getAbsolutePath() + File.separator;

public MSOfficeExcelDemo() {
this.testMSExcel();
}

public void testMSExcel() {
ComExcel_Application excelObject = null;
ComIApplication msExcel = null;
Factory factory = null;
try {
factory = new Factory();
excelObject = factory.createObject(ComExcel_Application.class);
msExcel = excelObject.queryInterface(ComIApplication.class);
System.out.println("MSExcel version: " + msExcel.getVersion());
msExcel.setVisible(true);
// msExcel.newExcelBook();
msExcel.getWorkbooks().Open(currentWorkingDir + "jnatest.xls");
msExcel.getActiveSheet().getRange("A1").setValue("Hello from JNA!");
// wait 1sec. before closing
Thread.currentThread().sleep(1000);
// // close and save the active sheet
// msExcel.getActiveWorkbook().Close(true);
// msExcel.setVisible(true);
// // msExcel.newExcelBook();
// msExcel.getWorkbooks().Open(currentWorkingDir + "jnatest.xls");
// msExcel.getActiveSheet().getRange("A2").setValue("Hello again from JNA!");

class Listener extends AbstractComEventCallbackListener implements ComIAppEvents {
boolean SheetSelectionChange_called;

@Override
public void errorReceivingCallbackEvent(String message, Exception exception) {
}

@Override
public void SheetSelectionChange(ComIWorksheet sheet, ComIRange target) {
SheetSelectionChange_called = true;
}

};
Listener listener = new Listener();
msExcel.advise(ComIAppEvents.class, listener);
//
// msExcel.getActiveSheet().getRange("A5").Activate();
//
// Thread.currentThread().sleep(500);

// close and save the active sheet
msExcel.getActiveWorkbook().Close(true);

msExcel.Quit();
msExcel = null;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != msExcel) {
msExcel.Quit();
}
if (null != factory) {
factory.disposeAll();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package com.sun.jna.platform.win32.COM.util.office;

import java.io.File;

import com.sun.jna.platform.win32.COM.COMException;
import com.sun.jna.platform.win32.COM.util.Factory;
import com.sun.jna.platform.win32.COM.util.office.word.ComIApplication;
import com.sun.jna.platform.win32.COM.util.office.word.ComWord_Application;
import com.sun.jna.platform.win32.COM.util.office.word.WdOriginalFormat;
import com.sun.jna.platform.win32.COM.util.office.word.WdSaveFormat;

public class MSOfficeWordDemo {

/**
* @param args
*/
public static void main(String[] args) {
new MSOfficeWordDemo();
}

private String currentWorkingDir = new File("").getAbsolutePath() + File.separator;

public MSOfficeWordDemo() {
this.testMSWord();
}

public void testMSWord() {
ComWord_Application msWordObject = null;
ComIApplication msWord = null;
Factory factory = null;
try {
String tempDir = System.getProperty("java.io.tmpdir");
System.out.println("Files in temp dir: "+tempDir);

factory = new Factory();
msWordObject = factory.createObject(ComWord_Application.class);
msWord = msWordObject.queryInterface(ComIApplication.class);

System.out.println("MSWord version: " + msWord.getVersion());

msWord.setVisible(true);
// msWord.newDocument();
msWord.getDocuments().Open(currentWorkingDir + "jnatest.doc");
msWord.getSelection().TypeText("Hello from JNA! \n\n");
// wait 10sec. before closing
Thread.sleep(1000);
// save in different formats
// pdf format is only supported in MSWord 2007 and above
msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestSaveAs.doc", WdSaveFormat.wdFormatDocument);
msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestSaveAs.pdf", WdSaveFormat.wdFormatPDF);
msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestSaveAs.rtf", WdSaveFormat.wdFormatRTF);
msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestSaveAs.html", WdSaveFormat.wdFormatHTML);
// close and save the document
msWord.getActiveDocument().Close(false);
msWord.getDocuments().Add();
// msWord.openDocument(currentWorkingDir + "jnatest.doc", true);
msWord.getSelection()
.TypeText(
"Hello from JNA! \n Please notice that JNA can control MS Word via the new COM interface! \nHere we are creating a new word document and we save it to the 'TEMP' directory!");
// save with no user prompt
msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestNewDoc1.docx", WdSaveFormat.wdFormatDocumentDefault);
msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestNewDoc2.docx", WdSaveFormat.wdFormatDocumentDefault);
msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestNewDoc3.docx", WdSaveFormat.wdFormatDocumentDefault);
// close and save the document
msWord.getActiveDocument().Close(false);
// open 3 documents
msWord.getDocuments().Open(tempDir+"\\jnatestNewDoc1.docx");
msWord.getSelection().TypeText("Hello some changes from JNA!\n");
msWord.getDocuments().Open(tempDir+"\\jnatestNewDoc2.docx");
msWord.getSelection().TypeText("Hello some changes from JNA!\n");
msWord.getDocuments().Open(tempDir+"\\jnatestNewDoc3.docx");
msWord.getSelection().TypeText("Hello some changes from JNA!\n");
// save the document and prompt the user
msWord.getDocuments().Save(false, WdOriginalFormat.wdPromptUser);
// wait then close word
msWord.Quit();
msWord = null;
} catch (InterruptedException ie) {
ie.printStackTrace();
} catch (COMException e) {
if (e.getExcepInfo() != null) {
System.out.println("bstrSource: " + e.getExcepInfo().bstrSource);
System.out.println("bstrDescription: " + e.getExcepInfo().bstrDescription);
}

// print stack trace
e.printStackTrace();
} finally {
if (msWord != null) {
msWord.Quit();
}
if (null != factory) {
factory.getComThread().terminate(500);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.sun.jna.platform.win32.COM.util.office.excel;

import com.sun.jna.platform.win32.COM.util.IUnknown;
import com.sun.jna.platform.win32.COM.util.annotation.ComMethod;
import com.sun.jna.platform.win32.COM.util.annotation.ComObject;

@ComObject(progId="Excel.Application")
public interface ComExcel_Application extends IUnknown {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.sun.jna.platform.win32.COM.util.office.excel;

import com.sun.jna.platform.win32.COM.util.annotation.ComEventCallback;
import com.sun.jna.platform.win32.COM.util.annotation.ComInterface;

@ComInterface(iid="{00024413-0000-0000-C000-000000000046}")
public interface ComIAppEvents {

@ComEventCallback(dispid=1558)
public void SheetSelectionChange(ComIWorksheet sheet, ComIRange target);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.sun.jna.platform.win32.COM.util.office.excel;

import com.sun.jna.platform.win32.COM.util.IConnectionPoint;
import com.sun.jna.platform.win32.COM.util.IUnknown;
import com.sun.jna.platform.win32.COM.util.annotation.ComInterface;
import com.sun.jna.platform.win32.COM.util.annotation.ComMethod;
import com.sun.jna.platform.win32.COM.util.annotation.ComProperty;

@ComInterface(iid="{000208D5-0000-0000-C000-000000000046}")
public interface ComIApplication extends IUnknown, IConnectionPoint {

@ComProperty
String getVersion();

@ComProperty
boolean getVisible();

@ComProperty
void setVisible(boolean value);

@ComProperty
ComIWorkbooks getWorkbooks();

@ComProperty
ComIWorksheet getActiveSheet();

@ComProperty
ComIWorkbook getActiveWorkbook();

@ComMethod
void Quit();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.sun.jna.platform.win32.COM.util.office.excel;

import com.sun.jna.platform.win32.COM.util.annotation.ComInterface;
import com.sun.jna.platform.win32.COM.util.annotation.ComMethod;
import com.sun.jna.platform.win32.COM.util.annotation.ComProperty;

@ComInterface(iid = "{00020846-0000-0000-C000-000000000046}")
public interface ComIRange {

@ComProperty
ComIApplication getApplication();

@ComProperty
String getText();

@ComMethod
void Select();

@ComProperty
void setValue(String value);

@ComMethod
void Activate();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.sun.jna.platform.win32.COM.util.office.excel;

import com.sun.jna.platform.win32.COM.util.annotation.ComInterface;
import com.sun.jna.platform.win32.COM.util.annotation.ComMethod;

@ComInterface(iid="{0002096B-0000-0000-C000-000000000046}")
public interface ComIWorkbook {

@ComMethod
void Close(boolean saveChanges);


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.sun.jna.platform.win32.COM.util.office.excel;

import com.sun.jna.platform.win32.COM.util.annotation.ComInterface;
import com.sun.jna.platform.win32.COM.util.annotation.ComMethod;
import com.sun.jna.platform.win32.COM.util.annotation.ComProperty;

@ComInterface(iid = "{000208DB-0000-0000-C000-000000000046}")
public interface ComIWorkbooks {

@ComProperty
long getCount();

@ComMethod
ComIWorkbook Item(long index);

@ComMethod
ComIWorkbook Open(Object FileName);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.sun.jna.platform.win32.COM.util.office.excel;

import com.sun.jna.platform.win32.COM.util.annotation.ComInterface;
import com.sun.jna.platform.win32.COM.util.annotation.ComMethod;
import com.sun.jna.platform.win32.COM.util.annotation.ComProperty;

@ComInterface(iid="{000208D8-0000-0000-C000-000000000046}")
public interface ComIWorksheet {

@ComProperty
String getName();

@ComProperty
ComIRange getRange(String cell1);

@ComProperty
ComIApplication getApplication();

}
Loading

0 comments on commit d6675fa

Please sign in to comment.