Discussion:
CDialog::OnCopyData, what does it do?
(too old to reply)
amccombs
2008-01-09 16:54:00 UTC
Permalink
I am using VC6. I have a dialog box application. I used Class Wizard and
added OnCopyData. The wizard added
[code]
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
[/code]

I have read the MSDN,
http://msdn2.microsoft.com/en-us/library/5hcat2sc(VS.80).aspx

I wanted to know the details of what this function does. Does it send a
message back to the sending app saying that it received the message or just
tells windows that it can free the memory?

What happens if pWnd is NULL?
Joseph M. Newcomer
2008-01-09 17:30:37 UTC
Permalink
The function does nothing at all. You have to write something IN the function to have it
do something!

There is no protocol of sending anything back; WM_COPYDATA can only be sent via
SendMessage. When you return from the OnCopyData handler, the storage is freed;
therefore, you have to copy out anything you need before you return.

I have never bothered to look at the pWnd pointer, because the sender is generally of no
interest whatsoever to me. All that matters is the data I have received. Not clear to me
why it would matter, but if it is NULL, you would have to obviously ignore it.
joe
Post by amccombs
I am using VC6. I have a dialog box application. I used Class Wizard and
added OnCopyData. The wizard added
[code]
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
[/code]
I have read the MSDN,
http://msdn2.microsoft.com/en-us/library/5hcat2sc(VS.80).aspx
I wanted to know the details of what this function does. Does it send a
message back to the sending app saying that it received the message or just
tells windows that it can free the memory?
What happens if pWnd is NULL?
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer
2008-01-09 22:04:15 UTC
Permalink
I forgot to point you to the essay on using WM_COPYDATA on my MVP Tips site...
joe
Post by Joseph M. Newcomer
The function does nothing at all. You have to write something IN the function to have it
do something!
There is no protocol of sending anything back; WM_COPYDATA can only be sent via
SendMessage. When you return from the OnCopyData handler, the storage is freed;
therefore, you have to copy out anything you need before you return.
I have never bothered to look at the pWnd pointer, because the sender is generally of no
interest whatsoever to me. All that matters is the data I have received. Not clear to me
why it would matter, but if it is NULL, you would have to obviously ignore it.
joe
Post by amccombs
I am using VC6. I have a dialog box application. I used Class Wizard and
added OnCopyData. The wizard added
[code]
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
[/code]
I have read the MSDN,
http://msdn2.microsoft.com/en-us/library/5hcat2sc(VS.80).aspx
I wanted to know the details of what this function does. Does it send a
message back to the sending app saying that it received the message or just
tells windows that it can free the memory?
What happens if pWnd is NULL?
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
amccombs
2008-01-10 21:23:01 UTC
Permalink
Thanks Joe, I read your site before I post here.

The SendMessage for WM_COPYDATA, they Handle to sender is an HWND

SendMessage(
(HWND) hWnd, // handle to destination window
WM_COPYDATA, // message to send
(WPARAM) wParam, // handle to window (HWND)
(LPARAM) lParam // data (PCOPYDATASTRUCT)
);

yet the OnCopyData is shows a CWnd
OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)

Why are they inconsistant? If the sender send a HWnd but the reciever casts
it to a CWnd, why?
Post by Joseph M. Newcomer
I forgot to point you to the essay on using WM_COPYDATA on my MVP Tips site...
joe
Post by Joseph M. Newcomer
The function does nothing at all. You have to write something IN the function to have it
do something!
There is no protocol of sending anything back; WM_COPYDATA can only be sent via
SendMessage. When you return from the OnCopyData handler, the storage is freed;
therefore, you have to copy out anything you need before you return.
I have never bothered to look at the pWnd pointer, because the sender is generally of no
interest whatsoever to me. All that matters is the data I have received. Not clear to me
why it would matter, but if it is NULL, you would have to obviously ignore it.
joe
Post by amccombs
I am using VC6. I have a dialog box application. I used Class Wizard and
added OnCopyData. The wizard added
[code]
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
[/code]
I have read the MSDN,
http://msdn2.microsoft.com/en-us/library/5hcat2sc(VS.80).aspx
I wanted to know the details of what this function does. Does it send a
message back to the sending app saying that it received the message or just
tells windows that it can free the memory?
What happens if pWnd is NULL?
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Scott McPhillips [MVP]
2008-01-10 21:44:30 UTC
Permalink
Post by amccombs
Thanks Joe, I read your site before I post here.
The SendMessage for WM_COPYDATA, they Handle to sender is an HWND
SendMessage(
(HWND) hWnd, // handle to destination window
WM_COPYDATA, // message to send
(WPARAM) wParam, // handle to window (HWND)
(LPARAM) lParam // data (PCOPYDATASTRUCT)
);
yet the OnCopyData is shows a CWnd
OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
Why are they inconsistant? If the sender send a HWnd but the reciever casts
it to a CWnd, why?
There are two SendMessage functions. The SendMessage that takes an HWND is
the Windows API function. The CWnd::SendMessage function is an MFC function
that uses as CWnd*, not an HWND:

