Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Detect Windows clipboard change

1,314 views
Skip to first unread message

Donkey Agony

unread,
May 15, 2003, 10:39:50 PM5/15/03
to
Is there a way in .NET to detect when the Windows clipboard has changed?

I have a Winforms app that I want to automatically "paste" when the user
copies something in any other Windows app. I want it to monitor the
clipboard, and when the user Control-C's some text in, say, IE, I want
it to automatically paste that new text in the Winform's textbox. I
know how to copy & paste in .NET, but I don't know how to "listen" for
clipboard change events.

Any advice? I've looked in the VS.NET references and Googled a bunch,
but can't seem to find anything on this.

--
da
~~
"OE Quotefix" http://flash.to/oe-quotefix
fixes Outlook Express, not ignorance ...
http://www.allmyfaqs.com/faq.pl?How_to_post


Donkey Agony

unread,
May 16, 2003, 11:23:07 AM5/16/03
to
I wrote:

> Is there a way in .NET to detect when the Windows clipboard has
> changed?

Since I posted that, I did find some vague material through Google
Groups on this. Suggested was:

protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if (m.Msg == 776)
MessageBox.Show("Clipboard change!");
}

I tried that, but I never get the MessageBox when I copy text to the
clipboard.

What am I missing? Does something need to go in the Form's constructor?

Also suggested was:

[DllImport("user32.dll")]
public static extern int SetClipboardViewer(int hwnd);

which I placed immediately above the the WndProc override. Still, no
nothing.

I'm usually able to find good info through Google or Google Groups. I'm
amazed that so little information seems to be available on this subject.

Any help would be greatly appreciated.

Thanks,

Ross Donald

unread,
May 19, 2003, 4:44:27 AM5/19/03
to
Hi Donkey,

You need to use the SetClipboardViewer() function in the Windows API.

It involves setting up a method to listen to the Windows messages. Here are
some code snippets.

// C# - functions in WinAPI
[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SetClipboardViewer(IntPtr hWnd);

[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern WindowProcDelegate SetWindowLong(IntPtr hWnd, int
nIndex, WindowProcDelegate dwNewLong);

// Window message listener function
public int WindowProc(IntPtr hw, IntPtr uMsg, IntPtr wParam, IntPtr lParam)
{
switch((Win32.Msgs)uMsg.ToInt32())
{
case Win32.Msgs.WM_DRAWCLIPBOARD:
// ...
break;
}

Then on the form load event set up the listener..

delWinProc = new Win32.WindowProcDelegate(WindowProc);
ptrProcPrev = Win32.User32.SetWindowLong(this.Handle,
(int)Win32.GetWindowLongFlags.GWL_WNDPROC, delWinProc);

// Register this form as a Clipboard Viewer
hwndClipboardViewerNext = Win32.User32.SetClipboardViewer(this.Handle);

There is alot more to it than this but it might get you started.

Actually if you go to http://www.allapi.net and get their API-Guide and
lookup SetClipboardViewer there is a VB6 example there which you can
transfer to .NET.

--
Ross Donald
RAD Software
http://www.radsoftware.com.au


"Donkey Agony" <nob...@foo.invalid> wrote in message
news:uG8SuR1...@TK2MSFTNGP10.phx.gbl...

Donkey Agony

unread,
May 19, 2003, 9:48:24 PM5/19/03
to
Ross Donald wrote:

Ross, thanks. Since I posted my initial query, I did find some C#
snippets which someone here kindly helped me get working:

[DllImport("user32.dll")]
public static extern int SetClipboardViewer(int hwnd);

protected override void WndProc(ref Message m) {


base.WndProc(ref m);
if (m.Msg == 776)
MessageBox.Show("Clipboard change!");

// now I can do a Paste
}

then, in the constructor:

SetClipboardViewer(this.Handle.ToInt32());

Your code, quoted below, look more or less like a direct VB6 to C#
translation. It does, however, have a WindowProcDelegate, with next and
previous windows handlers -- which mine does not have. I wonder if this
is needed for a simple "listen for a clipboard change, and you get one,
paste what's on it in this app's textbox".

Maybe so -- mine *sort of* works, but I get weird exceptions at times,
so maybe that's the reason.

I'd love to see a more "native" .NET version of your code:

> // C# - functions in WinAPI
> [DllImport("User32.dll", CharSet=CharSet.Auto)]
> public static extern IntPtr SetClipboardViewer(IntPtr hWnd);
>
> [DllImport("User32.dll", CharSet=CharSet.Auto)]
> public static extern WindowProcDelegate SetWindowLong(IntPtr hWnd, int
> nIndex, WindowProcDelegate dwNewLong);
>
> // Window message listener function
> public int WindowProc(IntPtr hw, IntPtr uMsg, IntPtr wParam, IntPtr
> lParam) {
> switch((Win32.Msgs)uMsg.ToInt32())
> {
> case Win32.Msgs.WM_DRAWCLIPBOARD:
> // ...
> break;
> }
>
> Then on the form load event set up the listener..
>
> delWinProc = new Win32.WindowProcDelegate(WindowProc);
> ptrProcPrev = Win32.User32.SetWindowLong(this.Handle,
> (int)Win32.GetWindowLongFlags.GWL_WNDPROC, delWinProc);
>
> // Register this form as a Clipboard Viewer
> hwndClipboardViewerNext =
> Win32.User32.SetClipboardViewer(this.Handle);
>
> There is alot more to it than this but it might get you started.

I'll have to play with some of your code to see if it does better.

> Actually if you go to http://www.allapi.net and get their API-Guide
> and lookup SetClipboardViewer there is a VB6 example there which you
> can transfer to .NET.

I'll check it out, thanks. But .NET and VB6 are quite different in
architecture -- I wonder if there's a more direct route in .NET...

0 new messages