關於C#監視剪貼板信息

1、常規方法

在C#中,有一個常規檢測剪貼板的方法,用的是 System.Windows.Forms.Clipboard;

使用起來很簡單,代碼如下:

/// <summary>
/// 設置剪貼板的文本內容
/// </summary>
/// <param name="s">文本內容</param>
public static void SetText(string s)
{
        Clipboard.SetDataObject(s ?? "");
}

/// <summary>
/// 獲取剪貼板中的文本內容
/// </summary>
/// <returns>返回剪貼板文本</returns>
public static string GetText()
{
        IDataObject iData = Clipboard.GetDataObject();
        return (string)iData.GetData(DataFormats.Text);
}

/// <summary>
/// 獲取剪貼板位圖格式數據(比如從畫圖軟件裏複製的圖片……)
/// </summary>
/// <returns>位圖</returns>
public static Bitmap GetBitmap()
{
        IDataObject iData = Clipboard.GetDataObject();
        //確定此實例中存儲的數據是否與指定的格式關聯,或是否可以轉換成指定的格式
        if (iData.GetDataPresent(DataFormats.Bitmap))
        {
                Bitmap bt = (Bitmap)iData.GetData(DataFormats.Bitmap);
                return bt;
        }
        return null;
}

2、通知檢測剪貼板

常規方法沒有通知來告訴我們有數據,所以再來一個帶通知的方案:

這個代碼比較長……

public partial class Form2 : Form
{
    IntPtr nextClipboardViewer;
    public Form2()
    {
        InitializeComponent();
        nextClipboardViewer = (IntPtr)SetClipboardViewer((int)Handle);
    }

    /// <summary>
    /// 要處理的 WindowsSystem.Windows.Forms.Message。
    /// </summary>
    /// <param name="m"></param>
    protected override void WndProc(ref Message m)
    {
        // defined in winuser.h
        const int WM_DRAWCLIPBOARD = 0x308;
        const int WM_CHANGECBCHAIN = 0x030D;

        switch (m.Msg)
        {
            case WM_DRAWCLIPBOARD:
                DisplayClipboardData();
                SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
                break;
            case WM_CHANGECBCHAIN:
                if (m.WParam == nextClipboardViewer)
                    nextClipboardViewer = m.LParam;
                else
                    SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
                break;
            default:
                base.WndProc(ref m);
                break;
        }
    }
    /// <summary>
    /// 顯示剪貼板內容
    /// </summary>
    public void DisplayClipboardData()
    {
        try
        {
            IDataObject iData = new DataObject();
            iData = Clipboard.GetDataObject();

            if (iData.GetDataPresent(DataFormats.Rtf))
                richTextBox1.Rtf = (string)iData.GetData(DataFormats.Rtf);
            else if (iData.GetDataPresent(DataFormats.Text))
                richTextBox1.Text = (string)iData.GetData(DataFormats.Text);
            else
                richTextBox1.Text = "[Clipboard data is not RTF or ASCII Text]";
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
        }
    }

    /// <summary>
    /// 關閉程序,從觀察鏈移除
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Form2_FormClosed(object sender, FormClosedEventArgs e)
    {
        ChangeClipboardChain(Handle, nextClipboardViewer);
    }

    #region WindowsAPI
    /// <summary>
    /// 將CWnd加入一個窗口鏈,每當剪貼板的內容發生變化時,就會通知這些窗口
    /// </summary>
    /// <param name="hWndNewViewer">句柄</param>
    /// <returns>返回剪貼板觀察器鏈中下一個窗口的句柄</returns>
    [DllImport("User32.dll")]
    protected static extern int SetClipboardViewer(int hWndNewViewer);

    /// <summary>
    /// 從剪貼板鏈中移出的窗口句柄
    /// </summary>
    /// <param name="hWndRemove">從剪貼板鏈中移出的窗口句柄</param>
    /// <param name="hWndNewNext">hWndRemove的下一個在剪貼板鏈中的窗口句柄</param>
    /// <returns>如果成功,非零;否則爲0。</returns>
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);

    /// <summary>
    /// 將指定的消息發送到一個或多個窗口
    /// </summary>
    /// <param name="hwnd">其窗口程序將接收消息的窗口的句柄</param>
    /// <param name="wMsg">指定被髮送的消息</param>
    /// <param name="wParam">指定附加的消息特定信息</param>
    /// <param name="lParam">指定附加的消息特定信息</param>
    /// <returns>消息處理的結果</returns>
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
    #endregion
}

認真看一下並不難理解,這種帶通知的方式更方便操作。

3、代碼

另外代碼打了個包(Form1是方案一,Form2是方案二)
下載

發佈了243 篇原創文章 · 獲贊 639 · 訪問量 80萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章