我正在開發與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來訪問剪貼板數據。 –