/// <summary>
/// Adds the specified window to the chain of clipboard viewers. Clipboard viewer windows receive a WM_DRAWCLIPBOARD message whenever the content of the clipboard changes. This function is used for backward compatibility with earlier versions of Windows.
/// </summary>
/// <param name="hWndNewViewer">A handle to the window to be added to the clipboard chain.</param>
/// <returns></returns>
[DllImport("User32.dll")]
protected static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
/// <summary>
/// Removes a specified window from the chain of clipboard viewers.
/// </summary>
/// <param name="hWndRemove">A handle to the window to be removed from the chain. The handle must have been passed to the SetClipboardViewer function.</param>
/// <param name="hWndNewNext">A handle to the window that follows the hWndRemove window in the clipboard viewer chain. (This is the handle returned by SetClipboardViewer, unless the sequence was changed in response to a WM_CHANGECBCHAIN message.)</param>
/// <returns>The return value indicates the result of passing the WM_CHANGECBCHAIN message to the windows in the clipboard viewer chain. Because a window in the chain typically returns FALSE when it processes WM_CHANGECBCHAIN, the return value from ChangeClipboardChain is typically FALSE. If there is only one window in the chain, the return value is typically TRUE.</returns>
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);
/// <summary>
/// Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.
/// To send a message and return immediately, use the SendMessageCallback or SendNotifyMessage function. To post a message to a thread's message queue and return immediately, use the PostMessage or PostThreadMessage function.
/// </summary>
/// <param name="hWnd">A handle to the window whose window procedure will receive the message. If this parameter is HWND_BROADCAST ((HWND)0xffff), the message is sent to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows.
/// Message sending is subject to UIPI. The thread of a process can send messages only to message queues of threads in processes of lesser or equal integrity level.</param>
/// <param name="Msg">The message to be sent.</param>
/// <param name="wParam">Additional message-specific information.</param>
/// <param name="lParam">Additional message-specific information.</param>
/// <returns>The return value specifies the result of the message processing; it depends on the message sent.</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
// defined in winuser.h
public const int WM_DRAWCLIPBOARD = 0x0308;//剪贴板内容发生变化时的消息
public const int WM_CHANGECBCHAIN = 0x030D;//维持剪贴板链的消息
IntPtr nextViewer;//句柄
public Form1()
{
InitializeComponent();
nextViewer = SetClipboardViewer(this.Handle);
}
protected override void WndProc(ref System.Windows.Forms.Message m)
{
//根据获取的消息决定操作方法
switch (m.Msg)
{
case WM_DRAWCLIPBOARD:
DisplayClipboardData();
SendMessage(nextViewer, m.Msg, m.WParam, m.LParam);
break;
case WM_CHANGECBCHAIN:
if (m.WParam == nextViewer)
nextViewer = m.LParam;
else
SendMessage(nextViewer, m.Msg, m.WParam, m.LParam);
break;
default:
base.WndProc(ref m);
break;
}
}
private void DisplayClipboardData()
{
IDataObject data = new DataObject();
data = Clipboard.GetDataObject();//获取剪贴板中的数据
if (data.GetDataPresent(DataFormats.Rtf))//判断格式是否相同
txtData.Rtf = (string)data.GetData(DataFormats.Rtf);
else if (data.GetDataPresent(DataFormats.Text))
txtData.Text = (string)data.GetData(DataFormats.Text);
else
txtData.Text = "剪贴板中的数据格式不可用";
}