Catching WM_CLOSE in a CDialog subclass
Jeff Wishnie -- jwishnie@swellsoft.com Friday, August 23, 1996 Environment: MSVC 4.2/Win 95 [Moderator's note: Jeff has been told to try Spy++, so if you don't have any other advice for him...] I have a dynamically allocated modeless CDialog. I want to catch WM_CLOSE so that the dialog simply hides itself on close rather than destroying the window. Pretty straightforward right? Here's what I did: Used the class wizard to create the message handler as follows: declartation: afx_msg OnClose(); message map entry: ON_WM_CLOSE(); handler: void CMyDialogSubclass::OnClose() { ShowWindow(SW_HIDE); // CDialog::OnClose(); // do _not_ call parent } Problem is, OnClose _never_ gets called. I click the little close box as much as I want but I never receive the WM_CLOSE message and the box does nothing. Questions: 1. Where is the message going? Who's catching it? 2. What's wrong with my approach? Why can't I catch the message?? Thanks for any help! - Jeff jwishnie@swellsoft.com 415 243-9900 (w)
Andrew Dalgleish -- andrewd@axonet.com.au Monday, August 26, 1996 [Mini-digest: 4 responses] You can catch the 'X' button in WM_SYSCOMMAND for ((nID & 0xFFF0) == SC_CLOSE) Regards, Andrew Dalgleish ---------- From: owner-mfc-l[SMTP:owner-mfc-l@majordomo.netcom.com] Sent: Friday, 23 August 1996 15:56 To: mfc-l Subject: Catching WM_CLOSE in a CDialog subclass Environment: MSVC 4.2/Win 95 [Moderator's note: Jeff has been told to try Spy++, so if you don't have any other advice for him...] I have a dynamically allocated modeless CDialog. I want to catch WM_CLOSE so that the dialog simply hides itself on close rather than destroying the window. Pretty straightforward right? Here's what I did: Used the class wizard to create the message handler as follows: declartation: afx_msg OnClose(); message map entry: ON_WM_CLOSE(); handler: void CMyDialogSubclass::OnClose() { ShowWindow(SW_HIDE); // CDialog::OnClose(); // do _not_ call parent } Problem is, OnClose _never_ gets called. I click the little close box as much as I want but I never receive the WM_CLOSE message and the box does nothing. Questions: 1. Where is the message going? Who's catching it? 2. What's wrong with my approach? Why can't I catch the message?? Thanks for any help! - Jeff jwishnie@swellsoft.com 415 243-9900 (w) -----From: Paramasivan MaddyHandle the OnSysCommand for the dialog. The ID for close menu item is SC_CLOSE. void CAboutDlg::OnSysCommand( UINT nID, LPARAM lParam ) { if (nID == SC_CLOSE) AfxMessageBox("Close"); else CWnd::OnSysCommand(nID, lParam); } -----From: "Brad Wilson" > 2. What's wrong with my approach? Why can't I catch the message?? Try catching WM_SYSCOMMAND and looking for SC_CLOSE instead. > [Moderator's note: Jeff has been told to try Spy++, so if you don't > have any other advice for him...] You would have noticed the WM_SYSCOMMAND message with Spy++. -- Brad Wilson Objectivist Philosopher, Software Engineer, Web Designer crucial@pobox.com http://www.thebrads.com/bradw Objectvst@Undernet "I know that you would love to know the answers, but to you the truth is just another lie." -----From: WnDBSoft@aol.com Dialogs, oddly enough, don't process WM_CLOSE or WM_DESTROY well. Try using the WM_SYSCOMMAND message! Clicking the Close box is a system command (like you'd find on a Control menu or box in Win 3.1). AFX_MSG delclaration: afx_msg OnSysCommand(UINT nID, LPARAM lParam); message map macro: ON_WM_SYSCOMMAND( ) 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 CMyDialog::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 CDialog::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. Under case: SC_CLOSE , call ShowWindow(SW_HIDE). Don't call the base class in this case, because it would close the dialog. You see, clicking the close button on the titlebar sends WM_SYSCOMMAND with a wParam of SC_CLOSE. For example: // WM_SYSCOMMAND handler void CMyDialog::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: ShowWindow(SW_HIDE); break; // let's put a default here for brevity default: // call base class for all other system commands CDialog::OnSysCommand(nID, lParam); break; } } return; }
| Вернуться в корень Архива |