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

SetClipboardViewer()

379 views
Skip to first unread message

ou

unread,
Dec 20, 2007, 1:32:15 AM12/20/07
to
Env: WindowsXP, VC++6.00

In my app, SetClipboardViewer() is called and it returns NULL. So there are
no other windows in the clipboard viewer chain.

I wonder why mspaint, WORD and notepad are not added into the clipboard
viewer chain?

After I call SetClipboardViewer(), my app can receive WM_DRAWCLIPBOARD, but
not WM_CHANGECBCHAIN from WindowProc(). I don't know why?

TIA

ou

Gernot Frisch

unread,
Dec 20, 2007, 5:39:23 AM12/20/07
to

> In my app, SetClipboardViewer() is called and it returns NULL. So
> there are
> no other windows in the clipboard viewer chain.
>
> I wonder why mspaint, WORD and notepad are not added into the
> clipboard
> viewer chain?


You don't have to add t the clipboard VIEWER chain in order to
copy/paste stuff.
The clipboard viewer chain is for programs like:
http://www.glbasic.com/main.php?site=clipchap


> After I call SetClipboardViewer(), my app can receive
> WM_DRAWCLIPBOARD, but
> not WM_CHANGECBCHAIN from WindowProc(). I don't know why?

Uhm. You might get this message as well, but it's very very rarely
used.
See my program above to see what it acually does.


Joseph M. Newcomer

unread,
Dec 20, 2007, 10:52:36 AM12/20/07
to
They would be added only if they have active clipboard viewers. For example, if the
"office clipboard" window were being displayed in Word, it might add itself to the
clipboard viewer. Notepad would have no reason to be added to the clipboard viewer chain,
since it has no clipboard viewer feature. Likewise paint.

You would receive WM_CHANGECBCHAIN if someone added or removed a window from the viewer
chain, so unless one of these events happens, you wouldn't see the message. So you would
have to test it by creating, for example, another instance of your app, and then shutting
one of them down (such as the first one, but maybe the second one) to cause a situation in
which that event is seen. If the chain is empty, you will not receive such notifications.
You don't receive these notifications "from" the WindowProc, they are sent "to" the
WindowProc by the system. And if you are programming in MFC, you would never see
AfxWndProc or any other low-level window proc. You would receive notifications via
methods in your message map.
joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

ou

unread,
Dec 20, 2007, 7:29:02 PM12/20/07
to
Thanks joe.

If I launch clipbrd.exe firstly before my app, Yes, SetClipboardViewer()
returns a valid handle. By Spy++, I can confirm it is clipbrd's handle.

And then, I copy something by NOTEPAD or MSPAINT, by CMyDlg::WindowProc(UINT
message, WPARAM wParam, LPARAM lParam), I can catch WM_DRAWCLIPBOARD
message.

After that, I exit clipbrd, I fail to catch WM_CHANGECBCHAIN message.

I think it is not necessary for a clipboard viewer to be a top window(CMyDlg
is a child-window).

Another question: should I return (LRESULT) NULL or call
CDialog::WindowProc(message, wParam, lParam) after dealing with
WM_DRAWCLIPBOARD /WM_CHANGECBCHAIN as follows,

LRESULT CMyDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if ( message == WM_DRAWCLIPBOARD )
{
UpdateClipSizeShow();
::SendMessage(hNextWnd, message, wParam, lParam);
//Should I return NULL here?
return (LRESULT) NULL
}
else if ( message == WM_CHANGECBCHAIN )
{
if (hNextWnd == (HWND) wParam )
hNextWnd = (HWND) lParam;
else if (hNextWnd != NULL)
::SendMessage(hNextWnd, message, wParam, lParam);

//Should I return NULL here?
return (LRESULT) NULL
}
return CDialog::WindowProc(message, wParam, lParam);
}


ou

Joseph M. Newcomer

unread,
Dec 20, 2007, 8:21:14 PM12/20/07
to
You should not be seeing WindowProc at all; you should not see any of this. You are
clearly programming in MFC, so you should be using message maps to handle this.

You should always return the vaue from the superclass, but ultimately, this code is very
weird to find in an MFC application. Why are you not just handling messages with a
message map?
joe

ou

unread,
Dec 20, 2007, 9:36:00 PM12/20/07
to
Sorry, I just don't understand what you mean.
I use CMyDlg::WindowProc() because it appears at ClassWizard.
I just don't understand the meaning of "message maps" method you mentioned.
I indeed know I should return the value from the superclass.
For WM_CHANGECBCHAIN/WM_DRAWCLIPBOARD, I just don't know which one of the
following I should use:

return NULL;
return return CDialog::WindowProc(message, wParam, lParam);

ou

> You should not be seeing WindowProc at all; you should not see any of

Joseph M. Newcomer

unread,
Dec 21, 2007, 11:07:56 PM12/21/07
to
Well, just because it appears does not mean it is reasonable, or even sensible, to use it.
This is the wrong approach to handling your own messages.

You had better understand message maps because they are really fundamental to how MFC
works; otherwise, you are just programming Petzold Windows 2.0 code in 32-bit MFC.

If you are using VS2003 or higher, there are already handlers the Properties window will
generate for WM_CHANGECBCHAIN and WM_DRAWCLIPBOARD. If you are using VS6, it may not have
these, and you might have to add, by hand
ON_MESSAGE(WM_CHANGECBCHAIN, OnChangeCbChain)
ON_MESSAGE(WM_DRAWCLIPBOARD, OnDrawClipboard)
with the declarations
afx_msg LRESULT OnChangeCbChain(WPARAM, LPARAM);
afx_msg LRESULT OnDrawClipboard(WPARAM, LPARAM);
but it is no big deal to do so.

At the worst you should return the superclass result, but essentially, you need to learn
how to program in MFC. It is safe to assume that 100% of the time you generate a
WindowProc you have made a fundamental design error (the number of times this actually
makes sense is so vanishingly small that 100% is close enough to the truth to be taken as
a good guideline).

If you don't have a good book on MFC (most people here recommend Prosise; I've never seen
it so can't comment beyond the recommendations given), just sit down and spend a few days
doing the Scribble tutorial. I learned MFC in three days from it (it took me another two
years to fully appreciate both C++ and MFC, but it will really get you started, and when
you are done with it, you will have a very good idea how message maps work)
joe

0 new messages