using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Management; using System.Reflection; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Windows.Forms; using Microsoft.Office.Core; using Microsoft.Win32; using Excel = Microsoft.Office.Interop.Excel; using PowerPoint = Microsoft.Office.Interop.PowerPoint; using Word = Microsoft.Office.Interop.Word; using Microsoft.Web.WebView2.Core; using System.Runtime.InteropServices.ComTypes; namespace RobvanderWoude { public partial class FormMonitorClipboard : Form { static readonly string progver = "4.00"; #region Global Variables static string clipboardtext = string.Empty; static string gsexec = string.Empty; static readonly string title = string.Format( "MonitorClipboard, Version {0}", progver ); static string errormessage = string.Empty; static bool debugmode = false; static bool modalwindow = true; static bool compactmode = false; static float fontsizefactor = 1F; static int interval = 1; static int[] highestversion = new int[] { 0, 0, 0, 0 }; static readonly bool isExcelInstalled = ( Type.GetTypeFromProgID( "Excel.Application" ) != null ); static readonly bool isGhostScriptInstalled = CheckIfGhostScriptIsInstalled( ); static readonly bool isPowerPointInstalled = ( Type.GetTypeFromProgID( "PowerPoint.Application" ) != null ); static readonly bool isWordInstalled = ( Type.GetTypeFromProgID( "Word.Application" ) != null ); static bool isRedirected = false; static List tempfiles = new List( ); static List tempdirs = new List( ); #endregion Global Variables public FormMonitorClipboard( ) { InitializeComponent( ); // Code to hide menu bar in WebViw2 by jpine // https://stackoverflow.com/a/74018241 webView2ClipboardContent.CoreWebView2InitializationCompleted += ( sender, e ) => { if ( e.IsSuccess ) { webView2ClipboardContent.CoreWebView2.Settings.HiddenPdfToolbarItems = CoreWebView2PdfToolbarItems.Bookmarks | CoreWebView2PdfToolbarItems.FitPage | CoreWebView2PdfToolbarItems.PageLayout | CoreWebView2PdfToolbarItems.PageSelector | CoreWebView2PdfToolbarItems.Print | CoreWebView2PdfToolbarItems.Rotate | CoreWebView2PdfToolbarItems.Save | CoreWebView2PdfToolbarItems.SaveAs | CoreWebView2PdfToolbarItems.Search | CoreWebView2PdfToolbarItems.ZoomIn | CoreWebView2PdfToolbarItems.ZoomOut; } }; } private void FormMonitorClipboard_Load( object sender, EventArgs e ) { // https://www.csharp411.com/console-output-from-winforms-application/ // redirect console output to parent process; // must be before any calls to Console.WriteLine( ) AttachConsole( ATTACH_PARENT_PROCESS ); Text = title; ParseCommandLine( ); if ( debugmode ) { DebugInfo( ); modalwindow = false; } if ( compactmode ) { CompactWindow( ); } CheckClipboard( ); TopMost = modalwindow; ClipboardNotification.ClipboardUpdate += ClipboardNotification_ClipboardUpdate; } private void ChangeViewerType( ViewerType viewerwindow ) { pictureBoxClipboardContent.Visible = ( viewerwindow == ViewerType.Picture ); richTextBoxClipboardContent.Visible = ( viewerwindow == ViewerType.RichText ); textBoxClipboardContent.Visible = ( viewerwindow == ViewerType.Text ); webView2ClipboardContent.Visible = ( viewerwindow == ViewerType.Web ); labelFilename.Visible = ( viewerwindow != ViewerType.Text ); switch ( viewerwindow ) { case ViewerType.Picture: richTextBoxClipboardContent.Text = null; textBoxClipboardContent.Text = null; webView2ClipboardContent.SendToBack( ); pictureBoxClipboardContent.BringToFront( ); break; case ViewerType.RichText: pictureBoxClipboardContent.Image = null; textBoxClipboardContent.Text = null; webView2ClipboardContent.SendToBack( ); richTextBoxClipboardContent.BringToFront( ); break; case ViewerType.Text: pictureBoxClipboardContent.Image = null; richTextBoxClipboardContent.Text = null; webView2ClipboardContent.SendToBack( ); textBoxClipboardContent.BringToFront( ); break; case ViewerType.Web: pictureBoxClipboardContent.Image = null; richTextBoxClipboardContent.Text = null; textBoxClipboardContent.Text = null; webView2ClipboardContent.BringToFront( ); break; } } private void CheckClipboard( ) { labelFilename.Text = null; if ( Clipboard.ContainsText( ) ) { ChangeViewerType( ViewerType.Text ); clipboardtext = Clipboard.GetText( TextDataFormat.UnicodeText ); textBoxClipboardContent.BackColor = Color.White; textBoxClipboardContent.ForeColor = Color.Black; textBoxClipboardContent.Text = clipboardtext; } else if ( Clipboard.ContainsImage( ) ) { ChangeViewerType( ViewerType.Picture ); pictureBoxClipboardContent.Image = Clipboard.GetImage( ); } else if ( Clipboard.GetFileDropList( ) != null ) { bool success = false; if ( Clipboard.GetFileDropList( ).Count == 1 ) { success = Preview( Clipboard.GetFileDropList( )[0] ); } if ( !success ) { ChangeViewerType( ViewerType.Text ); textBoxClipboardContent.Text = null; textBoxClipboardContent.BringToFront( ); labelFilename.Text = null; labelFilename.Visible = false; List files = new List( ); List folders = new List( ); foreach ( var file in Clipboard.GetFileDropList( ) ) { if ( Directory.Exists( file ) ) { folders.Add( file ); } else { files.Add( file ); } } if ( folders.Count > 0 ) { folders.Sort( ); textBoxClipboardContent.Text = "Folders:" + Environment.NewLine + string.Join( Environment.NewLine, folders ) + Environment.NewLine + Environment.NewLine; } if ( files.Count > 0 ) { files.Sort( ); textBoxClipboardContent.Text += "Files:" + Environment.NewLine + string.Join( Environment.NewLine, files ); } } } else { ChangeViewerType( ViewerType.Picture ); textBoxClipboardContent.BackColor = Form.DefaultBackColor; textBoxClipboardContent.ForeColor = Color.Gray; textBoxClipboardContent.Text = string.Join( Environment.NewLine, Clipboard.GetDataObject( ).GetFormats( ).ToArray( ) ); // requires Linq } textBoxClipboardContent.SelectionStart = 0; textBoxClipboardContent.SelectionLength = 0; } static bool CheckIfGhostScriptIsInstalled( ) { string gspath; if ( Win3264( ) == 64 ) { gspath = SearchPath( "gswin64c.exe" ); if ( !string.IsNullOrWhiteSpace( gspath ) ) { gsexec = gspath; return true; } } gspath = SearchPath( "gswin32c.exe" ); if ( !string.IsNullOrWhiteSpace( gspath ) ) { gsexec = gspath; return true; } RegistryKey uninstallKey = Registry.LocalMachine.OpenSubKey( @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" ); var programs = uninstallKey.GetSubKeyNames( ); foreach ( var program in programs ) { if ( program.ToLower( ).Contains( "ghostscript" ) ) { RegistryKey subkey = uninstallKey.OpenSubKey( program ); string uninstallstring = subkey.GetValue( "UninstallString" ).ToString( ); subkey.Close( ); if ( !string.IsNullOrWhiteSpace( uninstallstring ) ) { if ( File.Exists( Path.GetDirectoryName( uninstallstring ) + @"\bin\gswin64.exe" ) ) { gsexec = Path.GetDirectoryName( uninstallstring ) + @"\bin\gswin64.exe"; } else if ( File.Exists( Path.GetDirectoryName( uninstallstring ) + @"\bin\gswin32.exe" ) ) { gsexec = Path.GetDirectoryName( uninstallstring ) + @"\bin\gswin32.exe"; } break; } } } uninstallKey.Close( ); if ( !string.IsNullOrWhiteSpace( gsexec ) ) { return true; } if ( Win3264( ) == 64 ) { uninstallKey = Registry.LocalMachine.OpenSubKey( @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" ); programs = uninstallKey.GetSubKeyNames( ); foreach ( var program in programs ) { if ( program.ToLower( ).Contains( "ghostscript" ) ) { RegistryKey subkey = uninstallKey.OpenSubKey( program ); string uninstallstring = subkey.GetValue( "UninstallString" ).ToString( ); subkey.Close( ); if ( !string.IsNullOrWhiteSpace( uninstallstring ) ) { if ( File.Exists( Path.GetDirectoryName( uninstallstring ) + @"\bin\gswin32.exe" ) ) { gsexec = Path.GetDirectoryName( uninstallstring ) + @"\bin\gswin32.exe"; } break; } } } uninstallKey.Close( ); } return string.IsNullOrWhiteSpace( gsexec ); } private void CompactWindow( ) { this.ClientSize = new Size( (int)( Screen.PrimaryScreen.Bounds.Width / 2 ), 40 ); this.Location = new System.Drawing.Point( (int)( Screen.PrimaryScreen.Bounds.Width / 4 ), Screen.PrimaryScreen.Bounds.Height - 40 ); this.TopLevel = true; this.ControlBox = false; this.Text = string.Empty; this.FormBorderStyle = FormBorderStyle.None; textBoxClipboardContent.Size = new Size( this.ClientSize.Width - 40, this.ClientSize.Height ); textBoxClipboardContent.Location = new System.Drawing.Point( 0, 0 ); textBoxClipboardContent.Font = new System.Drawing.Font( textBoxClipboardContent.Font.FontFamily, (float)( textBoxClipboardContent.Font.Size * fontsizefactor ), FontStyle.Regular ); Button exitbutton = new Button { Text = "Exit", Size = new Size( 32, 32 ), Location = new System.Drawing.Point( this.ClientSize.Width - 36, 4 ) }; exitbutton.Click += Exitbutton_Click; this.Controls.Add( exitbutton ); } private void DebugInfo( ) { string programpath = System.Windows.Forms.Application.ExecutablePath; string[] arguments = Environment.GetCommandLineArgs( ).Skip( 1 ).ToArray( ); // requires Linq string installednetframework = GetInstalledNETFrameworkVersion( ); string requirednetframework = GetRequiredNETFrameworkVersion( ); string debuginfo = string.Format( "DEBUGGING INFO:{0}==============={0}Program path : {1}{0}Required .NET version : {2}{0}Installed .NET version : {3}{0}Command line arguments : {4}{0}Timer interval : {5}{0}Modal window : {6}", System.Environment.NewLine, programpath, requirednetframework, installednetframework, string.Join( " ", arguments ), interval, modalwindow ); Clipboard.SetText( debuginfo ); } private string Excel2PDF( string excelfile ) { if ( !isExcelInstalled ) { return null; } string pdffile = Path.GetTempFileName( ) + ".pdf"; if ( pdffile != null ) { tempfiles.Add( pdffile ); Excel.Application excelapp = null; Excel.Workbook workbook = null; try { excelapp = new Excel.Application { Visible = false }; object updatelinks = true; object openreadonly = true; workbook = excelapp.Workbooks.Open( excelfile, updatelinks, openreadonly ); Excel.Worksheet sheet = (Excel.Worksheet)workbook.Worksheets[1]; sheet.ExportAsFixedFormat( Excel.XlFixedFormatType.xlTypePDF, pdffile ); } catch ( Exception ex ) { MessageBox.Show( ex.Message + "\n\n" + ex.StackTrace ); } finally { workbook?.Close( ); excelapp?.Quit( ); } } return pdffile; } private string GetInstalledNETFrameworkVersion( ) { string rc = string.Empty; System.Collections.Generic.List installedversions = new System.Collections.Generic.List( ); // Get the list of installed .NET Framework versions from the registry, by Microsoft: // https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed using ( RegistryKey ndpKey = RegistryKey.OpenRemoteBaseKey( RegistryHive.LocalMachine, "" ).OpenSubKey( @"SOFTWARE\Microsoft\NET Framework Setup\NDP\" ) ) { foreach ( string versionKeyName in ndpKey.GetSubKeyNames( ) ) { if ( versionKeyName.StartsWith( "v" ) ) { RegistryKey versionKey = ndpKey.OpenSubKey( versionKeyName ); string name = (string) versionKey.GetValue( "Version", "" ); if ( name == "" ) { foreach ( string subKeyName in versionKey.GetSubKeyNames( ) ) { RegistryKey subKey = versionKey.OpenSubKey( subKeyName ); name = (string) subKey.GetValue( "Version", "" ); if ( name != "" ) { installedversions.Add( name ); } } } else { installedversions.Add( name ); } } } } // Determine the highest version foreach ( string version in installedversions ) { highestversion = HighestVersion( highestversion, version ); } return string.Join( ".", highestversion.Select( x => x.ToString( ) ).ToArray( ) ); // requires System.Linq } static string GetRequiredNETFrameworkVersion( ) { // Get the required .NET Framework version // By Fernando Gonzalez Sanchez on StackOverflow.com // https://stackoverflow.com/a/18623516 object[] list = Assembly.GetExecutingAssembly( ).GetCustomAttributes( true ); var attribute = list.OfType( ).First( ); // requires Linq //string frameworkname = attribute.FrameworkName; string frameworkdisplayname = attribute.FrameworkDisplayName; return frameworkdisplayname; } static int[] HighestVersion( int[] version1, string version2 ) { int[] converted2 = version2.Split( ".".ToCharArray( ) ).Select( x => System.Convert.ToInt32( x ) ).ToArray( ); int minlength = Math.Min( version1.Length, converted2.Length ); for ( int i = 0; i < minlength; i++ ) { if ( version1[i] > converted2[i] ) { return version1; } else if ( version1[i] < converted2[i] ) { return converted2; } } return version1; } private void ParseCommandLine( ) { isRedirected = ( Console.IsOutputRedirected || Console.IsErrorRedirected ); string[] arguments = Environment.GetCommandLineArgs( ).Skip( 1 ).ToArray( ); // requires Linq foreach ( string argument in arguments ) { string clswitch = argument.Split( ":=".ToCharArray( ) )[0].ToUpper( ); string clval = ( argument.IndexOfAny( ":=".ToCharArray( ) ) > 0 ? argument.Split( ":=".ToCharArray( ) )[1] : string.Empty ); switch ( clswitch ) { case "/CM": compactmode = true; break; case "/D": case "/DEBUG": debugmode = true; break; case "/F": int fontsizepercentage = 100; if ( !int.TryParse( clval, out fontsizepercentage ) ) { errormessage = string.Format( "Invalid font size percentage: {0}", argument ); ShowHelp( ); } else if ( fontsizepercentage < 50 || fontsizepercentage > 150 ) { errormessage = string.Format( "Font size percentage out of range (50..150): {0}", argument ); ShowHelp( ); } else { fontsizefactor = fontsizepercentage / 100F; } break; case "/NM": modalwindow = false; break; case "/?": ShowHelp( ); break; default: errormessage = string.Format( "Invalid argument: {0}", argument ); ShowHelp( ); break; } } } private string PPT2JPG( string pptfile ) { if ( !isPowerPointInstalled ) { return null; } string jpgfile = Path.GetTempFileName( ) + ".jpg"; tempfiles.Add( jpgfile ); PowerPoint.Application pptapp = new PowerPoint.Application( ); try { PowerPoint.Slide slide = pptapp.Presentations.Open( pptfile, MsoTriState.msoTrue, MsoTriState.msoFalse, MsoTriState.msoFalse ).Slides[1]; slide.Export( jpgfile, "JPG" ); } catch { jpgfile = null; } finally { pptapp.Quit( ); } return jpgfile; } private bool Preview( string filename ) { labelFilename.Location = new System.Drawing.Point( 12, 325 ); labelFilename.Width = textBoxClipboardContent.Width; labelFilename.Height = 30; labelFilename.TextAlign = ContentAlignment.MiddleCenter; labelFilename.BackColor = Color.Transparent; labelFilename.Visible = false; string tempfile; bool result = true; switch ( Path.GetExtension( filename ).ToLower( ) ) { case ".ini": case ".log": case ".txt": ChangeViewerType( ViewerType.Text ); textBoxClipboardContent.Text = File.ReadAllText( filename ); ShowLabel( filename ); break; case ".htm": case ".html": case ".pdf": case ".php": case ".xhtml": ChangeViewerType( ViewerType.Web ); webView2ClipboardContent.Source = new Uri( filename ); ShowLabel( filename ); break; case ".bmp": case ".gif": case ".jpg": case ".jpeg": case ".png": case ".tif": case ".tiff": ChangeViewerType( ViewerType.Picture ); pictureBoxClipboardContent.Image = Image.FromFile( filename ); ShowLabel( filename ); break; case ".mp3": case ".mp4": case ".webp": ChangeViewerType( ViewerType.Web ); webView2ClipboardContent.Source = new Uri( filename ); ShowLabel( filename ); break; case ".epub": string tempdir = Path.Combine( Environment.GetEnvironmentVariable( "Temp" ), Path.GetFileNameWithoutExtension( filename ) ); if ( Directory.Exists( tempdir ) ) { Directory.Delete( tempdir, true ); } else { Directory.CreateDirectory( tempdir ); } tempdirs.Add( tempdir ); System.IO.Compression.ZipFile.ExtractToDirectory( filename, tempdir ); string cover = Directory.GetFiles( tempdir, "cover.jpg", SearchOption.AllDirectories ).FirstOrDefault( ); if ( !File.Exists( cover ) ) { cover = Directory.GetFiles( tempdir, "cover.jpeg", SearchOption.AllDirectories ).FirstOrDefault( ); } if ( File.Exists( cover ) ) { tempfiles.Add( cover ); ChangeViewerType( ViewerType.Picture ); pictureBoxClipboardContent.Image = Image.FromFile( cover ); ShowLabel( filename ); } else { ChangeViewerType( ViewerType.Text ); textBoxClipboardContent.Text = "File:" + Environment.NewLine + filename; } break; case ".xls": case ".xlsx": case ".ods": tempfile = Excel2PDF( filename ); if ( tempfile == null ) { ChangeViewerType( ViewerType.Text ); textBoxClipboardContent.Text = "File:" + Environment.NewLine + filename; } else { tempfiles.Add( tempfile ); ChangeViewerType( ViewerType.Web ); webView2ClipboardContent.Source = new Uri( tempfile ); ShowLabel( filename ); } break; case ".doc": case ".docx": case ".odt": tempfile = Word2RTF( filename ); if ( tempfile == null ) { ChangeViewerType( ViewerType.Text ); textBoxClipboardContent.Text = "File:" + Environment.NewLine + filename; } else { tempfiles.Add( tempfile ); ChangeViewerType( ViewerType.RichText ); richTextBoxClipboardContent.Rtf = File.ReadAllText( tempfile, Encoding.UTF8 ); ShowLabel( filename ); } break; case ".pps": case ".ppsx": case ".ppt": case ".pptx": case ".odp": tempfile=PPT2JPG( filename ); if ( tempfile == null ) { ChangeViewerType( ViewerType.Text ); textBoxClipboardContent.Text = "File:" + Environment.NewLine + filename; } else { ChangeViewerType( ViewerType.Picture ); pictureBoxClipboardContent.Image = Image.FromFile( tempfile ); ShowLabel( filename ); } break; case ".rtf": ChangeViewerType( ViewerType.RichText ); richTextBoxClipboardContent.Rtf = File.ReadAllText( filename, Encoding.UTF8 ); ShowLabel( filename ); break; default: ChangeViewerType( ViewerType.Text ); result = false; break; } return result; } static string SearchPath( string execname ) { foreach(string folder in Environment.GetEnvironmentVariable("PATH").Split( ';' ) ) { if ( File.Exists( Path.Combine( folder, execname ) ) ) { return Path.Combine( folder, execname ); } } return null; } private void ShowHelp( ) { string message = string.Empty; if ( !string.IsNullOrWhiteSpace( errormessage ) ) { message += errormessage + "\n\n"; } message += title; message += "\nMonitor clipboard content in realtime\n\n"; message += "Usage: MONITORCLIPBOARD.EXE [ options ]\n\n"; message += "Options: /CM Compact Mode: small window over taskbar\n"; message += " (default: normal window at center of screen)\n"; message += " /F:perc Font size percentage (50..150; default: 100)\n"; message += " /NM sets the program's window to Non-Modal\n"; message += " (default: always on top)\n"; message += " /D Debug mode: send some debugging information\n"; message += " to the clipboard (warning: this will overwrite\n"; message += " the current clipboard content)\n\n"; message += "Notes: If the clipboard content is text or image, a preview will\n"; message += " be shown in the program window.\n"; message += " If the clipboard contains multiple files and/or folders,\n"; message += " the files and folders will be listed separately, sorted.\n"; message += " If the clipboard contains a single file, the program will\n"; message += " attempt to show a preview of the file's content, plus its path.\n"; message += " Supported file types are images, Microsoft Office and OpenOffice\n"; message += " text, spreadsheets and presentations, PDF and RTF.\n"; message += " These previews depend on software installed on the computer,\n"; message += " i.e. Microsoft Office and GhostScript.\n"; message += " if the required software is not found, the program will show\n"; message += " the file as a \"list of one file\".\n"; message += " Though invalid or duplicate arguments DO raise error\n"; message += " messages, they are ignored.\n\n"; message += "Credits: Clipboard changes notifications by Gert Lombard\n"; message += " https://gist.github.com/glombard/7986317\n"; message += " Console output from a WinForms program by Timm\n"; message += " https://www.csharp411.com/console-output-from-winforms-application/\n"; message += " Show text as RTF based on code by Wendy Zang\n"; message += " https://learn.microsoft.com/en-us/archive/msdn-technet-forums\n"; message += " /6e56af9b-d7d3-49f3-9ec4-80edde3fe54b#a64345e9-cfcb-43be-ab18-c08fae02cb2a\n"; message += " Hide menus in WebView2 viewer by jpine\n"; message += " https://stackoverflow.com/a/74018241\n\n"; message += "Written by Rob van der Woude\n"; message += "https://www.robvanderwoude.com"; Console.WriteLine( message ); Clipboard.SetText( message.Replace( "\n", Environment.NewLine ) ); } private void ShowLabel( string text ) { labelFilename.Text = text; labelFilename.Visible = true; labelFilename.BringToFront( ); } static int Win3264( ) { ManagementObjectSearcher searcher = new ManagementObjectSearcher( @"root\CIMV2", "SELECT * FROM Win32_Processor" ); foreach ( ManagementObject queryObj in searcher.Get( ).Cast( ) ) { return (int)(UInt16)( queryObj["AddressWidth"] ); } return 0; } private string Word2RTF( string filename ) { if(!isWordInstalled) { return null; } string rtffile = Path.GetTempFileName( ) + ".rtf"; tempfiles.Add( rtffile ); Word.Application wordapp = new Word.Application( ); object savechanges = Word.WdSaveOptions.wdDoNotSaveChanges; try { wordapp.Visible = false; Word.Document worddoc = wordapp.Documents.Open( filename ); worddoc.SaveAs2( rtffile, Word.WdSaveFormat.wdFormatRTF ); worddoc.Close( savechanges ); } finally { wordapp.Quit( savechanges ); } return rtffile; } private void ClipboardNotification_ClipboardUpdate( object sender, EventArgs e ) { CheckClipboard( ); } private void Exitbutton_Click( object sender, EventArgs e ) { System.Windows.Forms.Application.Exit( ); } private void FormMonitorClipboard_FormClosing( object sender, FormClosingEventArgs e ) { pictureBoxClipboardContent.Image = null; pictureBoxClipboardContent.Dispose( ); richTextBoxClipboardContent.Text = null; richTextBoxClipboardContent.Dispose( ); textBoxClipboardContent.Text = null; textBoxClipboardContent.Dispose( ); webView2ClipboardContent.Dispose( ); foreach ( string tempfile in tempfiles ) { try { File.Delete( tempfile ); } catch { // ignore } } foreach ( string tempdir in tempdirs ) { try { Directory.Delete( tempdir, true ); } catch { // ignore } } } private void FormMonitorClipboard_HelpRequested( object sender, HelpEventArgs hlpevent ) { ShowHelp( ); } [DllImport( "kernel32.dll" )] static extern bool AttachConsole( int dwProcessId ); private const int ATTACH_PARENT_PROCESS = -1; #region Clipboard Changes Notification // Code by Gert Lombard on https://gist.github.com/glombard/7986317 /// /// Provides notifications when the contents of the clipboard is updated. /// public sealed class ClipboardNotification { /// /// Occurs when the contents of the clipboard is updated. /// public static event EventHandler ClipboardUpdate; private static NotificationForm _form = new NotificationForm( ); /// /// Raises the event. /// /// Event arguments for the event. private static void OnClipboardUpdate( EventArgs e ) { var handler = ClipboardUpdate; if ( handler != null ) { handler( null, e ); } } /// /// Hidden form to recieve the WM_CLIPBOARDUPDATE message. /// private class NotificationForm : Form { public NotificationForm( ) { NativeMethods.SetParent( Handle, NativeMethods.HWND_MESSAGE ); NativeMethods.AddClipboardFormatListener( Handle ); } protected override void WndProc( ref Message m ) { if ( m.Msg == NativeMethods.WM_CLIPBOARDUPDATE ) { OnClipboardUpdate( null ); } base.WndProc( ref m ); } } } internal static class NativeMethods { // See http://msdn.microsoft.com/en-us/library/ms649021%28v=vs.85%29.aspx public const int WM_CLIPBOARDUPDATE = 0x031D; public static IntPtr HWND_MESSAGE = new IntPtr( -3 ); // See http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#message_only [DllImport( "user32.dll", SetLastError = true )] [return: MarshalAs( UnmanagedType.Bool )] public static extern bool AddClipboardFormatListener( IntPtr hwnd ); // See http://msdn.microsoft.com/en-us/library/ms633541%28v=vs.85%29.aspx // See http://msdn.microsoft.com/en-us/library/ms649033%28VS.85%29.aspx [DllImport( "user32.dll", SetLastError = true )] public static extern IntPtr SetParent( IntPtr hWndChild, IntPtr hWndNewParent ); } #endregion Clipboard Changes Notification } public enum ViewerType { Picture, RichText, Text, Web } }