15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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 Maddy 


Handle 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;
} 





| Вернуться в корень Архива |