I wanted to drop an outlook email to my RCP application and as always I asked google to help me. You don't find much on this, an older post was
http://www.eclipse.org/forums/index.php?t=msg&&th=147516&goto=464661
That got me startet. The damn it didn't work, I asked on the forum again and the answer made confusion even greater:
http://www.eclipse.org/forums/index.php?t=rview&goto=519397#msg_519397
gladly my wife gladly does some more windows thingy's with c# and with her help and a c# example i found out that i have to make an os call to get the type of the transfer that may change with every boot.
but i still did not know what the heck to do with these objects. I started to search again and finally found an example in the eclipse OleClient:
now with that I can read Streams from the IStorage. What streams there are is in the STATSTG's
http://www.fileformat.info/format/outlookmsg/
I can now extract the contents of the message and push it to jackrabbit ;) The code in these examples is for x86_64, you may need some ints for the adresses on 32bit windows.
http://www.eclipse.org/forums/index.php?t=msg&&th=147516&goto=464661
That got me startet. The damn it didn't work, I asked on the forum again and the answer made confusion even greater:
http://www.eclipse.org/forums/index.php?t=rview&goto=519397#msg_519397
gladly my wife gladly does some more windows thingy's with c# and with her help and a c# example i found out that i have to make an os call to get the type of the transfer that may change with every boot.
Then at least the stuff from the first post started to do something, i could get an IStorage and enumerate over the STATSTG'spublic static int registerType() {// Look name up in the registry// If name is not in registry, add it and return assigned value.// If name already exists in registry, return its assigned valueTCHAR chFormatName = new TCHAR(0, "FileContents", true);return OS.RegisterClipboardFormat(chFormatName);}
public Object nativeToJava(TransferData transferData) {
IDataObject idata = new IDataObject(transferData.pIDataObject);idata.AddRef();FORMATETC formatetc = new FORMATETC();
STGMEDIUM stgmedium = new STGMEDIUM();formatetc.cfFormat = type;formatetc.lindex = 0;formatetc.ptd = 0;formatetc.tymed = 4 | 8 | 1;formatetc.dwAspect = COM.DVASPECT_CONTENT;transferData.result = getData(idata, formatetc, stgmedium);idata.Release();if (transferData.result != COM.S_OK) {System.out.println("Fehler" + transferData.result);return null;}
if ((stgmedium.tymed & 8) == 8) {// IStorageIStorage storage = new IStorage(stgmedium.unionField);storage.AddRef();long[] x = new long[1];long ret = storage.EnumElements(0, 0, 0, x);
IEnumSTATSTG enumSTATSTG = new IEnumSTATSTG(x[0]);enumSTATSTG.AddRef();STATSTG[] data = new STATSTG[0];// Loop over enumeratorlong rgelt = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, STATSTG.sizeof);int[] pceltFetched = new int[1];enumSTATSTG.Reset();while (enumSTATSTG.Next(1, rgelt, pceltFetched) == COM.S_OK && pceltFetched[0] == 1) {STATSTG statstg = new STATSTG();COM.MoveMemory(statstg, rgelt, STATSTG.sizeof);STATSTG[] newData = new STATSTG[data.length + 1];System.arraycopy(data, 0, newData, 0, data.length);newData[data.length] = statstg;data = newData;}OS.GlobalFree(rgelt);
enumSTATSTG.Release();
// do something with STATSTG[]
but i still did not know what the heck to do with these objects. I started to search again and finally found an example in the eclipse OleClient:
private byte[] readStream(IStorage storage, String stream) {boolean success = false;
long[] address = new long[1];// Look for a CONTENTS streamif (storage.OpenStream(stream, 0, COM.STGM_DIRECT | COM.STGM_READ | COM.STGM_SHARE_EXCLUSIVE, 0, address) == COM.S_OK) {IStream tempContents = new IStream(address[0]);tempContents.AddRef();
try {ByteArrayOutputStream w = new ByteArrayOutputStream();
int increment = 1024 * 4;long pv = COM.CoTaskMemAlloc(increment);int[] pcbWritten = new int[1];while (tempContents.Read(pv, increment, pcbWritten) == COM.S_OK && pcbWritten[0] > 0) {byte[] buffer = new byte[pcbWritten[0]];OS.MoveMemory(buffer, pv, pcbWritten[0]);w.write(buffer);success = true;}COM.CoTaskMemFree(pv);
w.close();return w.toByteArray();} catch (IOException err) {} finally {
tempContents.Release();}
}return null;}
now with that I can read Streams from the IStorage. What streams there are is in the STATSTG's
There we are. The IStorage contains the data in the .msg Format that I return in some strange way via the Map. I don't know how to get the .msg in one piece, but at least with some informations from// do something with STATSTG[]Map result = new HashMap();for (STATSTG s : data) {String stream = getString(s.pwcsName);result.put(stream, readStream(storage, stream));}
storage.Release();return result;
http://www.fileformat.info/format/outlookmsg/
I can now extract the contents of the message and push it to jackrabbit ;) The code in these examples is for x86_64, you may need some ints for the adresses on 32bit windows.