我正在开发与Windows剪贴板相关的C#应用程序。由于在Dot Net剪贴板库(STA,无法打开剪贴板等)中存在许多缺点,我决定直接使用系统API。使用P时调用堆损坏GlobalSize
我想要做的是每种格式的备份数据(尽可能多,如果不是全部),将它们推入堆栈,然后再弹出到剪贴板。如果您尝试使用AutoHotKey,那么它会执行“ClipboardAll”。
问题提出时,我试图获取数据,我这是怎么写的PInvoke:
[DllImport("user32.dll", SetLastError = true)]
public static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool CloseClipboard();
[DllImport("user32.dll")]
public static extern IntPtr GetClipboardData(uint uFormat);
[DllImport("user32.dll", SetLastError = true)]
public static extern uint EnumClipboardFormats(uint format);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GlobalLock(IntPtr hMem);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GlobalUnlock(IntPtr hMem);
[DllImport("kernel32.dll")]
public static extern UIntPtr GlobalSize(IntPtr hMem);
这就是我如何使用它们:
var x = GetFormats(); // a list returned from EnumClipboardFormats
foreach (uint format in x)
{
IntPtr p = NativeMethods.GetClipboardData(format);
int length = (int) NativeMethods.GlobalSize(p);
IntPtr memPtr = NativeMethods.GlobalLock(p);
byte[] buffer = new byte[length];
Marshal.Copy(memPtr, buffer, 0, length);
NativeMethods.GlobalFree(p);
dataObject.Data[format] = buffer;//My data object
}
WinApi.CloseClipBoard();
return dataObject;
然后当我复制的东西在微软Office Excel中,我得到: A Heap corrupted Exception at "GlobalSize" Method.
而我试图跳过触发例外的格式:
if(format==14||format==2) continue;
然后一切正常。
格式2表示CF_BITMAP,格式14是CF_ENHMETAFILE,我想他们可能会在剪贴板中使用所谓的“延迟渲染”技术,也就是说他们的数据在第一次创建时是空的,而当有人试图获得他们,我想知道渲染调用时数据的句柄是否会改变,但我不确定。
所以,有没有人可以帮助,找出原因,并告诉我如何解决。
http://www.olivierlanglois.net/metafile-clipboard.html – stuartd
该代码在23年前停止工作。您必须使用IDataObject来访问剪贴板数据。 –