That's a fun and useful little project. This worked well, I hope I got the chaining right. Drop a picturebox and a label on a form, then paste this code:
using System; using System.Windows.Forms;
namespace WindowsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.FormClosing += Form1_Closing; this.Load += Form1_Load; } private IntPtr mPrevViewer; private void Form1_Load(object sender, EventArgs e) { // Register notification mPrevViewer = SetClipboardViewer(this.Handle); updateClipboard(); } private void Form1_Closing(object sender, FormClosingEventArgs e) { // Remove notification ChangeClipboardChain(this.Handle, mPrevViewer); } private void updateClipboard() { // Called when clipboard contents changed pictureBox1.Image = null; label1.Text = ""; if (Clipboard.ContainsText()) label1.Text = Clipboard.GetText(); if (Clipboard.ContainsImage()) pictureBox1.Image = Clipboard.GetImage(); } protected override void WndProc(ref Message m) { if (m.Msg == WM_CHANGECBCHAIN) { if (m.WParam == mPrevViewer) mPrevViewer = m.LParam; else if (mPrevViewer != null) SendMessage(mPrevViewer, m.Msg, m.WParam, m.LParam); } else if (m.Msg == WM_DRAWCLIPBOARD) { updateClipboard(); if (mPrevViewer != null) SendMessage(mPrevViewer, m.Msg, m.WParam, m.LParam); } base.WndProc(ref m); } // P/Invoke declarations private static int WM_CHANGECBCHAIN = 0x30d; private static int WM_DRAWCLIPBOARD = 0x308; [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern IntPtr SetClipboardViewer(IntPtr hWnd); [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern bool ChangeClipboardChain(IntPtr hRemove, IntPtr hNext); [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); } }
|