Resending:
Hi,
I am writing a .Net wrapper for the MS object picker, but I am
running into a marshalling problem.
I am having trouble retrieving data returned after selecting users and
clicking OK. When I call the dataObj.GetData (...) it returns a handle
inside STGMEDIUM that is invalid. The GetLastWin32Error returns an
Error Code 6. (ERROR_INVALID_HANDLE)
Please see code below.
Ill appreciate any input on this issue.
Thanks in advance,
Abhinav
/**********************************************
This is code to extract the data
***********************************************/
private string ProcessSelectedObjects (IDataObject dataObj)
{
STGMEDIUM stg = new STGMEDIUM ();
stg.tymed = (uint) TYMED.TYMED_HGLOBAL;
stg.pUnkForRelease = null;
stg.hGlobal = IntPtr.Zero;
FORMATETC fetc = new FORMATETC ();
fetc.cfFormat = PInvoke.RegisterClipboardFormat
(CLIPBOARD_FORMAT.CFSTR_DSOP_DS_SELECTION_LIST);
fetc.ptd = 0;
fetc.dwAspect = (uint) DVASPECT.DVASPECT_CONTENT;
fetc.lindex = -1;
fetc.tymed = (uint) TYMED.TYMED_HGLOBAL;
int hr = dataObj.GetData (ref fetc, ref stg);
if (hr != HRESULT.S_OK)
{
//error
}
int error = 0;
IntPtr ptr = PInvoke.GlobalLock(stg.hGlobal);
if (ptr == IntPtr.Zero)
{
error = Marshal.GetLastWin32Error ();
}
PInvoke.GlobalUnlock(ptr);
}
/*********************************
These are the structures
**********************************/
/* Interfaces */
[
ComImport,
CLSCompliant(false),
Guid("0000010e-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
public interface IDataObject
{
[PreserveSig ()]
int GetData(ref FORMATETC pFormatEtc, ref STGMEDIUM b);
void GetDataHere(ref FORMATETC pFormatEtc, ref STGMEDIUM b);
[PreserveSig()]
int QueryGetData(IntPtr a);
[PreserveSig()]
int GetCanonicalFormatEtc(IntPtr a, IntPtr b);
[PreserveSig()]
int SetData(IntPtr a, IntPtr b, int c);
[PreserveSig()]
int EnumFormatEtc(uint a, IntPtr b);
[PreserveSig()]
int DAdvise(IntPtr a, uint b, IntPtr c, ref uint d);
[PreserveSig()]
int DUnadvise(uint a);
[PreserveSig()]
int EnumDAdvise(IntPtr a);
}
[
CLSCompliant(false),
StructLayout(LayoutKind.Sequential)
]
public struct FORMATETC
{
public int cfFormat;
public int ptd;
public uint dwAspect;
public int lindex;
public uint tymed;
}
[
CLSCompliant(false),
StructLayout(LayoutKind.Sequential)
]
public struct STGMEDIUM
{
public uint tymed;
public IntPtr hGlobal;
public Object pUnkForRelease;
}
/********************************************
Call to INvokeDialog
********************************************/
public override string InvokeDialog (IntPtr handle)
{
IDsObjectPicker idop = null;
idop = Initialize ();
IDataObject dataObj = null;
idop.InvokeDialog(handle, out dataObj);
//have to process dataObj and return SID string
return ProcessSelectedObjects (dataObj);