Floating toolbar hide/unhide message
jshao@pluto.dspt.com Thursday, August 22, 1996 Environment: VC++ 4.0, Win95 In the project I am working, I created a floating toolbar in the MainFrm.cpp OnCreate() function: int CMainFrame::ONCreate() { .. m_PaletteBar.Create(this, WS_CHILD|WS_VISIBLE|CBRS_SIZE_FIXED| CBRS_FLOATING|CBRS_TOOLTIPS,IDW_PALLETE_BAR) ... } where m_paletteBar is an object of a class CPaleetebar -- derived from CToolBar. The floatingbar works fine accept one thing: I would like to capture the message whenever one clicks on the top-right kill the window button (cross button -- not minimize or maximize window buttons) and perform some processing. I have tried several methods such as to overwrite OnClose, OnDestroy ... of the CpaletteBar class, but none of them successful. Anyone in the net can solve this problem? James Shao DSP Technology
Jim McCabe -- jmccabe@mail.portup.com Monday, August 26, 1996 [Mini-digest: 5 responses] Hi James, >I would like to capture the message whenever one clicks on the top-right >kill the window button (cross button -- not minimize or maximize window >buttons) and perform some processing. Try capturing WM_SYSCOMMAND, wParam should be SC_CLOSE. I don't know if the toolbars function this way, but ordinary windows do. Jim jmccabe@mail.portup.com - http://www.portup.com/~jmccabe -----From: Mario Contestabile It isn't killed or closed. It is hidden. You can check that by putting a breakpoint in the CpaletteBar DTOR. Write a handler for OnWindowPosChanged(), and you can determine if indeed it is being hidden. void CpaletteBar::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos) { CToolBar::OnWindowPosChanged(lpwndpos); if( (lpwndpos->flags & SWP_HIDEWINDOW) && (lpwndpos->flags & SWP_NOREDRAW) ){ CString title; GetWindowText(title); TRACE1("CpaletteBar::OnWindowPosChanged() Palette Bar closing %s\n", title); CMainFrame* pMDIFrame = (CMainFrame*)AfxGetMainWnd(); if(pMDIFrame) pMDIFrame->AlarmBarClosing(title); } } mcontest@universal.com -----From: Mike BlaszczakSimply overriding these functions isn't enough. You need to hook up a message map entry that says your OnClose() or OnDestroy() function handles WM_CLOSE or WM_DESTROY. Or did you mean to say that you did make a message map and get everything hooked up like that and you're still not getting the calls? .B ekiM http://www.nwlink.com/~mikeblas <--- trip report central 1995 Honda VFR750F (Serial number 00050!) 4 Corners 1996! 1987 Yamaha FZ700 (damaged) AMA, HRC, VFROC These words are my own: I do not speak for Microsoft. -----From: WnDBSoft@aol.com Sure. I have an idea which might help, though I'm not sure. Have ClassWizard add a message handler for WM_SYSCOMMAND to your message map. Now, go to wincore.cpp and find CWnd::OnSysCommand( ), if it's there. Once you find CWnd::OnSysCommand( ), copy (do not cut) the entire body of the function to the Clipboard. Then, in the CPaletteBar::OnSysCommand( ) handler, select the comments in the body and then paste the Clipboard contents over the selection. NOTE: Change over all the calls to CWnd::OnSysCommand( ) to CToolBar::OnSysCommand( ). In OnSysCommand( ), there is a switch(nID & 0xFF0) { } series, with case: SC_* in it. Let all of the case: SC_* fall through, except for case: SC_CLOSE. Then, write a function which does your close processing, then call the base class OnSysCommand( ). You see, clicking the close button on the titlebar send WM_SYSCOMMAND with a wParam of SC_CLOSE. For example: void CPalletteBar::DoCloseProcessing( ) { // ... // TODO: Add code here to do processing on close // ... } // WM_SYSCOMMAND handler void CPalletteBar::OnSysCommand(UINT nID, LPARAM lParam ) { if (AfxGetMainWnd( )->m_bHelpMode) { //... //... // help processing... //... //... } else { // switch/case on nID & 0xFF0, or something like that, I'm not sure switch (nID & 0xFF0) { case SC_CLOSE: DoCloseProcessing( ); CToolBar::OnSysCommand(nID, lParam); break; // let's put a default here for brevity default: // call base class for all other system commands CToolBar::OnSysCommand(nID, lParam); break; } } return; } -----From: Mark Conway James, Two things to note about the close button on the CToolBar: 1) The toolbar is inside a frame window MFC creates - the undocumented CMiniDockFrameWnd class. When a control bar is floated, this is created dynamically by the frame work, and your toolbar is parented off it. 2) The default action for this close button on the frame window is to just to hide the control bar, so you won't get close/destroy messages. It is possible to replace the CMiniDockFrameWnd class yourself - MFC provides a hook (more of a loophole really) for doing this: CFrameWnd::m_pFloatingFrameClass points to a runtime class structure for the class to create for a floating frame. Derive from CMiniDockFrameWnd, and slot your own class in here. Although not quite what you want, download MRCEXT from http://ourworld.compuserve.com/homepages/mrconway/mrcext.htm and you'll find some source code that uses this technique for something a bit more drastic. You can also hook into your toolbars WM_WINDOWPOSCHANGED/CHANGING messages, and when you receive them workout whether it's visible or not. The toolbar gets these messages when the toolbar is being floated, docked, hidden or shown, as well as in more normal circumstances. This is an indirect way, and more problematic, but you may prefer it. Hope this helps Mark.
Shane -- shane_trenary@penmetrics.com Tuesday, August 27, 1996 Two people below hit upon your solution--however, the last person below also has an additional solution you may want to use. -- Shane ______________________________ Reply Separator _________________________________ Subject: Re: Floating toolbar hide/unhide message Author: mfc-l@netcom.com at Internet Date: 8/27/96 9:34 AM Received: by ccmail Received: from bashir by penmetrics.com (UUPC/extended 1.11) with UUCP; Tue, 27 Aug 1996 09:31:50 PDT Received: from majordomo.netcom.com (listless.netcom.com [206.217.29.105]) by bas hir.peak.org (8.7.3/8.7.3) with ESMTP id JAA07331; Tue, 27 Aug 1996 09:25:37 -070 0 (PDT) Received: by majordomo.netcom.com (8.7.5/8.7.3/(NETCOM MLS v1.01)) id IAA16774; T ue, 27 Aug 1996 08:55:41 -0700 (PDT) From: jmccabe@mail.portup.com (Jim McCabe) X-ccAdmin: postmaster@bashir To: mfc-l@netcom.com Subject: Re: Floating toolbar hide/unhide message Date: Mon, 26 Aug 1996 08:32:37 -0400 Message-ID: <322198be.460434@mail.portup.com> References:In-Reply-To: X-Mailer: Forte Agent .99e/32.227 Sender: owner-mfc-l@majordomo.netcom.com Errors-To: owner-mfc-l@majordomo.netcom.com Precedence: bulk Reply-To: mfc-l@netcom.com [Mini-digest: 5 responses] Hi James, >I would like to capture the message whenever one clicks on the top-right >kill the window button (cross button -- not minimize or maximize window >buttons) and perform some processing. Try capturing WM_SYSCOMMAND, wParam should be SC_CLOSE. I don't know if the toolbars function this way, but ordinary windows do. Jim jmccabe@mail.portup.com - http://www.portup.com/~jmccabe -----From: Mario Contestabile It isn't killed or closed. It is hidden. You can check that by putting a breakpoint in the CpaletteBar DTOR. Write a handler for OnWindowPosChanged(), and you can determine if indeed it is being hidden. void CpaletteBar::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos) { CToolBar::OnWindowPosChanged(lpwndpos); if( (lpwndpos->flags & SWP_HIDEWINDOW) && (lpwndpos->flags & SWP_NOREDRAW) ){ CString title; GetWindowText(title); TRACE1("CpaletteBar::OnWindowPosChanged() Palette Bar closing %s\n", title); CMainFrame* pMDIFrame = (CMainFrame*)AfxGetMainWnd(); if(pMDIFrame) pMDIFrame->AlarmBarClosing(title); } } mcontest@universal.com -----From: Mike Blaszczak Simply overriding these functions isn't enough. You need to hook up a message map entry that says your OnClose() or OnDestroy() function handles WM_CLOSE or WM_DESTROY. Or did you mean to say that you did make a message map and get everything hooked up like that and you're still not getting the calls? .B ekiM http://www.nwlink.com/~mikeblas <--- trip report central 1995 Honda VFR750F (Serial number 00050!) 4 Corners 1996! 1987 Yamaha FZ700 (damaged) AMA, HRC, VFROC These words are my own: I do not speak for Microsoft. -----From: WnDBSoft@aol.com Sure. I have an idea which might help, though I'm not sure. Have ClassWizard add a message handler for WM_SYSCOMMAND to your message map. Now, go to wincore.cpp and find CWnd::OnSysCommand( ), if it's there. Once you find CWnd::OnSysCommand( ), copy (do not cut) the entire body of the function to the Clipboard. Then, in the CPaletteBar::OnSysCommand( ) handler, select the comments in the body and then paste the Clipboard contents over the selection. NOTE: Change over all the calls to CWnd::OnSysCommand( ) to CToolBar::OnSysCommand( ). In OnSysCommand( ), there is a switch(nID & 0xFF0) { } series, with case: SC_* in it. Let all of the case: SC_* fall through, except for case: SC_CLOSE. Then, write a function which does your close processing, then call the base class OnSysCommand( ). You see, clicking the close button on the titlebar send WM_SYSCOMMAND with a wParam of SC_CLOSE. For example: void CPalletteBar::DoCloseProcessing( ) { // ... // TODO: Add code here to do processing on close // ... } // WM_SYSCOMMAND handler void CPalletteBar::OnSysCommand(UINT nID, LPARAM lParam ) { if (AfxGetMainWnd( )->m_bHelpMode) { //... //... // help processing... //... //... } else { // switch/case on nID & 0xFF0, or something like that, I'm not sure switch (nID & 0xFF0) { case SC_CLOSE: DoCloseProcessing( ); CToolBar::OnSysCommand(nID, lParam); break; // let's put a default here for brevity default: // call base class for all other system commands CToolBar::OnSysCommand(nID, lParam); break; } } return; } -----From: Mark Conway James, Two things to note about the close button on the CToolBar: 1) The toolbar is inside a frame window MFC creates - the undocumented CMiniDockFrameWnd class. When a control bar is floated, this is created dynamically by the frame work, and your toolbar is parented off it. 2) The default action for this close button on the frame window is to just to hide the control bar, so you won't get close/destroy messages. It is possible to replace the CMiniDockFrameWnd class yourself - MFC provides a hook (more of a loophole really) for doing this: CFrameWnd::m_pFloatingFrameClass points to a runtime class structure for the class to create for a floating frame. Derive from CMiniDockFrameWnd, and slot your own class in here. Although not quite what you want, download MRCEXT from http://ourworld.compuserve.com/homepages/mrconway/mrcext.htm and you'll find some source code that uses this technique for something a bit more drastic. You can also hook into your toolbars WM_WINDOWPOSCHANGED/CHANGING messages, and when you receive them workout whether it's visible or not. The toolbar gets these messages when the toolbar is being floated, docked, hidden or shown, as well as in more normal circumstances. This is an indirect way, and more problematic, but you may prefer it. Hope this helps Mark.
| Вернуться в корень Архива |