Mega Code Archive

 
Categories / Java / SWT Jface Eclipse
 

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