Compartir a través de


[Sample of Mar 7th] Monitor Windows Clipboard Changes in WPF

 

Homepage image
Sample of the Day RSS Feed

Sample download
C# version:
https://code.msdn.microsoft.com/CSWPFClipboardViewer-f601b815 
VB version:
https://code.msdn.microsoft.com/VBWPFClipboardViewer-d3f3cbd3

imageToday’s code sample demonstrates how to monitor Windows clipboard changes in a WPF application. In order to be notified by the system when the clipboard content changes, an application must use the SetClipboardViewer function (user32.dll) to add its window into the chain of clipboard viewers. Clipboard viewer windows receive a WM_DRAWCLIPBOARD message whenever the content of the clipboard changes. And the WM_CHANGECBCHAIN message is sent to the first window in the clipboard viewer chain when a window is being removed from the chain. In a WPF application, we use HwndSource class to register a Win32 window message handler to process the messages. This sample also shows a workaround for a known issue in WPF Clipboard.GetImage() method.

The sample was written by our star sample writer: Jie Wang.

imageYou can find more code samples that demonstrate the most typical programming scenarios by using Microsoft All-In-One Code Framework Sample Browser or Sample Browser Visual Studio extension. They give you the flexibility to search samples, download samples on demand, manage the downloaded samples in a centralized place, and automatically be notified about sample updates. If it is the first time that you hear about Microsoft All-In-One Code Framework, please watch the introduction video on Microsoft Showcase, or read the introduction on our homepage https://1code.codeplex.com/.

 

Introduction

This Sample demonstrates how to monitor Windows clipboard changes in a WPF application. In order to be notified by the system when the clipboard content changes, an application must use the SetClipboardViewer function (user32.dll) to add its window into the chain of clipboard viewers. Clipboard viewer windows receive a WM_DRAWCLIPBOARD message whenever the content of the clipboard changes. And the WM_CHANGECBCHAIN message is sent to the first window in the clipboard viewer chain when a window is being removed from the chain. In a WPF application, we use HwndSource class to register a Win32 window message handler to process the messages. This sample also shows a workaround for a known issue in WPF Clipboard.GetImage() method.

 

Running the Sample

Press F5 to run this application, you will see following result.

image

 

Using the Code

Gets the window handle for a Windows Presentation Foundation (WPF).

Adds an event handler to handle the clipboard message.

         private void InitCBViewer() 
        { 
            WindowInteropHelper wih = new WindowInteropHelper(this); 
            hWndSource = HwndSource.FromHwnd(wih.Handle); 
 
            hWndSource.AddHook(this.WinProc);   // start processing window messages 
            hWndNextViewer = Win32.SetClipboardViewer(hWndSource.Handle);   // set this window as a viewer 
            isViewing = true; 
        } 
         private IntPtr WinProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
        { 
            switch (msg) 
            { 
                case Win32.WM_CHANGECBCHAIN: 
                    if (wParam == hWndNextViewer) 
                    { 
                        // clipboard viewer chain changed, need to fix it. 
                        hWndNextViewer = lParam; 
                    } 
                    else if (hWndNextViewer != IntPtr.Zero) 
                    { 
                        // pass the message to the next viewer. 
                        Win32.SendMessage(hWndNextViewer, msg, wParam, lParam); 
                    } 
                    break; 
 
                case Win32.WM_DRAWCLIPBOARD: 
                    // clipboard content changed 
                    this.DrawContent(); 
                    // pass the message to the next viewer. 
                    Win32.SendMessage(hWndNextViewer, msg, wParam, lParam); 
                    break; 
            } 
 
            return IntPtr.Zero; 
        } 

Draw content in the window

         private void DrawContent() 
        { 
            pnlContent.Children.Clear(); 
 
            if (Clipboard.ContainsText()) 
            { 
                // we have some text in the clipboard. 
                TextBox tb = new TextBox(); 
                tb.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; 
                tb.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; 
                tb.Text = Clipboard.GetText(); 
                tb.IsReadOnly = true; 
                tb.TextWrapping = TextWrapping.NoWrap; 
                pnlContent.Children.Add(tb); 
            } 
            else if (Clipboard.ContainsFileDropList()) 
            { 
                // we have a file drop list in the clipboard 
                ListBox lb = new ListBox(); 
                lb.ItemsSource = Clipboard.GetFileDropList(); 
                pnlContent.Children.Add(lb); 
            } 
            else if (Clipboard.ContainsImage()) 
            { 
                // Because of a known issue in WPF, 
                // we have to use a workaround to get correct 
                // image that can be displayed. 
                // The image have to be saved to a stream and then 
                // read out to workaround the issue. 
                MemoryStream ms = new MemoryStream(); 
                BmpBitmapEncoder enc = new BmpBitmapEncoder(); 
                enc.Frames.Add(BitmapFrame.Create(Clipboard.GetImage())); 
                enc.Save(ms); 
                ms.Seek(0, SeekOrigin.Begin); 
 
                BmpBitmapDecoder dec = new BmpBitmapDecoder(ms, 
                    BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); 
 
                Image img = new Image(); 
                img.Stretch = Stretch.Uniform; 
                img.Source = dec.Frames[0]; 
                pnlContent.Children.Add(img); 
            } 
            else 
            { 
                Label lb = new Label(); 
                lb.Content = "The type of the data in the clipboard is not supported by this sample."; 
                pnlContent.Children.Add(lb); 
            } 
        } 

 

More Information

Clipboard

Clipboard Class (System.Windows)