C#使用WinApi監(jiān)控和獲取剪切板數(shù)據(jù)
[DllImport("user32.dll")]
? ? ? ? public static extern int OpenClipboard(IntPtr hWndNewOwner);
? ? ? ? [DllImport("user32.dll")]
? ? ? ? public static extern int CloseClipboard();
? ? ? ? [DllImport("user32.dll")]
? ? ? ? public static extern uint EnumClipboardFormats(uint format);
? ? ? ? [DllImport("user32.dll", CharSet = CharSet.Unicode)]
? ? ? ? public static extern int GetClipboardFormatNameW(int format, StringBuilder buffer, int maxLength);
? ? ? ? [DllImport("user32.dll")]
? ? ? ? public static extern bool IsClipboardFormatAvailable(int format);
? ? ? ? [DllImport("user32.dll")]
? ? ? ? public static extern IntPtr GetClipboardData(uint uFormat);
? ? ? ? [DllImport("Kernel32.dll")]
? ? ? ? public static extern IntPtr GlobalLock(IntPtr hMem);
? ? ? ? [DllImport("Kernel32.dll")]
? ? ? ? public static extern bool GlobalUnlock(IntPtr hMem);
? ? ? ? [DllImport("kernel32.dll", SetLastError = true)]
? ? ? ? public static extern uint GlobalSize([In] IntPtr hMem);
? ? ? ? [DllImport("user32.dll")]
? ? ? ? public static extern uint GetClipboardSequenceNumber();
? ? ? ? //輸出內(nèi)容:
? ? ? ? //Current clipboard sequence number: 1037
? ? ? ? //剪切板內(nèi)容改變!
? ? ? ? //fmt: 13? ? ? ? ?---? ? ?CF_UNICODETEXT
? ? ? ? //fmt: 16? ? ? ? ?---? ? ?CF_LOCALE
? ? ? ? //fmt: 1? ? ? ? ? ---? ? ?CF_TEXT
? ? ? ? //fmt: 7? ? ? ? ? ---? ? ?CF_OEMTEXT
? ? ? ? //獲取剪切板內(nèi)容 CF_UNICODETEXT: 這是測試數(shù)據(jù)
? ? ? ? static void Main(string[] args)
? ? ? ? {
? ? ? ? ? ? uint sequenceNumber;
? ? ? ? ? ? uint tmpSN = 0;
? ? ? ? ? ? bool f = true;
? ? ? ? ? ? while (true)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? sequenceNumber = GetClipboardSequenceNumber();
? ? ? ? ? ? ? ? if (f)
? ? ? ? ? ? ? ? {? ? ? ?? ?
? ? ? ? ? ? ? ? ? ? f = false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else if (sequenceNumber == tmpSN)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? tmpSN = sequenceNumber;
? ? ? ? ? ? ? ? Console.WriteLine("Current clipboard sequence number: " + sequenceNumber);
? ? ? ? ? ? ? ? OpenClipboard(IntPtr.Zero);
? ? ? ? ? ? ? ? uint fmt = 0;
? ? ? ? ? ? ? ? Console.WriteLine("剪切板內(nèi)容改變!");
? ? ? ? ? ? ? ? while ((fmt = EnumClipboardFormats(fmt)) != 0)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? // 定義緩沖區(qū)和最大長度
? ? ? ? ? ? ? ? ? ? StringBuilder buffer = new StringBuilder(256);
? ? ? ? ? ? ? ? ? ? int maxLength = buffer.Capacity;
? ? ? ? ? ? ? ? ? ? string fmtName = "";
? ? ? ? ? ? ? ? ? ? switch (fmt)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? case 2:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_BITMAP";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 8:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_DIB";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 17:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_DIBV5";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 5:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_DIF";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 0x0082:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_DSPBITMAP";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 0x008E:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_DSPENHMETAFILE";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 0x0083:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_DSPMETAFILEPICT";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 0x0081:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_DSPTEXT";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 14:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_ENHMETAFILE";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 0x0300:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_GDIOBJFIRST";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 0x03FF:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_GDIOBJLAST";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 15:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_HDROP";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 16:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_LOCALE";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 3:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_METAFILEPICT";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 7:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_OEMTEXT";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 0x0080:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_OWNERDISPLAY";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 9:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_PALETTE";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 10:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_PENDATA";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 0x0200:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_PRIVATEFIRST";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 0x02FF:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_PRIVATELAST";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 11:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_RIFF";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 4:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_SYLK";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 1:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_TEXT";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 6:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_TIFF";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 13:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_UNICODETEXT";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 12:
? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = "CF_WAVE";
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? ? ? ? ? //對于不是標(biāo)準(zhǔn)的剪切板格式
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 調(diào)用GetClipboardFormatNameW函數(shù)獲取剪貼板格式名稱
? ? ? ? ? ? ? ? ? ? ? ? ? ? int result = GetClipboardFormatNameW((int)fmt, buffer, maxLength);
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (result > 0)
? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = buffer.ToString();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 輸出剪貼板格式名稱
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // Console.WriteLine("剪貼板格式 " + fmt + " 的名稱是:" + buffer.ToString());
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? buffer.Clear();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? buffer.Append("[Error]");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fmtName = buffer.ToString();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //Console.WriteLine("無法獲取剪貼板格式 " + fmt + " 的名稱");
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? Console.WriteLine("fmt: " + fmt.ToString().PadRight(8) + "\t" + "---" + "\t" + fmtName);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if (IsClipboardFormatAvailable(13))//CF_UNICODETEXT
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? IntPtr hCpData = GetClipboardData(13);
? ? ? ? ? ? ? ? ? ? IntPtr pGlobal = GlobalLock(hCpData);
? ? ? ? ? ? ? ? ? ? byte[] bf = new byte[GlobalSize(pGlobal)];
? ? ? ? ? ? ? ? ? ? if (pGlobal != IntPtr.Zero)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? Marshal.Copy(pGlobal, bf, 0, bf.Length);
? ? ? ? ? ? ? ? ? ? ? ? GlobalUnlock(pGlobal);
? ? ? ? ? ? ? ? ? ? ? ? Console.WriteLine("獲取剪切板內(nèi)容 CF_UNICODETEXT: " + System.Text.Encoding.Unicode.GetString(bf));// bf.ToString() 不行,只會輸出 System::char[]
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? Console.WriteLine("pGlobal 為 Null!");
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? CloseClipboard();
? ? ? ? ? ? ? ? //窗口程序可用 AddClipboardFormatListener 來注冊監(jiān)聽器,這樣就不用使用死循環(huán)來檢測剪切板數(shù)據(jù)是否變化了
? ? ? ? ? ? ? ? //BOOL AddClipboardFormatListener(
? ? ? ? ? ? ? ? //? ? [in] HWND hwnd//要放置在剪貼板格式偵聽器列表中的窗口的句柄。
? ? ? ? ? ? ? ? //);
? ? ? ? ? ? ? ? System.Threading.Thread.Sleep(1000);?
? ? ? ? ? ? ? ? Console.WriteLine();
? ? ? ? ? ? }
? ? ? ? }