Search code examples
c#.netclipboardunmanagedintptr

Getting byte[] from GetClipboardData native method


I'm trying to get the Clipboard data using this native method with C#/.NET. The problem is I'm mangling the data. Here's my code:

IntPtr pointer = GetClipboardData(dataformat);
int size = Marshal.SizeOf(pointer);
byte[] buff = new byte[size];
Marshal.Copy(data, buff, 0, size);

Here's the pinvoke I'm using for the GetClipboardData method:

[DllImport("user32.dll")]
private static extern IntPtr GetClipboardData(uint uFormat);

Can anyone tell me where I'm going wrong?


Solution

  • If you want to get byte array from clipboard, which represents unicode text for example, the code will be something like this:

    using System;
    using System.Runtime.InteropServices;
    using System.Text;
    
    public class ClipboardHelper
    {
        #region Win32
    
        [DllImport("User32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool IsClipboardFormatAvailable(uint format);
    
        [DllImport("User32.dll", SetLastError = true)]
        private static extern IntPtr GetClipboardData(uint uFormat);
    
        [DllImport("User32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool OpenClipboard(IntPtr hWndNewOwner);
    
        [DllImport("User32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseClipboard();
    
        [DllImport("Kernel32.dll", SetLastError = true)]
        private static extern IntPtr GlobalLock(IntPtr hMem);
    
        [DllImport("Kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GlobalUnlock(IntPtr hMem);
    
        [DllImport("Kernel32.dll", SetLastError = true)]
        private static extern int GlobalSize(IntPtr hMem);
    
        private const uint CF_UNICODETEXT = 13U;
    
        #endregion
    
        public static string GetText()
        {
            if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
                return null;
    
            try
            {
                if (!OpenClipboard(IntPtr.Zero))
                    return null;
    
                IntPtr handle = GetClipboardData(CF_UNICODETEXT);
                if (handle == IntPtr.Zero)
                    return null;
    
                IntPtr pointer = IntPtr.Zero;
    
                try
                {
                    pointer = GlobalLock(handle);
                    if (pointer == IntPtr.Zero)
                        return null;
    
                    int size = GlobalSize(handle);
                    byte[] buff = new byte[size];
    
                    Marshal.Copy(pointer, buff, 0, size);
    
                    return Encoding.Unicode.GetString(buff).TrimEnd('\0');
                }
                finally
                {
                    if (pointer != IntPtr.Zero)
                        GlobalUnlock(handle);
                }
            }
            finally
            {
                CloseClipboard();
            }
        }
    }