2013-11-20 43 views
-1

我认为我的剪贴板错了,但我想知道或得到一个提示,我将需要实现这一点。我希望这个程序在后台运行,并且每次我都复制它在程序中结束的时候。那样,如果我想回去看看我10分钟前复制的内容,我会在程序中找到它。所以我想我需要将它保存在一个文本文件中。我如何实现这个?按ctrl + c并将其保存到texbox

+2

这个问题是如此混乱:)))删除它自己是最好的方式,第二个最好的方法是尝试改进它。 –

+0

该程序将不得不持续轮询剪贴板中的内容。它也必须为非文本内容做好准备。应该是可以的。 –

+0

签出一些已经这样做的开源程序:http://ditto-cp.sourceforge.net/ –

回答

1

C#在剪贴板更改时通常无法引发事件。您可以从剪贴板读取数据,并且可以忙于等待轮询剪贴板,但这些对我来说似乎并非最佳。

但是,有一点extern用法,你应该能够得到你想要的。在一类的子类Form

/// <summary> 
/// Message id for data being copied to the clipboard 
/// </summary> 
/// <value>776</value> 
private const int WM_DRAWCLIPBOARD = 0x0308; 
/// <summary> 
/// Message id for a window being removed from the viewer chain 
/// </summary> 
/// <value>781</value> 
private const int WM_CHANGECBCHAIN = 0x030D; 
/// <summary> 
/// Message id for the window being destroyed 
/// </summary> 
/// <value>2</value> 
private const int WM_DESTROY = 0x0002; 
/// <summary> 
/// The next window in the clipboard viewer chain 
/// </summary> 
private IntPtr nextClipboardViewer; 

/// <summary> 
/// Adds the specified window to the chain of clipboard viewers. Clipboard viewer windows receive a <c>WM_DRAWCLIPBOARD</c> 
/// message whenever the content of the clipboard changes. 
/// </summary> 
/// <param name="hWnd">A handle to the window to be added to the clipboard chain.</param> 
/// <returns>If the function succeeds, the return value identifies the next window in the clipboard viewer chain. If an 
/// error occurs or there are no other windows in the clipboard viewer chain, the return value is <c>null</c>.</returns> 
[DllImport("User32.dll", CharSet = CharSet.Auto)] 
public static extern IntPtr SetClipboardViewer(IntPtr hWnd); 
/// <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 
/// <see cref="SetClipboardViewer"/> function.</param> 
/// <param name="hWndNewNext">A handle to the window that follows the <paramref name="hWndRemove"/> window in the clipboard 
/// viewer chain. (This is the handle returned by <see cref="SetClipboardViewer"/>, unless the sequence was changed in response 
/// to a <c>WM_CHANGECBCHAIN</c> message.)</param> 
/// <returns>The return value indicates the result of passing the <c>WM_CHANGECBCHAIN</c> message to the windows in the 
/// clipboard viewer chain. Because a window in the chain typically returns <c>false</c> when it processes <c>WM_CHANGECBCHAIN</c>, 
/// the return value from <see cref="ChangeClipboardChain"/> is typically <c>false</c>. If there is only one window in the chain, 
/// the return value is typically <c>true</c>.</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 <c>SendMessage</c> function calls the window 
/// procedure for the specified window and does not return until the window procedure has processed the message. 
/// </summary> 
/// <param name="hwnd">A handle to the window whose window procedure will receive the message.</param> 
/// <param name="wMsg">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 wMsg, IntPtr wParam, IntPtr lParam); 

/// <inheritdoc/> 
protected override void WndProc(ref Message m) 
{ 
    if (m.Msg == WM_DRAWCLIPBOARD) 
    { 
     // The user copied something to the clipboard 
     IDataObject clipData = Clipboard.GetDataObject(); 
     if (clipData.GetDataPresent(DataFormats.Text)) 
     { 
      // Copied data is text 
     } 

     SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam); 
    } 
    // Handle necessary native clipboard stuff 
    else if (m.Msg == WM_DESTROY) 
    { 
     // Remove MyForm from the clipboard chain 
     ChangeClipboardChain(this.Handle, nextClipboardViewer); 
    } 
    else if (m.Msg == WM_CHANGECBCHAIN) 
    { 
     if (m.WParam == nextClipboardViewer) 
     { 
      nextClipboardViewer = m.LParam; 
     } 
     else 
     { 
      SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam); 
     } 
    } 
    else 
    { 
     base.WndProc(ref m); 
    } 
} 

private void MyForm_Load(object sender, EventArgs e) 
{ 
    // Include MyForm in the clipboard chain 
    nextClipboardViewer = SetClipboardViewer(this.Handle); 
} 

确保MyForm_Load添加为(从设计器窗口最容易)的Form相应事件。

+1

只是一个小纸条。您可以通过在WndProc()中捕获WM_DESTROY来消除订阅FormClosing()事件的需要,并从那里的链中删除自己。 –

+0

很高兴知道!我承认,我从我写的现有应用程序中提取这些代码,删除无关位。在我的应用程序中,我正在'_Load'和'_FormClosing' _anyway_中执行其他操作。 WM_DESTROY的价值是什么? –

+0

'私人const int WM_DESTROY = 0x2;' –

相关问题