Tobias Willig
Tobias Willig

Reputation: 1144

Drag Emails From Outlook to Java (with JNA)

I'm trying to transfer Emails from Outlook to an Eclipse RCP application via drag and drop. Using this Code Snippet I found out that the following native types are transfered during the drag and drop operation from Outlook 2010 to Java:

enter image description here

I need the full message body, therefore the provided text during the drag and drop operation is not enough. I have tried to extend ByteArrayTransfer in order to convert the native objects into Java objects, which provides access to the email. Structures like FileGroupDescriptor are native C structs. I tried to read them out using JNA, but JNA fails to convert the C struct into an object of my Structure class.

I have two questions:

  1. What's wrong with my JNA code?
  2. Does someone know a better way to read out native drag and drop structures in java?

Code from extended ByteArrayTransfer class:

    public class FileGroupDescriptor extends Structure {
        public int cItems;
        public FileDescriptor[] fgd;

        public FileGroupDescriptor() {
            super();
        }

        public FileGroupDescriptor(Pointer pointer) {
            super(pointer);
        }
    }

    public Object nativeToJava(TransferData transferData) {
        if (transferData.type == 49478) {
            Native.setProtected(true);

            byte[] buffer = (byte[]) super.nativeToJava(transferData);

            Memory memory = new Memory(buffer.length);
            memory.write(0, buffer, 0, buffer.length - 1);

            Pointer p = memory.getPointer(0);
            FileGroupDescriptor groupDescriptor = new FileGroupDescriptor(p);

            System.out.println(groupDescriptor.cItems);
        }

        return "";
    }

Upvotes: 1

Views: 1765

Answers (1)

technomage
technomage

Reputation: 10069

Nominally, this is how you need to initialize the JNA structure.

public class FileGroupDescriptor extends Structure {
    public int cItems;
    public FileDescriptor[] fgd;

    public FileGroupDescriptor(Pointer pointer) {
        super(pointer);
        this.cItems = pointer.readInt(0);
        this.fgd = new FileDescriptor[this.cItems];
        this.read();
    }
}

That should be sufficient to provide the information you're looking for in the fgd field. You should also write the entire byte[] length into memory; not sure why you're omitting the last byte (this isn't a C string).

Upvotes: 1

Related Questions