From: Joseph M. Newcomer on
See below...
On Sat, 26 Jun 2010 23:39:23 +0100, "David Webber" <dave(a)musical-dot-demon-dot-co.uk>
wrote:

>
>"Joseph M. Newcomery" <newcomer(a)flounder.com> wrote in message
>news:j2qc26pnsge8f50k0c8jatcst7ae6n93ii(a)4ax.com...
>
>> This is remarkably ugly, but something like this should work...
>>
>> First, have a window subclass that you want. I'll call it CMySubclass
>>
>> void CMyApp::RedrawClientArea()
>> {
>> CMySublcass w;
>> w.Attach(m_wndClientArea.Detach());
>> w->Invalidate();
>> w->UpdateWindow();
>> m_wndClientArea.Attach(w.Detach());
>> }
>>
>> Overall, this is pretty gross. Also, I have not figured out quite where
>> you would need to
>> call this, but I'd suspect this is one of the interesting uses of
>> PreTranslateMessage,
>> looking for a WM_PAINT directed to the client area (in that case, the
>> Invalidate() would
>> not be required)
>
>I vaguely wondered about something like that. When it says that
>SubclassWindow only works for an HWND with no CWnd attached, the immediate
>question is why? The next question is - well if we remove the attached
>CWnd, what then?
****
When an HWND is placed in a CWnd-derived class (as the m_hWnd), an entryis made in the
handle map for that thread. If, in the future, someone delivers an HWND (say, a message
is received), the way the methods are found is to use the handle map to obtain the CWnd*
pointer; in the case of message dispatching, from the CWnd* reference, the message map is
found. Note that in general if the lookup fails, a *temporary* CWnd* reference is
generated, which is deleted in the CWinApp::OnIdle handler. This is why there all all the
warnings about the CWnd* reference being temporary, and that it must not be stored.

So you cannot have an HWND mapped to two different CWnd-derived objects. Hence the ugly
detach/attach code I gave; the Attach code creates a new mapping of an newly-unattached
HWND.

Note that when an Attach (or SubclassWindow, which ultimately does an Attach) occurs, the
handle is looked up in the handle map. It had better return an error coden (handle not
found), otherwise, there is an ASSSERT failure that there is an attempt to create a handle
map entry for an HWND which is already mapped.
*****
>
>If we take your suggestion one step further: suppose I derive CMySubclass
>from the CWnd-derived class which was attached in the first place. Then I
>could detach the original and attach mine, and leave it attached, with no
>apparent penalties. But if it is as easy as that, why doesn't
>SublassWindow just do it? I guess the originally attached class may itself
>have some data necessary to the correct functioning of the window?
****
Actually, there are penalties; messages directed to that window will not be handled by the
class of the m_wndClientArea. Presumably, this will not be healthy for your app.

And, as I indicated, SubclassWindow *cannot* work correctly if the HWND is already mapped!
It is considered erroneous to let SubclassWIndow map an HWND to some other CWnd* when it
is already mapped to a CWnd*. So the code I showed (remember, I said it was gross and
ugly) creates a *temporary* remapping only in the cases where you need it. Otherwise, the
mapping is left at the correct class for the new framework, so it continues to work
correctly.

joe
****
>
>I feel I am walking on eggshells here.
>
>Dave
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
A friend who wrote an analogously ugly piece of code used "ASCII Art" to draw a
skull-and-crossbones in the function header comments, and quoted the Unix kernel's
context-swap code: "You are not meant to understand this"
joe
On Sat, 26 Jun 2010 23:39:23 +0100, "David Webber" <dave(a)musical-dot-demon-dot-co.uk>
wrote:

