J
Jeff Gaines
I am trying to set up a DROPFILES structure and copy it to the
clipboard as follows:
[StructLayout(LayoutKind.Sequential)]
struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
struct DROPFILES
{
public int pFiles;
public POINT pt;
public bool fNC;
public bool fWide;
}
public bool clipCopyFiles(string[] strFiles)
{
bool blnReturn = false;
char[] cData;
DROPFILES df = new DROPFILES();
int intChars, intFiles, intPos;
int intDataLen = 0;
IntPtr lpGlobal = IntPtr.Zero;
// Build null terminated list of files
// Data length is total length of file names plus trailing null
intDataLen = 0;
int intNumFiles = strFiles.GetUpperBound(0);
for(intFiles = 0; intFiles <= intNumFiles; intFiles++)
intDataLen = intDataLen + strFiles[intFiles].Length + 1;
// Allow for final trailing zero
intDataLen++;
// Initialise char array with a margin
cData = new Char[intDataLen + 2];
intPos = 0;
for(intFiles = 0; intFiles <= intNumFiles; intFiles++)
{
for(intChars = 0; intChars < strFiles[intFiles].Length;
intChars++)
cData[intPos++] = strFiles[intFiles][intChars];
cData[intPos++] = '\0';
}
cData[intPos++] = '\0';
// Allocate and get pointer to global memory - needs a margin!
lpGlobal = Marshal.AllocHGlobal(Marshal.SizeOf(df) + intDataLen
+ 10);
if(lpGlobal == IntPtr.Zero)
return false;
// Build DROPFILES structure in global memory.
df.pFiles = Marshal.SizeOf(df);
df.fWide = false;
Marshal.StructureToPtr(df, lpGlobal, true);
IntPtr ipNew = new IntPtr(lpGlobal.ToInt32() +
Marshal.SizeOf(df));
Marshal.Copy(cData, 0, ipNew, intDataLen);
// Open and empty clipboard
if(!OpenClipboard(this.Handle))
return false;
EmptyClipboard();
// Copy data to clipboard
blnReturn = (SetClipboardData(CF_HDROP, lpGlobal) !=
IntPtr.Zero);
// Clean up
CloseClipboard();
Marshal.FreeHGlobal(lpGlobal);
return blnReturn;
}
It is based on a VB6 app (that works fine). I have had quite a few
crashes getting it together and it now works to the extent that
getting the file format from the clipboard returns 'FileDrop'. Right
clicking in Explorer shows the 'Paste' option is available but
attempting to paste the files in Explorer produces the error 'Cannot
copy file: Cannot read from the source file or disk'. The files do
exist and I am trying to paste into another folder, i.e. not on top of
the existing files.
Has anybody any thought on this? Am I attempting the impossible?
It seems so close yet so far )
clipboard as follows:
[StructLayout(LayoutKind.Sequential)]
struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
struct DROPFILES
{
public int pFiles;
public POINT pt;
public bool fNC;
public bool fWide;
}
public bool clipCopyFiles(string[] strFiles)
{
bool blnReturn = false;
char[] cData;
DROPFILES df = new DROPFILES();
int intChars, intFiles, intPos;
int intDataLen = 0;
IntPtr lpGlobal = IntPtr.Zero;
// Build null terminated list of files
// Data length is total length of file names plus trailing null
intDataLen = 0;
int intNumFiles = strFiles.GetUpperBound(0);
for(intFiles = 0; intFiles <= intNumFiles; intFiles++)
intDataLen = intDataLen + strFiles[intFiles].Length + 1;
// Allow for final trailing zero
intDataLen++;
// Initialise char array with a margin
cData = new Char[intDataLen + 2];
intPos = 0;
for(intFiles = 0; intFiles <= intNumFiles; intFiles++)
{
for(intChars = 0; intChars < strFiles[intFiles].Length;
intChars++)
cData[intPos++] = strFiles[intFiles][intChars];
cData[intPos++] = '\0';
}
cData[intPos++] = '\0';
// Allocate and get pointer to global memory - needs a margin!
lpGlobal = Marshal.AllocHGlobal(Marshal.SizeOf(df) + intDataLen
+ 10);
if(lpGlobal == IntPtr.Zero)
return false;
// Build DROPFILES structure in global memory.
df.pFiles = Marshal.SizeOf(df);
df.fWide = false;
Marshal.StructureToPtr(df, lpGlobal, true);
IntPtr ipNew = new IntPtr(lpGlobal.ToInt32() +
Marshal.SizeOf(df));
Marshal.Copy(cData, 0, ipNew, intDataLen);
// Open and empty clipboard
if(!OpenClipboard(this.Handle))
return false;
EmptyClipboard();
// Copy data to clipboard
blnReturn = (SetClipboardData(CF_HDROP, lpGlobal) !=
IntPtr.Zero);
// Clean up
CloseClipboard();
Marshal.FreeHGlobal(lpGlobal);
return blnReturn;
}
It is based on a VB6 app (that works fine). I have had quite a few
crashes getting it together and it now works to the extent that
getting the file format from the clipboard returns 'FileDrop'. Right
clicking in Explorer shows the 'Paste' option is available but
attempting to paste the files in Explorer produces the error 'Cannot
copy file: Cannot read from the source file or disk'. The files do
exist and I am trying to paste into another folder, i.e. not on top of
the existing files.
Has anybody any thought on this? Am I attempting the impossible?
It seems so close yet so far )