/* * EnumFormatEtc([in] dwDirection, [out] ppenumFormatetc) * Ownership of ppenumFormatetc transfers from callee to caller so reference count on ppenumFormatetc * must be incremented before returning. Caller is responsible for releasing ppenumFormatetc. */ private int EnumFormatEtc(int dwDirection, long /*int*/ ppenumFormatetc) { // only allow getting of data - SetData is not currently supported if (dwDirection == COM.DATADIR_SET) return COM.E_NOTIMPL; // what types have been registered? TransferData[] allowedDataTypes = new TransferData[0]; for (int i = 0; i < transferAgents.length; i++) { Transfer transferAgent = transferAgents[i]; if (transferAgent != null) { TransferData[] formats = transferAgent.getSupportedTypes(); TransferData[] newAllowedDataTypes = new TransferData[allowedDataTypes.length + formats.length]; System.arraycopy(allowedDataTypes, 0, newAllowedDataTypes, 0, allowedDataTypes.length); System.arraycopy(formats, 0, newAllowedDataTypes, allowedDataTypes.length, formats.length); allowedDataTypes = newAllowedDataTypes; } } OleEnumFORMATETC enumFORMATETC = new OleEnumFORMATETC(); enumFORMATETC.AddRef(); FORMATETC[] formats = new FORMATETC[allowedDataTypes.length]; for (int i = 0; i < formats.length; i++) { formats[i] = allowedDataTypes[i].formatetc; } enumFORMATETC.setFormats(formats); OS.MoveMemory(ppenumFormatetc, new long /*int*/[] {enumFORMATETC.getAddress()}, OS.PTR_SIZEOF); return COM.S_OK; }
private int SetData(long /*int*/ pFormatetc, long /*int*/ pmedium, int fRelease) { if (pFormatetc == 0 || pmedium == 0) return COM.E_INVALIDARG; FORMATETC formatetc = new FORMATETC(); COM.MoveMemory(formatetc, pFormatetc, FORMATETC.sizeof); if (formatetc.cfFormat == CFSTR_PERFORMEDDROPEFFECT && formatetc.tymed == COM.TYMED_HGLOBAL) { STGMEDIUM stgmedium = new STGMEDIUM(); COM.MoveMemory(stgmedium, pmedium, STGMEDIUM.sizeof); // TODO - this should be GlobalLock() long /*int*/[] ptrEffect = new long /*int*/[1]; OS.MoveMemory(ptrEffect, stgmedium.unionField, OS.PTR_SIZEOF); int[] effect = new int[1]; OS.MoveMemory(effect, ptrEffect[0], 4); dataEffect = osToOp(effect[0]); } if (fRelease == 1) { COM.ReleaseStgMedium(pmedium); } return COM.S_OK; }
/* QueryInterface([in] riid, [out] ppvObject) * Ownership of ppvObject transfers from callee to caller so reference count on ppvObject * must be incremented before returning. Caller is responsible for releasing ppvObject. */ private int QueryInterface(long /*int*/ riid, long /*int*/ ppvObject) { if (riid == 0 || ppvObject == 0) return COM.E_INVALIDARG; GUID guid = new GUID(); COM.MoveMemory(guid, riid, GUID.sizeof); if (COM.IsEqualGUID(guid, COM.IIDIUnknown) || COM.IsEqualGUID(guid, COM.IIDIDropSource)) { OS.MoveMemory(ppvObject, new long /*int*/[] {iDropSource.getAddress()}, OS.PTR_SIZEOF); AddRef(); return COM.S_OK; } if (COM.IsEqualGUID(guid, COM.IIDIDataObject)) { OS.MoveMemory(ppvObject, new long /*int*/[] {iDataObject.getAddress()}, OS.PTR_SIZEOF); AddRef(); return COM.S_OK; } OS.MoveMemory(ppvObject, new long /*int*/[] {0}, OS.PTR_SIZEOF); return COM.E_NOINTERFACE; }
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; long /*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 long /*int*/ pSafeArray = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, SAFEARRAY.sizeof); SAFEARRAY safeArray = new SAFEARRAY(); safeArray.cDims = cDims; safeArray.fFeatures = fFeatures; safeArray.cbElements = cbElements; safeArray.pvData = pvData; SAFEARRAYBOUND safeArrayBound = new SAFEARRAYBOUND(); safeArray.rgsabound = safeArrayBound; safeArrayBound.cElements = cElements1; safeArrayBound.lLbound = lLbound1; OS.MoveMemory(pSafeArray, safeArray, SAFEARRAY.sizeof); // Create a variant in memory to hold the safearray long /*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 long /*int*/[] {pSafeArray}, OS.PTR_SIZEOF); // Create a by ref variant Variant variantByRef = new Variant(pVariant, (short) (OLE.VT_BYREF | OLE.VT_VARIANT)); return variantByRef; }
static String readSafeArray(Variant variantByRef) { // Read a safearray that contains data of // type VT_UI1 (unsigned shorts) which contains // a text stream. long /*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)) { long /*int*/[] pSafearray = new long /*int*/[1]; OS.MoveMemory(pSafearray, pVariant[0] + 8, OS.PTR_SIZEOF); SAFEARRAY safeArray = new SAFEARRAY(); OS.MoveMemory(safeArray, pSafearray[0], SAFEARRAY.sizeof); for (int i = 0; i < safeArray.cDims; i++) { int cchWideChar = OS.MultiByteToWideChar(CodePage, OS.MB_PRECOMPOSED, safeArray.pvData, -1, null, 0); if (cchWideChar == 0) return null; char[] lpWideCharStr = new char[cchWideChar - 1]; OS.MultiByteToWideChar( CodePage, OS.MB_PRECOMPOSED, safeArray.pvData, -1, lpWideCharStr, lpWideCharStr.length); result = new String(lpWideCharStr); } } } return result; }