From: David Webber on 25 Jun 2010 11:14 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. Nowadays CMainFrame is derived from CMDIFrameWndEx and this has a member CMDIClientAreaWnd m_wndClientArea; and (I think) because a CWnd object already exists for the MDI client area, then SubclassWindow() doesn't work on it. A second reason is that CMFCToolBar etc come with a customisation property sheet, and I am considering what I might do to override one of its property pages. [I used to think that I knew MFC quite well - but all these new classes have thrown me somewhat!] 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: David Lowndes on 25 Jun 2010 11:54 >Nowadays CMainFrame is derived from CMDIFrameWndEx and this has a member > >CMDIClientAreaWnd m_wndClientArea; > >and (I think) because a CWnd object already exists for the MDI client area, >then SubclassWindow() doesn't work on it. I wonder if you can handle the message some other way - perhaps in the application's PreTranslateMessage handler? Dave
From: David Webber on 25 Jun 2010 13:30 "David Lowndes" <DavidL(a)example.invalid> wrote in message news:44k926hsb0voea68aeerl1r2vdq21i9btc(a)4ax.com... >>Nowadays CMainFrame is derived from CMDIFrameWndEx and this has a member >> >>CMDIClientAreaWnd m_wndClientArea; >> >>and (I think) because a CWnd object already exists for the MDI client >>area, >>then SubclassWindow() doesn't work on it. > > I wonder if you can handle the message some other way - perhaps in the > application's PreTranslateMessage handler? Sounds like a plausible idea for one message for that particular window - thanks. But it sounds pretty horrible for a whole property page and all its controls. BUT..... Please forgive me if I think aloud here, as something might be dawning on me in real time as I type. The App Wizard has given me: void CMainFrame::OnViewCustomize() { CMFCToolBarsCustomizeDialog* pDlgCust = new CMFCToolBarsCustomizeDialog(this, TRUE); pDlgCust->EnableUserDefinedToolbars(); pDlgCust->Create(); } so I can derive a class from CMFCToolBarsCustomizeDialog, and use that instead. This is a property sheet with a number of property pages, including CMFCToolBarsKeyboardPropertyPage* m_pKeyboardPage; which allows the user to set a new keyboard shortcut. No whilst I can't easily get at the property *page*, the property *sheet* (which I *can* subclass) has lots of virtual members, including virtual BOOL OnAssignKey( ACCEL *pAccel ) { return TRUE; } It *looks* like this gets called with the newly selected accelerator, and I can do what I want with it and return FALSE to tell MFC to ignore it! This is looking very promising!!!!!!!! Background: Shortcut keys like ^ > + - are very useful mnemonics for music applications. Equally Ctrl+> etc are very useful shortcuts. But I want it to appear as Ctrl+> on the menu, and not Ctrl+Shift+. And I want to define these shortcuts for all national keyboards (even if > isn't Shift+.) Accelerators are not up to the job, so I rolled my own method, built into WM_KEYDOWN and WM_CHAR processing. Maybe I *will* be able to integrate it with the new customisable toolbars!!!! A nice thought on which to end the week (especially as I'm out all weekend playing on bandstands.) 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: Joseph M. Newcomer on 26 Jun 2010 17:53 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) joe On Fri, 25 Jun 2010 16:14:02 +0100, "David Webber" <dave(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. > >Nowadays CMainFrame is derived from CMDIFrameWndEx and this has a member > >CMDIClientAreaWnd m_wndClientArea; > >and (I think) because a CWnd object already exists for the MDI client area, >then SubclassWindow() doesn't work on it. > >A second reason is that CMFCToolBar etc come with a customisation property >sheet, and I am considering what I might do to override one of its property >pages. > >[I used to think that I knew MFC quite well - but all these new classes have >thrown me somewhat!] > >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 26 Jun 2010 18:39
"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 -- David Webber Mozart Music Software http://www.mozart.co.uk For discussion and support see http://www.mozart.co.uk/mozartists/mailinglist.htm |