From: Joseph M. Newcomer on 26 Jun 2010 20:31 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 26 Jun 2010 20:33 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 27 Jun 2010 05:31 "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 1 Jul 2010 07:25 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 1 Jul 2010 13:55
"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 |