/// <summary> /// Factory for the write information /// </summary> /// <param name="clipboardAccessToken">IClipboardLock</param> /// <param name="formatId">uint with the format id</param> /// <param name="size">int with the size of the clipboard area</param> /// <returns>ClipboardNativeInfo</returns> public static ClipboardNativeInfo WriteInfo(this IClipboardAccessToken clipboardAccessToken, uint formatId, long size) { clipboardAccessToken.ThrowWhenNoAccess(); var hGlobal = Kernel32Api.GlobalAlloc(GlobalMemorySettings.ZeroInit | GlobalMemorySettings.Movable, new UIntPtr((ulong)size)); if (hGlobal == IntPtr.Zero) { throw new Win32Exception(); } var memoryPtr = Kernel32Api.GlobalLock(hGlobal); if (memoryPtr == IntPtr.Zero) { throw new Win32Exception(); } return(new ClipboardNativeInfo { GlobalHandle = hGlobal, MemoryPtr = memoryPtr, NeedsWrite = true, FormatId = formatId }); }
/// <summary> /// Set the content for the specified format. /// You will need to "lock" (OpenClipboard) the clipboard before calling this. /// </summary> /// <param name="format">the format to set the content for</param> /// <param name="stream">MemoryStream with the content</param> public static void SetAsStream(string format, MemoryStream stream) { uint formatId; if (!Format2Id.TryGetValue(format, out formatId)) { formatId = RegisterFormat(format); } var length = stream.Length; var hGlobal = Kernel32Api.GlobalAlloc(GlobalMemorySettings.ZeroInit | GlobalMemorySettings.Movable, new UIntPtr((ulong)length)); if (hGlobal == IntPtr.Zero) { throw new Win32Exception(); } var memoryPtr = Kernel32Api.GlobalLock(hGlobal); try { if (memoryPtr == IntPtr.Zero) { throw new Win32Exception(); } // Fill the global memory Marshal.Copy(stream.GetBuffer(), 0, memoryPtr, (int)length); } finally { Kernel32Api.GlobalUnlock(hGlobal); } // Place the content on the clipboard NativeMethods.SetClipboardData(formatId, hGlobal); }
/// <summary> /// Create ClipboardNativeInfo to read /// </summary> /// <param name="clipboardAccessToken">IClipboardLock</param> /// <param name="formatId">uint</param> /// <returns>ClipboardNativeInfo</returns> public static ClipboardNativeInfo ReadInfo(this IClipboardAccessToken clipboardAccessToken, uint formatId) { clipboardAccessToken.ThrowWhenNoAccess(); var hGlobal = NativeMethods.GetClipboardData(formatId); if (hGlobal == IntPtr.Zero) { if (NativeMethods.IsClipboardFormatAvailable(formatId)) { throw new Win32Exception($"Format {formatId} not available."); } throw new Win32Exception(); } var memoryPtr = Kernel32Api.GlobalLock(hGlobal); if (memoryPtr == IntPtr.Zero) { throw new Win32Exception(); } return(new ClipboardNativeInfo { GlobalHandle = hGlobal, MemoryPtr = memoryPtr, FormatId = formatId }); }
/// <summary> /// Retrieve the content for the specified format. /// You will need to "lock" (OpenClipboard) the clipboard before calling this. /// </summary> /// <param name="format">the format to retrieve the content for</param> /// <returns>MemoryStream</returns> public static MemoryStream GetAsStream(string format) { uint formatId; if (!Format2Id.TryGetValue(format, out formatId)) { formatId = RegisterFormat(format); } var hGlobal = NativeMethods.GetClipboardData(formatId); var memoryPtr = Kernel32Api.GlobalLock(hGlobal); try { if (memoryPtr == IntPtr.Zero) { throw new Win32Exception(); } var size = Kernel32Api.GlobalSize(hGlobal); var stream = new MemoryStream(size); stream.SetLength(size); // Fill the memory stream Marshal.Copy(memoryPtr, stream.GetBuffer(), 0, size); return(stream); } finally { Kernel32Api.GlobalUnlock(hGlobal); } }