剪贴板更改通知?

我知道如何把内容和剪贴板中的内容。

但是,在这两个操作之间,另一个操作可能会改变剪贴板的内容。

有什么方法可以在任何应用程序修改剪贴板时得到通知吗?

Solutions Collecting From Web of "剪贴板更改通知?"

所有我能找到的是用C#/ VB.NET编写的剪贴板监视器 。 我看到WPF和WinForms,所以我认为这是一个可行的选择。

涉及到禁止user32 DLL的一些方法。

我知道这个答案是晚了你需要添加的唯一参考是从你的wpf应用程序的窗口。 我创建了一个包装到我在互联网上找到的功能。 大部分的例子比我所需要的要多,所以我决定创建自己的类。 我喜欢隔离这些问题,所以这个类只是在剪贴板发生变化的时候侦听,并且告诉你剪贴板上的数据类型。 比如说是文字? 一个图像? 或者是什么?

反正这里是我的包装:

using System; using System.Windows.Forms; using System.Threading; using System.Runtime.InteropServices; public static class ClipboardMonitor { public delegate void OnClipboardChangeEventHandler(ClipboardFormat format, object data); public static event OnClipboardChangeEventHandler OnClipboardChange; public static void Start() { ClipboardWatcher.Start(); ClipboardWatcher.OnClipboardChange += (ClipboardFormat format, object data) => { if (OnClipboardChange != null) OnClipboardChange(format, data); }; } public static void Stop() { OnClipboardChange = null; ClipboardWatcher.Stop(); } class ClipboardWatcher : Form { // static instance of this form private static ClipboardWatcher mInstance; // needed to dispose this form static IntPtr nextClipboardViewer; public delegate void OnClipboardChangeEventHandler(ClipboardFormat format, object data); public static event OnClipboardChangeEventHandler OnClipboardChange; // start listening public static void Start() { // we can only have one instance if this class if (mInstance != null) return; Thread t = new Thread(new ParameterizedThreadStart(x => { Application.Run(new ClipboardWatcher()); })); t.SetApartmentState(ApartmentState.STA); // give the [STAThread] attribute t.Start(); } // stop listening (dispose form) public static void Stop() { mInstance.Invoke(new MethodInvoker(() => { ChangeClipboardChain(mInstance.Handle, nextClipboardViewer); })); mInstance.Invoke(new MethodInvoker(mInstance.Close)); mInstance.Dispose(); mInstance = null; } // on load: (hide this window) protected override void SetVisibleCore(bool value) { CreateHandle(); mInstance = this; nextClipboardViewer = SetClipboardViewer(mInstance.Handle); base.SetVisibleCore(false); } [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer); [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam); // defined in winuser.h const int WM_DRAWCLIPBOARD = 0x308; const int WM_CHANGECBCHAIN = 0x030D; protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_DRAWCLIPBOARD: ClipChanged(); 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; } } static readonly string[] formats = Enum.GetNames(typeof(ClipboardFormat)); private void ClipChanged() { IDataObject iData = Clipboard.GetDataObject(); ClipboardFormat? format = null; foreach (var f in formats) { if (iData.GetDataPresent(f)) { format = (ClipboardFormat)Enum.Parse(typeof(ClipboardFormat), f); break; } } object data = iData.GetData(format.ToString()); if (data == null || format == null) return; if (OnClipboardChange != null) OnClipboardChange((ClipboardFormat)format, data); } } } public enum ClipboardFormat : byte { /// <summary>Specifies the standard ANSI text format. This static field is read-only. /// </summary> /// <filterpriority>1</filterpriority> Text, /// <summary>Specifies the standard Windows Unicode text format. This static field /// is read-only.</summary> /// <filterpriority>1</filterpriority> UnicodeText, /// <summary>Specifies the Windows device-independent bitmap (DIB) format. This static /// field is read-only.</summary> /// <filterpriority>1</filterpriority> Dib, /// <summary>Specifies a Windows bitmap format. This static field is read-only.</summary> /// <filterpriority>1</filterpriority> Bitmap, /// <summary>Specifies the Windows enhanced metafile format. This static field is /// read-only.</summary> /// <filterpriority>1</filterpriority> EnhancedMetafile, /// <summary>Specifies the Windows metafile format, which Windows Forms does not /// directly use. This static field is read-only.</summary> /// <filterpriority>1</filterpriority> MetafilePict, /// <summary>Specifies the Windows symbolic link format, which Windows Forms does /// not directly use. This static field is read-only.</summary> /// <filterpriority>1</filterpriority> SymbolicLink, /// <summary>Specifies the Windows Data Interchange Format (DIF), which Windows Forms /// does not directly use. This static field is read-only.</summary> /// <filterpriority>1</filterpriority> Dif, /// <summary>Specifies the Tagged Image File Format (TIFF), which Windows Forms does /// not directly use. This static field is read-only.</summary> /// <filterpriority>1</filterpriority> Tiff, /// <summary>Specifies the standard Windows original equipment manufacturer (OEM) /// text format. This static field is read-only.</summary> /// <filterpriority>1</filterpriority> OemText, /// <summary>Specifies the Windows palette format. This static field is read-only. /// </summary> /// <filterpriority>1</filterpriority> Palette, /// <summary>Specifies the Windows pen data format, which consists of pen strokes /// for handwriting software, Windows Forms does not use this format. This static /// field is read-only.</summary> /// <filterpriority>1</filterpriority> PenData, /// <summary>Specifies the Resource Interchange File Format (RIFF) audio format, /// which Windows Forms does not directly use. This static field is read-only.</summary> /// <filterpriority>1</filterpriority> Riff, /// <summary>Specifies the wave audio format, which Windows Forms does not directly /// use. This static field is read-only.</summary> /// <filterpriority>1</filterpriority> WaveAudio, /// <summary>Specifies the Windows file drop format, which Windows Forms does not /// directly use. This static field is read-only.</summary> /// <filterpriority>1</filterpriority> FileDrop, /// <summary>Specifies the Windows culture format, which Windows Forms does not directly /// use. This static field is read-only.</summary> /// <filterpriority>1</filterpriority> Locale, /// <summary>Specifies text consisting of HTML data. This static field is read-only. /// </summary> /// <filterpriority>1</filterpriority> Html, /// <summary>Specifies text consisting of Rich Text Format (RTF) data. This static /// field is read-only.</summary> /// <filterpriority>1</filterpriority> Rtf, /// <summary>Specifies a comma-separated value (CSV) format, which is a common interchange /// format used by spreadsheets. This format is not used directly by Windows Forms. /// This static field is read-only.</summary> /// <filterpriority>1</filterpriority> CommaSeparatedValue, /// <summary>Specifies the Windows Forms string class format, which Windows Forms /// uses to store string objects. This static field is read-only.</summary> /// <filterpriority>1</filterpriority> StringFormat, /// <summary>Specifies a format that encapsulates any type of Windows Forms object. /// This static field is read-only.</summary> /// <filterpriority>1</filterpriority> Serializable, } 

我知道它可能是很多,但包装后它应该是这样的: 在这里输入图像说明

然后你使用这个类作为:

  static void Main(string[] args) { ClipboardMonitor.Start(); ClipboardMonitor.OnClipboardChange += new ClipboardMonitor.OnClipboardChangeEventHandler(ClipboardMonitor_OnClipboardChange); Console.Read(); ClipboardMonitor.Stop(); // do not forget to stop } static void ClipboardMonitor_OnClipboardChange(ClipboardFormat format, object data) { Console.WriteLine("Clipboard changed and it has the format: "+format.ToString()); } 

但是,在这两个操作之间,另一个操作可能会改变剪贴板的内容。

当应用程序调用OpenClipboard()时,其他应用程序不能使用剪贴板。 一旦锁定剪贴板的应用程序调用了CloseClipboard(),则任何应用程序都可以使用并锁定剪贴板。

有什么方法可以在任何应用程序修改剪贴板时得到通知吗?

是。 请参阅API SetClipboardViewer()和消息WM_DRAWCLIPBOARD和WM_CHANGECBCHAIN。

更多信息: http : //msdn.microsoft.com/en-us/library/ms649016(v=vs.85).aspx#_win32_Adding_a_Window_to_the_Clipboard_Viewer_Chain

下面是几年前我写的一篇文章,详细介绍剪贴板,甚至是通过Windows API进行监视: http : //www.clipboardextender.com/developing-clipboard-aware-programs-for-windows/6请特别注意到“常见错误”部分。 几乎没有人第一次正确地做到这一点。