C#定義了一個類System.Windows.Forms.Clipboard來簡化剪切板操作,這個類有一個靜態方法,主要有:
Clear 清除剪切板中的所有數據;
ContainsData,ContainsAudio,ContainsFlieDropList,ContainsText,ContainsImage,用於檢查剪切板中是否存在相應的數據;
GetAudioStream,GetDataObject,GetText,GetImage,GetFileDropList,用於取得數據;
SetAudio,SetDataObject,SetText,SetImage,SetFileDropList,用於添加數據;
以下是檢測剪切板的方法:
一、引入
要使用剪切板首先要引入三個函數,
[System.Runtime.InteropServices.DllImport("user32")]
private static extern IntPtr SetClipboardViewer(IntPtr hwnd);
[System.Runtime.InteropServices.DllImport("user32")]
private static extern IntPtr ChangeClipboardChain(IntPtr hwnd,IntPtr hWndNext);
[System.Runtime.InteropServices.DllImport("user32")]
private static extern int SendMessage(IntPtr hwnd,int wMsg,IntPtr wParam,IntPtr lParam);
const int WM_DRAWCLIPBOARD = 0x308;
const int WM_CHANGECBCHAIN = 0x30D;
IntPtr SetClipboardViewer(IntPtr hwnd) 用於往觀察鏈中添加一個窗口句柄,這個窗口就可成為觀察鏈中的一員了,返回值指向下一個觀察者。
IntPtr ChangeClipboardChain(IntPtr hwnd,IntPtr hWndNext); 刪除由hwnd指定的觀察鏈成員,這是一個窗口句柄,第二個參數hWndNext是觀察鏈中下一個窗口的句柄
int SendMessage(IntPtr hwnd,int wMsg,IntPtr wParam,IntPtr lParam); 發送消息
二、使用 定義完成之后,可以分三部來使用,第一步把自己的窗口添加到觀察鏈中成為觀察者,並保存下一個觀察者的句柄;第二步監視剪切板,並把剪切板變化的消息發送給下一個觀察者;第三步撤消自己定義的觀察者,並通知下一個觀察者。
第一步:把自己的窗口添加到觀察鏈中成為觀察者,並保存下一個觀察者的句柄;
//存放觀察鏈中下一個窗口句柄 IntPtr NextClipHwnd; private void Form1_Load(object sender, System.EventArgs e) { //獲得觀察鏈中下一個窗口句 NextClipHwnd=SetClipboardViewer(this.Handle); }
第二步:監視剪切板,並把剪切板變化的消息發送給下一個觀察者,這里需要重載WndProc方法;
這里用到兩個消息常量:
const int WM_DRAWCLIPBOARD = 0x308; const int WM_CHANGECBCHAIN = 0x30D; protected override void WndProc(ref System.Windows.Forms.Message m) { switch(m.Msg) { case WM_DRAWCLIPBOARD: //將WM_DRAWCLIPBOARD消息傳遞到下一個觀察鏈中的窗口 SendMessage(NextClipHwnd,m.Msg,m.WParam,m.LParam); IDataObject iData = Clipboard.GetDataObject(); //檢測文本 if(iData.GetDataPresent(DataFormats.Text)|iData.GetDataPresent(DataFormats.OemText)) { this.richTextBox1.Text=(String)iData.GetData(DataFormats.Text); } //檢測圖像 if (iData.GetDataPresent(DataFormats.Bitmap)) { pictureBox1.Image=Clipboard.GetImage(); NewClipData(); } //檢測自定義類型 if (iData.GetDataPresent("myFormat")) { MyObj myobj=(MyObj)iData.GetData("myFormat"); this.richTextBox1.Text=myobj.ObjName; } break; default: base.WndProc(ref m); break; } }
第三步:撤消自己定義的觀察者,並通知下一個觀察者。
private void Form1_Closed(object sender, System.EventArgs e) { //從觀察鏈中刪除本觀察窗口(第一個參數:將要刪除的窗口的句柄;第二個參數://觀察鏈中下一個窗口的句柄 ) ChangeClipboardChain(this.Handle,NextClipHwnd); //將變動消息WM_CHANGECBCHAIN消息傳遞到下一個觀察鏈中的窗口 SendMessage(NextClipHwnd,WM_CHANGECBCHAIN,this.Handle,NextClipHwnd); }
三、擴展 DataFormats類定義了剪切板內容的幾種格式,包括Text,UnicodeText,OemText,Rtf,Html,Dib,Bitmap等,但自己可以定義新的數據格式,代碼如下 :
//新類 public class MyObj { private string objName; public MyObj() { objName = "自定義剪切板內容"; } public string ObjName { get { return objName; } } } //往剪切板中添加一個自定義內容 private void NewClipData() { DataFormats.Format myFormat = DataFormats.GetFormat("myFormat"); MyObj myobj = new MyObj(); DataObject myDataObject = new DataObject("myFormat", myobj); Clipboard.SetDataObject(myDataObject); } 其中myFormat就是自定義數據格式的名稱, 在上面的WinProc中可以看到 //檢測圖像 if (iData.GetDataPresent(DataFormats.Bitmap)) { pictureBox1.Image=Clipboard.GetImage(); NewClipData(); }
檢測到剪切板中有圖像內容時,就顯示這個圖像,然后,調用NewClipData(),產生一個新剪切板數據,其格式是自定義的myFormat,這時,程序會通過下面這段代碼來檢測到這個變化,並處理
//檢測自定義類型 if(iData.GetDataPresent("myFormat")) { MyObj myobj=(MyObj)iData.GetData("myFormat"); this.richTextBox1.Text=myobj.ObjName; }