关于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是方案二) 
下载

 

 

from: 

https://blog.csdn.net/arrowzz/article/details/56689111

=======================

MoreWindows工作笔记12】WM_DRAWCLIPBOARD 监视剪切板

2013年12月31日 16:00:23

阅读数:21767

有很多程序会监视剪贴板,比如迅雷,这样当你复制一个迅雷下载链接时,迅雷就可以自动启动并创建一个新的下载任务。下面我们就来看看如何实现这个技术。

 

实现这个技术一共需要4步:

第一步:Add the window to the clipboard viewer chain.

通过SetClipboardViewer()传入窗口句柄,所有监视剪贴板的窗口句柄会组成一个链表(后来者靠前)。这样当剪贴板内容发生变化时,Windows系统给给这些窗口发生消息。

 

第二步:Process the WM_CHANGECBCHAIN message.

当这个监视剪贴板的窗口句柄链表发生变化时,会收到这个消息。每个窗口都应该给下一个窗口传递消息。

这个消息的wParamlParam说明如下:

wParam表示

A handle to the window being removedfrom the clipboard viewer chain

lParam表示

A handle to the next window in thechain following the window being removed. This parameter is NULL if thewindow being removed is the last window in the chain。

 

第三步:Process the WM_DRAWCLIPBOARD message.

当剪贴板数据发送变化时,窗口会依次收到这个消息。

 

第四步:Remove the window from the clipboard viewer chain before itis destroyed.

当窗口关闭时,应该调用ChangeClipboardChain()来通知Windows系统将自己从监视剪贴板的窗口句柄链表中移除。

 

代码如下(下载地址:http://download.csdn.net/download/morewindows/6793027

 

[cpp] view plain copy

  1. <code class="language-cpp">// 【MoreWindows工作笔记12】WM_DRAWCLIPBOARD 监视剪切板  
  2. // http://blog.csdn.net/morewindows/article/details/17655429  
  3. // By MoreWindows( http://blog.csdn.net/MoreWindows )  
  4. BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)  
  5. {  
  6.   static HWND s_hwnd_new_clipboard_viewer = NULL;  
  7.   static HWND s_hwnd_edit_clipboard_info = NULL;  
  8.   
  9.     switch (message)  
  10.     {  
  11.     case WM_INITDIALOG:  
  12.     // 4-1 Add the window to the clipboard viewer chain.   
  13.     s_hwnd_new_clipboard_viewer = SetClipboardViewer(hDlg);  
  14.     // 把hwnd加入监视链,返回上一个加入的窗口句柄,如果是第一个,则返回值为NULL。新加的窗口在链条头部,成为“当前监视器”  
  15.         CenterWindow(hDlg);  
  16.     s_hwnd_edit_clipboard_info = GetDlgItem(hDlg, IDC_EDIT_CLIPBOARD_INFO);  
  17.         return FALSE;  
  18.   
  19.   // 4-2 Process the WM_CHANGECBCHAIN message.   
  20.   case WM_CHANGECBCHAIN:  
  21.     if ((HWND)wParam == s_hwnd_new_clipboard_viewer)  
  22.       s_hwnd_new_clipboard_viewer = (HWND)lParam;  
  23.     else  
  24.       SendMessage(s_hwnd_new_clipboard_viewer, message, wParam, lParam);  
  25.   
  26.   // 4-3 Process the WM_DRAWCLIPBOARD message.   
  27.   case WM_DRAWCLIPBOARD:  //剪切板内容发生变化  
  28.     if (OpenClipboard(hDlg)) {  
  29.       UINT clipboard_format = EnumClipboardFormats(0);  
  30.       HGLOBAL global_memory = GetClipboardData(clipboard_format);  
  31.       DWORD data_size = GlobalSize(global_memory);  
  32.       CloseClipboard();  
  33.       WCHAR clipboard_info[1024];  
  34.       swprintf(clipboard_info, L"Clipboard\r\n Data Format = %x\r\n Data Address = 0x%x\r\n Data Size = %d", clipboard_format, global_memory, data_size);  
  35.       if (clipboard_format == CF_UNICODETEXT) {  
  36.         LPCWSTR clipboard_data = (LPCWSTR)GlobalLock(global_memory);  
  37.         if (clipboard_data != NULL) {  
  38.           wcscat(clipboard_info, L"\r\nData: \r\n");  
  39.           WCHAR buffer[1024];  
  40.           DWORD data_size = GlobalSize(global_memory);  
  41.           for (size_t i = 0; i < data_size; i++)  
  42.             buffer[i] = clipboard_data[i];  
  43.           buffer[data_size] = L'\0';  
  44.           wcscat(clipboard_info, buffer);  
  45.         }  
  46.       }  
  47.       SetWindowTextW(s_hwnd_edit_clipboard_info, clipboard_info);  
  48.     }  
  49.     return FALSE;  
  50.   
  51.     case WM_COMMAND:  
  52.         switch (LOWORD(wParam))  
  53.         {  
  54.         case IDOK:  
  55.         case IDCANCEL:  
  56.       // 4-4 Remove the window from the clipboard viewer chain before it is destroyed.   
  57.       ChangeClipboardChain(hDlg, s_hwnd_new_clipboard_viewer);  
  58.             EndDialog(hDlg, FALSE);  
  59.             return TRUE;  
  60.         }  
  61.         break;  
  62.     }  
  63.     return FALSE;  
  64. }</code>  

 

运行程序,复制《【霍比特人2:史矛革之战】》的下载链接,然后程序会显示:

 

 

最后再列一下目录,方便大家查看。

1.《【MoreWindows工作笔记9】OleGetClipboard 访问剪切板的文本内容》

http://blog.csdn.net/morewindows/article/details/17655053

2.《【MoreWindows工作笔记10】OleGetClipboard 访问剪切板上的文件信息》

http://blog.csdn.net/morewindows/article/details/17655057

3.《【MoreWindows工作笔记11】EnumClipboardFormats剪切板内容的数据格式》

http://blog.csdn.net/morewindows/article/details/17655299

4.《【MoreWindows工作笔记12】WM_DRAWCLIPBOARD 监视剪切板》

http://blog.csdn.net/morewindows/article/details/17655429

 

from:https://blog.csdn.net/morewindows/article/details/17655429/ chang e c b chai n

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值