Snippet186.java Source code

Java tutorial

Introduction

Here is the source code for Snippet186.java

Source

/*
 * Reading and writing to a SAFEARRAY
 * 
 * This example reads from a PostData object in a BeforeNavigate2 event and
 * creates a PostData object in a call to Navigate.
 * 
 * For a list of all SWT example snippets see
 * http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/dev.html#snippets
 */
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.internal.win32.OS;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.OleControlSite;
import org.eclipse.swt.ole.win32.OleEvent;
import org.eclipse.swt.ole.win32.OleFrame;
import org.eclipse.swt.ole.win32.OleListener;
import org.eclipse.swt.ole.win32.Variant;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class Snippet186 {

    static int CodePage = OS.GetACP();

    public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setLayout(new GridLayout(2, false));

        final Text text = new Text(shell, SWT.BORDER);
        text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        Button go = new Button(shell, SWT.PUSH);
        go.setText("Go");
        OleFrame oleFrame = new OleFrame(shell, SWT.NONE);
        oleFrame.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
        OleControlSite controlSite;
        OleAutomation automation;
        try {
            controlSite = new OleControlSite(oleFrame, SWT.NONE, "Shell.Explorer");
            automation = new OleAutomation(controlSite);
            controlSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
        } catch (SWTException ex) {
            return;
        }

        final OleAutomation auto = automation;
        go.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                String url = text.getText();
                int[] rgdispid = auto.getIDsOfNames(new String[] { "Navigate", "URL" });
                int dispIdMember = rgdispid[0];
                Variant[] rgvarg = new Variant[1];
                rgvarg[0] = new Variant(url);
                int[] rgdispidNamedArgs = new int[1];
                rgdispidNamedArgs[0] = rgdispid[1];
                auto.invoke(dispIdMember, rgvarg, rgdispidNamedArgs);
            }
        });

        // Read PostData whenever we navigate to a site that uses it
        int BeforeNavigate2 = 0xfa;
        controlSite.addEventListener(BeforeNavigate2, new OleListener() {
            public void handleEvent(OleEvent event) {
                Variant url = event.arguments[1];
                Variant postData = event.arguments[4];
                if (postData != null) {
                    System.out.println("PostData = " + readSafeArray(postData) + ", URL = " + url.getString());
                }
            }
        });

        // Navigate to this web site which uses post data to fill in the text
        // field
        // and put the string "hello world" into the text box
        text.setText("file://" + Snippet186.class.getResource("Snippet186.html").getFile());
        int[] rgdispid = automation.getIDsOfNames(new String[] { "Navigate", "URL", "PostData" });
        int dispIdMember = rgdispid[0];
        Variant[] rgvarg = new Variant[2];
        rgvarg[0] = new Variant(text.getText());
        rgvarg[1] = writeSafeArray("hello world");
        int[] rgdispidNamedArgs = new int[2];
        rgdispidNamedArgs[0] = rgdispid[1];
        rgdispidNamedArgs[1] = rgdispid[2];
        automation.invoke(dispIdMember, rgvarg, rgdispidNamedArgs);

        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }

    // The following structs are accessed in the readSafeArray and
    // writeSafeArray
    // functions:
    //
    // VARIANT:
    // short vt
    // short wReserved1
    // short wReserved2
    // short wReserved3
    // int parray
    //
    // SAFEARRAY:
    // short cDims // Count of dimensions in this array
    // short fFeatures // Flags used by the SafeArray
    // int cbElements // Size of an element of the array
    // int cLocks // Number of times the array has been locked without
    // corresponding unlock
    // int pvData // Pointer to the data
    // SAFEARRAYBOUND[] rgsabound // One bound for each dimension
    //
    // SAFEARRAYBOUND:
    // int cElements // the number of elements in the dimension
    // int lLbound // the lower bound of the dimension

    static String readSafeArray(Variant variantByRef) {
        // Read a safearray that contains data of
        // type VT_UI1 (unsigned shorts) which contains
        // a text stream.
        int pPostData = variantByRef.getByRef();
        short[] vt_type = new short[1];
        OS.MoveMemory(vt_type, pPostData, 2);
        String result = null;
        if (vt_type[0] == (short) (OLE.VT_BYREF | OLE.VT_VARIANT)) {
            int[] pVariant = new int[1];
            OS.MoveMemory(pVariant, pPostData + 8, 4);
            vt_type = new short[1];
            OS.MoveMemory(vt_type, pVariant[0], 2);
            if (vt_type[0] == (short) (OLE.VT_ARRAY | OLE.VT_UI1)) {
                int[] pSafearray = new int[1];
                OS.MoveMemory(pSafearray, pVariant[0] + 8, 4);
                short[] cDims = new short[1];
                OS.MoveMemory(cDims, pSafearray[0], 2);
                int[] pvData = new int[1];
                OS.MoveMemory(pvData, pSafearray[0] + 12, 4);
                int safearrayboundOffset = 0;
                for (int i = 0; i < cDims[0]; i++) {
                    int[] cElements = new int[1];
                    OS.MoveMemory(cElements, pSafearray[0] + 16 + safearrayboundOffset, 4);
                    safearrayboundOffset += 8;
                    int cchWideChar = OS.MultiByteToWideChar(CodePage, OS.MB_PRECOMPOSED, pvData[0], -1, null, 0);
                    if (cchWideChar == 0)
                        return null;
                    char[] lpWideCharStr = new char[cchWideChar - 1];
                    OS.MultiByteToWideChar(CodePage, OS.MB_PRECOMPOSED, pvData[0], -1, lpWideCharStr,
                            lpWideCharStr.length);
                    result = new String(lpWideCharStr);
                }
            }
        }
        return result;
    }

    static Variant writeSafeArray(String string) {
        // Create a one dimensional safearray containing two VT_UI1 values
        // where VT_UI1 is an unsigned char

        // Define cDims, fFeatures and cbElements
        short cDims = 1;
        short FADF_FIXEDSIZE = 0x10;
        short FADF_HAVEVARTYPE = 0x80;
        short fFeatures = (short) (FADF_FIXEDSIZE | FADF_HAVEVARTYPE);
        int cbElements = 1;
        // Create a pointer and copy the data into it
        int count = string.length();
        char[] chars = new char[count + 1];
        string.getChars(0, count, chars, 0);
        int cchMultiByte = OS.WideCharToMultiByte(CodePage, 0, chars, -1, null, 0, null, null);
        if (cchMultiByte == 0)
            return null;
        int pvData = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, cchMultiByte);
        OS.WideCharToMultiByte(CodePage, 0, chars, -1, pvData, cchMultiByte, null, null);
        int cElements1 = cchMultiByte;
        int lLbound1 = 0;
        // Create a safearray in memory
        // 12 bytes for cDims, fFeatures and cbElements + 4 bytes for pvData +
        // number of dimensions * (size of safearraybound)
        int sizeofSafeArray = 12 + 4 + 1 * 8;
        int pSafeArray = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, sizeofSafeArray);
        // Copy the data into the safe array
        int offset = 0;
        OS.MoveMemory(pSafeArray + offset, new short[] { cDims }, 2);
        offset += 2;
        OS.MoveMemory(pSafeArray + offset, new short[] { fFeatures }, 2);
        offset += 2;
        OS.MoveMemory(pSafeArray + offset, new int[] { cbElements }, 4);
        offset += 4;
        OS.MoveMemory(pSafeArray + offset, new int[] { 0 }, 4);
        offset += 4;
        OS.MoveMemory(pSafeArray + offset, new int[] { pvData }, 4);
        offset += 4;
        OS.MoveMemory(pSafeArray + offset, new int[] { cElements1 }, 4);
        offset += 4;
        OS.MoveMemory(pSafeArray + offset, new int[] { lLbound1 }, 4);
        offset += 4;
        // Create a variant in memory to hold the safearray
        int pVariant = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, Variant.sizeof);
        short vt = (short) (OLE.VT_ARRAY | OLE.VT_UI1);
        OS.MoveMemory(pVariant, new short[] { vt }, 2);
        OS.MoveMemory(pVariant + 8, new int[] { pSafeArray }, 4);
        // Create a by ref variant
        Variant variantByRef = new Variant(pVariant, (short) (OLE.VT_BYREF | OLE.VT_VARIANT));
        return variantByRef;
    }
}