/** 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
*/
importorg.eclipse.swt.SWT;
importorg.eclipse.swt.SWTException;
importorg.eclipse.swt.internal.win32.OS;
importorg.eclipse.swt.layout.GridData;
importorg.eclipse.swt.layout.GridLayout;
importorg.eclipse.swt.ole.win32.OLE;
importorg.eclipse.swt.ole.win32.OleAutomation;
importorg.eclipse.swt.ole.win32.OleControlSite;
importorg.eclipse.swt.ole.win32.OleEvent;
importorg.eclipse.swt.ole.win32.OleFrame;
importorg.eclipse.swt.ole.win32.OleListener;
importorg.eclipse.swt.ole.win32.Variant;
importorg.eclipse.swt.widgets.Button;
importorg.eclipse.swt.widgets.Display;
importorg.eclipse.swt.widgets.Event;
importorg.eclipse.swt.widgets.Listener;
importorg.eclipse.swt.widgets.Shell;
importorg.eclipse.swt.widgets.Text;
public classSnippet186{
staticintCodePage = OS.GetACP();
public staticvoidmain(String[]args) {
Display display =newDisplay();
Shell shell =newShell(display);
shell.setLayout(newGridLayout(2,false));
finalText text =newText(shell, SWT.BORDER);
text
.setLayoutData(newGridData(SWT.FILL, SWT.CENTER, true, false,
1,1));
Button go =newButton(shell, SWT.PUSH);
go.setText("Go");
OleFrame oleFrame =newOleFrame(shell, SWT.NONE);
oleFrame.setLayoutData(newGridData(SWT.FILL, SWT.FILL, true, true,2,
1));
OleControlSite controlSite;
OleAutomation automation;
try{
controlSite =newOleControlSite(oleFrame, SWT.NONE,
"Shell.Explorer");
automation =newOleAutomation(controlSite);
controlSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
}catch(SWTException ex) {
return;
}
finalOleAutomation auto = automation;
go.addListener(SWT.Selection,newListener() {
publicvoidhandleEvent(Event e) {
String url = text.getText();
int[]rgdispid = auto.getIDsOfNames(newString[] {"Navigate",
"URL"});
intdispIdMember = rgdispid[0];
Variant[]rgvarg =newVariant[1];
rgvarg[0]=newVariant(url);
int[]rgdispidNamedArgs =newint[1];
rgdispidNamedArgs[0]= rgdispid[1];
auto.invoke(dispIdMember, rgvarg, rgdispidNamedArgs);
}
});
// Read PostData whenever we navigate to a site that uses it
intBeforeNavigate2 =0xfa;
controlSite.addEventListener(BeforeNavigate2,newOleListener() {
publicvoidhandleEvent(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(newString[] {"Navigate",
"URL","PostData"});
intdispIdMember = rgdispid[0];
Variant[]rgvarg =newVariant[2];
rgvarg[0]=newVariant(text.getText());
rgvarg[1]= writeSafeArray("hello world");
int[]rgdispidNamedArgs =newint[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
staticString readSafeArray(Variant variantByRef) {
// Read a safearray that contains data of
// type VT_UI1 (unsigned shorts) which contains
// a text stream.
intpPostData = variantByRef.getByRef();
short[]vt_type =newshort[1];
OS.MoveMemory(vt_type, pPostData,2);
String result =null;
if(vt_type[0]==(short) (OLE.VT_BYREF | OLE.VT_VARIANT)) {
int[]pVariant =newint[1];
OS.MoveMemory(pVariant, pPostData +8,4);
vt_type =newshort[1];
OS.MoveMemory(vt_type, pVariant[0],2);
if(vt_type[0]==(short) (OLE.VT_ARRAY | OLE.VT_UI1)) {
int[]pSafearray =newint[1];
OS.MoveMemory(pSafearray, pVariant[0]+8,4);
short[]cDims =newshort[1];
OS.MoveMemory(cDims, pSafearray[0],2);
int[]pvData =newint[1];
OS.MoveMemory(pvData, pSafearray[0]+12,4);
intsafearrayboundOffset =0;
for(inti =0; i
int[]cElements =newint[1];
OS.MoveMemory(cElements, pSafearray[0]+16
+ safearrayboundOffset,4);
safearrayboundOffset +=8;
intcchWideChar = OS.MultiByteToWideChar(CodePage,
OS.MB_PRECOMPOSED, pvData[0], -1, null,0);
if(cchWideChar ==0)
return null;
char[]lpWideCharStr =newchar[cchWideChar -1];
OS.MultiByteToWideChar(CodePage, OS.MB_PRECOMPOSED,
pvData[0], -1, lpWideCharStr, lpWideCharStr.length);
result =newString(lpWideCharStr);
}
}
}
returnresult;
}
staticVariant 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
shortcDims =1;
shortFADF_FIXEDSIZE =0x10;
shortFADF_HAVEVARTYPE =0x80;
shortfFeatures =(short) (FADF_FIXEDSIZE | FADF_HAVEVARTYPE);
intcbElements =1;
// Create a pointer and copy the data into it
intcount = string.length();
char[]chars =newchar[count +1];
string.getChars(0, count, chars,0);
intcchMultiByte = OS.WideCharToMultiByte(CodePage,0, chars, -1, null,
0, null,null);
if(cchMultiByte ==0)
return null;
intpvData = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT,
cchMultiByte);
OS.WideCharToMultiByte(CodePage,0, chars, -1, pvData, cchMultiByte,
null,null);
intcElements1 = cchMultiByte;
intlLbound1 =0;
// Create a safearray in memory
// 12 bytes for cDims, fFeatures and cbElements + 4 bytes for pvData +
// number of dimensions * (size of safearraybound)
intsizeofSafeArray =12+4+1*8;
intpSafeArray = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT,
sizeofSafeArray);
// Copy the data into the safe array
intoffset =0;
OS.MoveMemory(pSafeArray + offset,newshort[] {cDims},2);
offset +=2;
OS.MoveMemory(pSafeArray + offset,newshort[] {fFeatures},2);
offset +=2;
OS.MoveMemory(pSafeArray + offset,newint[] {cbElements},4);
offset +=4;
OS.MoveMemory(pSafeArray + offset,newint[] {0},4);
offset +=4;
OS.MoveMemory(pSafeArray + offset,newint[] {pvData},4);
offset +=4;
OS.MoveMemory(pSafeArray + offset,newint[] {cElements1},4);
offset +=4;
OS.MoveMemory(pSafeArray + offset,newint[] {lLbound1},4);
offset +=4;
// Create a variant in memory to hold the safearray
intpVariant = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT,
Variant.sizeof);
shortvt =(short) (OLE.VT_ARRAY | OLE.VT_UI1);
OS.MoveMemory(pVariant,newshort[] {vt},2);
OS.MoveMemory(pVariant +8,newint[] {pSafeArray},4);
// Create a by ref variant
Variant variantByRef =newVariant(pVariant,
(short) (OLE.VT_BYREF | OLE.VT_VARIANT));
returnvariantByRef;
}
}