pWnd->SendMessage(WM_COPYDATA, wParam, lParam);

This is not an inconsistancy, it is a feature of MFC :)
--
Scott McPhillips [VC++ MVP]
David Wilkinson
2008-01-10 22:23:07 UTC
Permalink
Post by amccombs
Thanks Joe, I read your site before I post here.
The SendMessage for WM_COPYDATA, they Handle to sender is an HWND
SendMessage(
(HWND) hWnd, // handle to destination window
WM_COPYDATA, // message to send
(WPARAM) wParam, // handle to window (HWND)
(LPARAM) lParam // data (PCOPYDATASTRUCT)
);
yet the OnCopyData is shows a CWnd
OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
Why are they inconsistant? If the sender send a HWnd but the reciever casts
it to a CWnd, why?
amccombs;

Presumably, MFC creates a temporary CWnd object from the HWND contained
in the wParam argument of the message. Many/most MFC message handlers do
things like this.
--
David Wilkinson
Visual C++ MVP
David Webber
2008-01-11 10:42:34 UTC
Permalink
Post by amccombs
The SendMessage for WM_COPYDATA, they Handle to sender is an HWND
SendMessage(
(HWND) hWnd, // handle to destination window
WM_COPYDATA, // message to send
(WPARAM) wParam, // handle to window (HWND)
(LPARAM) lParam // data (PCOPYDATASTRUCT)
);
yet the OnCopyData is shows a CWnd
OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
Why are they inconsistant? If the sender send a HWnd but the reciever casts
it to a CWnd, why?
That is the Windows API function. the first parameter, hWnd, is the
destination window for the message.

The MFC equivalent is

CWnd::SendMessage(
WM_COPYDATA, // message to send
(WPARAM) wParam, // handle to window (HWND)
(LPARAM) lParam // data (PCOPYDATASTRUCT)
);

where the CWnd is the destination window.

In both cases the WPARAM can be the HWND handle of the *sending* window.
This is because a message is a message is a message. WM_COPYDATA can be
sent by MFC or non-MFC (or non-C++) programs.

But MFC prefers CWnd to HWND so the MFC handler function OnCopyData() gets a
CWnd * (presumably constructed from the HWND carried by the message).

Dave
--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mozartists/mailinglist.htm
Joseph M. Newcomer
2008-01-11 15:55:41 UTC
Permalink
Well, the SendMessage you showed uses an HWND, but you could just as easily have done

CWnd * wnd;
wnd = figure_out_target_window();

wnd->SendMessage(WM_COPYDATA, wParam, lParam);

so the use of an HWND is NOT required at the sender site! Note that
wnd->SendMessage(msg, wParam, lParam)
is IMPLEMENTED as
LRESULT CWnd::SendMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
return ::SendMessage(m_hWnd, msg, wParam, lParam); }