>
>"Joseph M. Newcomery" <newcomer(a)flounder.com> wrote in message
>news:j2qc26pnsge8f50k0c8jatcst7ae6n93ii(a)4ax.com...
>
>> This is remarkably ugly, but something like this should work...
>>
>> First, have a window subclass that you want. I'll call it CMySubclass
>>
>> void CMyApp::RedrawClientArea()
>> {
>> CMySublcass w;
>> w.Attach(m_wndClientArea.Detach());
>> w->Invalidate();
>> w->UpdateWindow();
>> m_wndClientArea.Attach(w.Detach());
>> }
>>
>> Overall, this is pretty gross. Also, I have not figured out quite where
>> you would need to
>> call this, but I'd suspect this is one of the interesting uses of
>> PreTranslateMessage,
>> looking for a WM_PAINT directed to the client area (in that case, the
>> Invalidate() would
>> not be required)
>
>I vaguely wondered about something like that. When it says that
>SubclassWindow only works for an HWND with no CWnd attached, the immediate
>question is why? The next question is - well if we remove the attached
>CWnd, what then?
>
>If we take your suggestion one step further: suppose I derive CMySubclass
>from the CWnd-derived class which was attached in the first place. Then I
>could detach the original and attach mine, and leave it attached, with no
>apparent penalties. But if it is as easy as that, why doesn't
>SublassWindow just do it? I guess the originally attached class may itself
>have some data necessary to the correct functioning of the window?
>
>I feel I am walking on eggshells here.
>
>Dave
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: David Webber on
"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
news:dc6d26psjoevppsmkueotlvhiq7o78h3i5(a)4ax.com...

>>I vaguely wondered about something like that. When it says that
>>SubclassWindow only works for an HWND with no CWnd attached, the immediate
>>question is why? The next question is - well if we remove the attached
>>CWnd, what then?
> ****
>
> [Can't attach an HWND to two CWnds]....

Yes I can see this - replacing the CWnd would be the only option.

> Actually, there are penalties; messages directed to that window will not
> be handled by the
> class of the m_wndClientArea. Presumably, this will not be healthy for
> your app.

But if I derived my window class from CMDIClientAreaWnd then presumably the
only danger would be that any data members it had would be different from
the original CMDIClientAreaWnd m_wndClientArea.

Still maybe that's danger enough.

> And, as I indicated, SubclassWindow *cannot* work correctly if the HWND is
> already mapped!
> It is considered erroneous to let SubclassWIndow map an HWND to some other
> CWnd* when it
> is already mapped to a CWnd*. So the code I showed (remember, I said it
> was gross and
> ugly) creates a *temporary* remapping only in the cases where you need it.
> Otherwise, the
> mapping is left at the correct class for the new framework, so it
> continues to work
> correctly.

Yes I realise that. I think your 'gross and ugly' is my 'walking on
eggshells'. :-)

Dave
--
David Webber
Mozart Music Software
http://www.mozart.co.uk
For discussion and support see
http://www.mozart.co.uk/mozartists/mailinglist.htm


From: Goran on
On Jun 25, 5:14 pm, "David Webber" <d...(a)musical-dot-demon-dot-co.uk>
wrote:
> Is there any easy way of overriding the responses to some messages to a
> CWnd-derived object buried deep within MFC?
>
> One reason for the question is:
>
> In the old days CMainFrame was derived from CMDIFrameWnd and this had a
> member
>
> HWND m_hWndMDIClient;
>
> To draw the background of this window I used to do a
>
> SubclassWindow( )
>
> on it, and with my own CWnd-derived object, respond to WM_ERASEBKGND
> messages.

How about just putting a window of your own into m_wndClientArea and
doing your drawing in that, then?

Goran.
From: David Webber on


"Goran" <goran.pusic(a)gmail.com> wrote in message
news:a18e04e3-fa94-40a3-a651-ba96b83817b6(a)k39g2000yqb.googlegroups.com...
> On Jun 25, 5:14 pm, "David Webber" <d...(a)musical-dot-demon-dot-co.uk>
> wrote:

>> Is there any easy way of overriding the responses to some messages to a
>> CWnd-derived object buried deep within MFC?
>>
>...
>
> How about just putting a window of your own into m_wndClientArea and
> doing your drawing in that, then?

Unfortunately the m_wndClientArea being difficult to get at, I suspect it
would be diificult to give it children. Surely getting at its
WM_ERASEBKGD should be easier? But thanks for the idea - a bit of lateral
thought is always welcome :-)

Dave

--
David Webber
Mozart Music Software
http://www.mozart.co.uk
For discussion and support see
http://www.mozart.co.uk/mozartists/mailinglist.htm