Reading and writing to a SAFEARRAY : WIN32 « SWT JFace Eclipse « Java





Reading and writing to a SAFEARRAY


/*
 * 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;
  }
}


           
       










Related examples in the same category

1.Invoke the system text editor on autoexec.bat
2.Place an icon with a popup menu on the system trayPlace an icon with a popup menu on the system tray
3.SWT Ole FrameSWT Ole Frame
4.OLE and ActiveX example snippet
5.Word OLEWord OLE
6.Invoke an external batch fileInvoke an external batch file
7.Find the icon of the program that edits .bmp filesFind the icon of the program that edits .bmp files
8.Running a script within IE.Running a script within IE.
9.Embed Word in an applet
10.OLE and ActiveX example: browse the typelibinfo for a program id
11.OLE and ActiveX example: get events from IE controlOLE and ActiveX example: get events from IE control
12.How to access About, Preferences and Quit menus on carbon