从GetClipboardData本机方法

时间:2015-10-07 23:11:00

标签: c# .net clipboard unmanaged intptr

我正在尝试使用带有C#/ .NET的this native method来获取剪贴板数据。问题是我正在破坏数据。这是我的代码:

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

这是我用于GetClipboardData方法的pinvoke:

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

谁能告诉我哪里出错?

1 个答案:

答案 0 :(得分:5)

如果你想从剪贴板获取字节数组,例如代表unicode文本,代码将是这样的:

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();
        }
    }
}