so what the sender does to send the message is irrelevant, because the *receiver* is in
MFC, so it uses a CWnd *. Nobody cares how the sender sent the message.
joe
Post by amccombs
Thanks Joe, I read your site before I post here.
The SendMessage for WM_COPYDATA, they Handle to sender is an HWND
SendMessage(
(HWND) hWnd, // handle to destination window
WM_COPYDATA, // message to send
(WPARAM) wParam, // handle to window (HWND)
(LPARAM) lParam // data (PCOPYDATASTRUCT)
);
yet the OnCopyData is shows a CWnd
OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
Why are they inconsistant? If the sender send a HWnd but the reciever casts
it to a CWnd, why?
Post by Joseph M. Newcomer
I forgot to point you to the essay on using WM_COPYDATA on my MVP Tips site...
joe
Post by Joseph M. Newcomer
The function does nothing at all. You have to write something IN the function to have it
do something!
There is no protocol of sending anything back; WM_COPYDATA can only be sent via
SendMessage. When you return from the OnCopyData handler, the storage is freed;
therefore, you have to copy out anything you need before you return.
I have never bothered to look at the pWnd pointer, because the sender is generally of no
interest whatsoever to me. All that matters is the data I have received. Not clear to me
why it would matter, but if it is NULL, you would have to obviously ignore it.
joe
Post by amccombs
I am using VC6. I have a dialog box application. I used Class Wizard and
added OnCopyData. The wizard added
[code]
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
[/code]
I have read the MSDN,
http://msdn2.microsoft.com/en-us/library/5hcat2sc(VS.80).aspx
I wanted to know the details of what this function does. Does it send a
message back to the sending app saying that it received the message or just
tells windows that it can free the memory?
What happens if pWnd is NULL?
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
David Wilkinson
2008-01-11 17:44:04 UTC
Permalink
Post by Joseph M. Newcomer
Well, the SendMessage you showed uses an HWND, but you could just as easily have done
CWnd * wnd;
wnd = figure_out_target_window();
wnd->SendMessage(WM_COPYDATA, wParam, lParam);
so the use of an HWND is NOT required at the sender site! Note that
wnd->SendMessage(msg, wParam, lParam)
is IMPLEMENTED as
LRESULT CWnd::SendMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
return ::SendMessage(m_hWnd, msg, wParam, lParam); }
so what the sender does to send the message is irrelevant, because the *receiver* is in
MFC, so it uses a CWnd *. Nobody cares how the sender sent the message.
Joe:

I think he is talking about the wParam parameter of the message getting
converted from HWND to CWnd* in the MFC handler.
--
David Wilkinson
Visual C++ MVP
Joseph M. Newcomer
2008-01-12 06:22:16 UTC
Permalink
Ah, yes. Well, that just means using the m_hWnd member, e.g.,

target->PostMessage(WM_COPYDATA, m_hWnd, ...etc...)

no big deal.
joe
Post by David Wilkinson
Post by Joseph M. Newcomer
Well, the SendMessage you showed uses an HWND, but you could just as easily have done
CWnd * wnd;
wnd = figure_out_target_window();
wnd->SendMessage(WM_COPYDATA, wParam, lParam);
so the use of an HWND is NOT required at the sender site! Note that
wnd->SendMessage(msg, wParam, lParam)
is IMPLEMENTED as
LRESULT CWnd::SendMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
return ::SendMessage(m_hWnd, msg, wParam, lParam); }
so what the sender does to send the message is irrelevant, because the *receiver* is in
MFC, so it uses a CWnd *. Nobody cares how the sender sent the message.
I think he is talking about the wParam parameter of the message getting
converted from HWND to CWnd* in the MFC handler.
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

David Webber
2008-01-09 17:32:26 UTC
Permalink
Post by amccombs
I am using VC6. I have a dialog box application. I used Class Wizard and
added OnCopyData. The wizard added
[code]
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
[/code]
I have read the MSDN,
http://msdn2.microsoft.com/en-us/library/5hcat2sc(VS.80).aspx
I wanted to know the details of what this function does. Does it send a
message back to the sending app saying that it received the message or just
tells windows that it can free the memory?
It responds to a WM_COPYDATA message. There should be an ON_WM_COPYDATA()
in your message map, which ensures it gets called.

So when you receive such a message you use this function to do what you need
to do with the data encapsulated in *pCopyDataStruct. It does what you
program it it to do.

I don't think the base class implementation does anything. It should surely
NOT free the data, as you are being sent something which may still be needed
by the sender. Typically the sender will do something like

COPYDATASTRUCT cds;
// fill in cds
pRecipientWnd->SendMessage( WM_COPYDATA, WPARAM(hWndSender),
(LPARAM)(&cds) );
// allow cds to go out of scope.

and if the recipient tries to destroy the pointer it gets, I'd anticipate
deep trouble!
Post by amccombs
What happens if pWnd is NULL?
pWnd is a pointer to the Window which sent the WM_COPYDATA message. I
assume it is constructed from the WPARAM of the message. I pass NULL
regularly when the recipient doesn't need to know where the message comes
from.


By the by:

A common use of this message for main application windows in MDI programs is
as follows:
User double clicks on a document file name.
Application checks to see if an instance of the same program is already
running.
If so it parcels the double-clicked filename in a COPYDATA struct and sends
a WM_COPYDATA to the main window of th existing instance, and then exits
silently.
On receipt of a WM_COPYDATA the application opens the file.

In this way double clicking a document file in explorer opens it in a new
view window in an already-running instance of the application. You don't
get a second instance of the program.

Dave
--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mozartists/mailinglist.htm
Loading...