Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. modeless dialog WM_CLOSE - opinion

modeless dialog WM_CLOSE - opinion

Scheduled Pinned Locked Moved C / C++ / MFC
questionhelptutorialdiscussion
16 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 2 Offline
    2 Offline
    23_444
    wrote on last edited by
    #1

    Need your thoughts and/or opinion. Question at the bottom. When user closes the modeless dialog box you can trap the WM_CLOSE message to insure proper cleanup. According to Help CWnd::OnClose The framework calls this member function as a signal that the CWnd or an application is to terminate. The default implementation calls DestroyWindow. I found two ways to approach the user who closes the modeless dialog box by clicking the x on the upper right hand corner of the window Looking at the first example below. I found out that if you don't call DestroyWindow() from your OnClose() and you don't want multiple instances of your modeless opened you will need to set the pointer to NULL here (otherwise your pointer value can't be used as a flag to prohibit other instances of your modeless dialog from being opened). PostNcDestroy apparently isn't run until the parent is destroyed. Once the parent/owner is closed then a PostNcDestroy is run for each modeless that opened - one right after another. void CDialogDerived::OnClose() { CDialog::OnClose(); m_pParent->m_pModelessDialog = NULL; } void CDialogDerived::PostNcDestroy() { CDialog::PostNcDestroy(); m_pParent->m_pModelessDialog = NULL; //in case destroy window is called from your code and OnClose is never run delete this; } Example 2. This seems like a cleaner approach as the Dialog is destroyed immediately and thus your pointer is set to NULL immediately void CDialogDerived::OnClose() { CDialog::OnClose(); DestroyWindow(); } void CDialogDerived::PostNcDestroy() { CDialog::PostNcDestroy(); m_pParent->m_pModelessDialog = NULL; delete this; } Any thoughts pro and con to either of these approaches? I'm curious why the PostNcDestroy is not run promptly with the OnClose call on the first example. Thanks!

    S R 2 3 Replies Last reply
    0
    • 2 23_444

      Need your thoughts and/or opinion. Question at the bottom. When user closes the modeless dialog box you can trap the WM_CLOSE message to insure proper cleanup. According to Help CWnd::OnClose The framework calls this member function as a signal that the CWnd or an application is to terminate. The default implementation calls DestroyWindow. I found two ways to approach the user who closes the modeless dialog box by clicking the x on the upper right hand corner of the window Looking at the first example below. I found out that if you don't call DestroyWindow() from your OnClose() and you don't want multiple instances of your modeless opened you will need to set the pointer to NULL here (otherwise your pointer value can't be used as a flag to prohibit other instances of your modeless dialog from being opened). PostNcDestroy apparently isn't run until the parent is destroyed. Once the parent/owner is closed then a PostNcDestroy is run for each modeless that opened - one right after another. void CDialogDerived::OnClose() { CDialog::OnClose(); m_pParent->m_pModelessDialog = NULL; } void CDialogDerived::PostNcDestroy() { CDialog::PostNcDestroy(); m_pParent->m_pModelessDialog = NULL; //in case destroy window is called from your code and OnClose is never run delete this; } Example 2. This seems like a cleaner approach as the Dialog is destroyed immediately and thus your pointer is set to NULL immediately void CDialogDerived::OnClose() { CDialog::OnClose(); DestroyWindow(); } void CDialogDerived::PostNcDestroy() { CDialog::PostNcDestroy(); m_pParent->m_pModelessDialog = NULL; delete this; } Any thoughts pro and con to either of these approaches? I'm curious why the PostNcDestroy is not run promptly with the OnClose call on the first example. Thanks!

      S Offline
      S Offline
      Shog9 0
      wrote on last edited by
      #2

      Why make this so complex? You can easily check if the window still exists from the parent with a check like this:

      if ( NULL == m_pModelessDialog->GetSafeHwnd() )
      {
      if ( NULL != m_pModelessDialog )
      delete m_pModelessDialog;
      // create new instance of dialog
      // ...
      }

      And just forget about all the messy cleanup in the dialog itself.

      ---- Scripts i've known... CPhog 0.9.9 - make CP better. Forum Bookmark 0.2.5 - bookmark forum posts on Pensieve Print forum 0.1.1 - printer-friendly forums

      1 Reply Last reply
      0
      • 2 23_444

        Need your thoughts and/or opinion. Question at the bottom. When user closes the modeless dialog box you can trap the WM_CLOSE message to insure proper cleanup. According to Help CWnd::OnClose The framework calls this member function as a signal that the CWnd or an application is to terminate. The default implementation calls DestroyWindow. I found two ways to approach the user who closes the modeless dialog box by clicking the x on the upper right hand corner of the window Looking at the first example below. I found out that if you don't call DestroyWindow() from your OnClose() and you don't want multiple instances of your modeless opened you will need to set the pointer to NULL here (otherwise your pointer value can't be used as a flag to prohibit other instances of your modeless dialog from being opened). PostNcDestroy apparently isn't run until the parent is destroyed. Once the parent/owner is closed then a PostNcDestroy is run for each modeless that opened - one right after another. void CDialogDerived::OnClose() { CDialog::OnClose(); m_pParent->m_pModelessDialog = NULL; } void CDialogDerived::PostNcDestroy() { CDialog::PostNcDestroy(); m_pParent->m_pModelessDialog = NULL; //in case destroy window is called from your code and OnClose is never run delete this; } Example 2. This seems like a cleaner approach as the Dialog is destroyed immediately and thus your pointer is set to NULL immediately void CDialogDerived::OnClose() { CDialog::OnClose(); DestroyWindow(); } void CDialogDerived::PostNcDestroy() { CDialog::PostNcDestroy(); m_pParent->m_pModelessDialog = NULL; delete this; } Any thoughts pro and con to either of these approaches? I'm curious why the PostNcDestroy is not run promptly with the OnClose call on the first example. Thanks!

        R Offline
        R Offline
        Rage
        wrote on last edited by
        #3

        mx483 wrote:

        you don't want multiple instances of your modeless opened you will need to set the pointer to NULL

        This is a curious way to avoid multiple instance. Is this a child dialog of your app or, the app itself ? Why don't you check if the dialog already exists before starting a new one ? If you destroy your dialog, a simple check on SafeWindow will tell you that your pointer is not used anymore. YOu could even fire up a message to your parent to reset the pointer if you really want to. As for the examples, I think this is sufficient, no need to intercept another message.

        void CDialogDerived::PostNcDestroy()
        {
        m_pParent->m_pModelessDialog = NULL;
        delete this;
        CDialog::PostNcDestroy(); // I usually call the base class AFTER my processing

        }

        ~RaGE(); [edit] I wrote teh same as Shog because I forgot to post my message right away... Nevermind, and great to see we are on the same wave length [/edit] -- modified at 10:01 Wednesday 15th February, 2006

        2 2 Replies Last reply
        0
        • R Rage

          mx483 wrote:

          you don't want multiple instances of your modeless opened you will need to set the pointer to NULL

          This is a curious way to avoid multiple instance. Is this a child dialog of your app or, the app itself ? Why don't you check if the dialog already exists before starting a new one ? If you destroy your dialog, a simple check on SafeWindow will tell you that your pointer is not used anymore. YOu could even fire up a message to your parent to reset the pointer if you really want to. As for the examples, I think this is sufficient, no need to intercept another message.

          void CDialogDerived::PostNcDestroy()
          {
          m_pParent->m_pModelessDialog = NULL;
          delete this;
          CDialog::PostNcDestroy(); // I usually call the base class AFTER my processing

          }

          ~RaGE(); [edit] I wrote teh same as Shog because I forgot to post my message right away... Nevermind, and great to see we are on the same wave length [/edit] -- modified at 10:01 Wednesday 15th February, 2006

          2 Offline
          2 Offline
          23_444
          wrote on last edited by
          #4

          Thanks for the responses. I do check for the NULL pointer before opening an instance. I didn't include that code because it isn't relevant. What is relevant though is the correct way to handle the WM_CLOSE message. And my curiosity was I didn't understand why the WM_CLOSE message didn't run the Destroy Window right away - only after parent was closed.

          1 Reply Last reply
          0
          • R Rage

            mx483 wrote:

            you don't want multiple instances of your modeless opened you will need to set the pointer to NULL

            This is a curious way to avoid multiple instance. Is this a child dialog of your app or, the app itself ? Why don't you check if the dialog already exists before starting a new one ? If you destroy your dialog, a simple check on SafeWindow will tell you that your pointer is not used anymore. YOu could even fire up a message to your parent to reset the pointer if you really want to. As for the examples, I think this is sufficient, no need to intercept another message.

            void CDialogDerived::PostNcDestroy()
            {
            m_pParent->m_pModelessDialog = NULL;
            delete this;
            CDialog::PostNcDestroy(); // I usually call the base class AFTER my processing

            }

            ~RaGE(); [edit] I wrote teh same as Shog because I forgot to post my message right away... Nevermind, and great to see we are on the same wave length [/edit] -- modified at 10:01 Wednesday 15th February, 2006

            2 Offline
            2 Offline
            23_444
            wrote on last edited by
            #5

            I think you both missed my message. You have to intercept the WM_CLOSE message. If you don't you are 1. Not Destroying your window till your parent is closed. 2. Therefore you PostNcDestroy is not run until your parent is closed 3. Therefore, how does your app know that the pointer is no longer valid. You can run GetSafeWnd all day long - it still points to valid memory...cause you never bothered to delete the CWnd object...until the parent is closed. So back to my original question please.

            S 1 Reply Last reply
            0
            • 2 23_444

              I think you both missed my message. You have to intercept the WM_CLOSE message. If you don't you are 1. Not Destroying your window till your parent is closed. 2. Therefore you PostNcDestroy is not run until your parent is closed 3. Therefore, how does your app know that the pointer is no longer valid. You can run GetSafeWnd all day long - it still points to valid memory...cause you never bothered to delete the CWnd object...until the parent is closed. So back to my original question please.

              S Offline
              S Offline
              Shog9 0
              wrote on last edited by
              #6

              mx483 wrote:

              1. Not Destroying your window till your parent is closed.

              Sorry, i guess i missed that. Sounds like you're missing a few things in your implementation, so i'll go over the steps to doing a proper modeless dialog in MFC:

              1. Create with Create(), followed by ShowWindow(), not DoModal() (i'm sure you're already doing this :) )
              2. Never call EndModalLoop() (or EndDialog())
              3. Never let the default behavior run when it will end up doing what you avoided in #1 or #2
              • No default behavior for OnOK() or OnCancel() (WM_COMMAND handlers for IDOK and IDCANCEL)
              • Be aware that the default behavior for WM_CLOSE just posts a WM_COMMAND for IDCANCEL (so it'll end up calling IDCANCEL)
              • Be aware that various keys can trigger OnCancel()/OnOK() directly (ENTER, ESC) or indirectly (Alt+F4 -> WM_CLOSE -> OnCancel()). So you really do need to override these commands, even if you don't have an explicit IDOK or IDCANCEL button on your dialog.

              So the likely explanation for the behavior you describe is that you're letting the baseclass call EndModalLoop(), which just hides the window. Then when the parent is destroyed, its (now hidden) children are also destroyed, causing the wave of delayed destruction you noticed. So your fix is simple: override OnOK() and OnCancel() and cause them to call DestroyWindow() rather than the baseclass implementation. Optionally, do the same for OnClose() (isn't necessary, but will make it more obvious what you're doing). And i'd still encourage you to avoid messing with data in the parent window class (and especially doing delete this). Nothing absolutely wrong with it, but it's messy - let the owner handle that stuff.

              ---- Scripts i've known... CPhog 0.9.9 - make CP better. Forum Bookmark 0.2.5 - bookmark forum posts on Pensieve

              2 1 Reply Last reply
              0
              • S Shog9 0

                mx483 wrote:

                1. Not Destroying your window till your parent is closed.

                Sorry, i guess i missed that. Sounds like you're missing a few things in your implementation, so i'll go over the steps to doing a proper modeless dialog in MFC:

                1. Create with Create(), followed by ShowWindow(), not DoModal() (i'm sure you're already doing this :) )
                2. Never call EndModalLoop() (or EndDialog())
                3. Never let the default behavior run when it will end up doing what you avoided in #1 or #2
                • No default behavior for OnOK() or OnCancel() (WM_COMMAND handlers for IDOK and IDCANCEL)
                • Be aware that the default behavior for WM_CLOSE just posts a WM_COMMAND for IDCANCEL (so it'll end up calling IDCANCEL)
                • Be aware that various keys can trigger OnCancel()/OnOK() directly (ENTER, ESC) or indirectly (Alt+F4 -> WM_CLOSE -> OnCancel()). So you really do need to override these commands, even if you don't have an explicit IDOK or IDCANCEL button on your dialog.

                So the likely explanation for the behavior you describe is that you're letting the baseclass call EndModalLoop(), which just hides the window. Then when the parent is destroyed, its (now hidden) children are also destroyed, causing the wave of delayed destruction you noticed. So your fix is simple: override OnOK() and OnCancel() and cause them to call DestroyWindow() rather than the baseclass implementation. Optionally, do the same for OnClose() (isn't necessary, but will make it more obvious what you're doing). And i'd still encourage you to avoid messing with data in the parent window class (and especially doing delete this). Nothing absolutely wrong with it, but it's messy - let the owner handle that stuff.

                ---- Scripts i've known... CPhog 0.9.9 - make CP better. Forum Bookmark 0.2.5 - bookmark forum posts on Pensieve

                2 Offline
                2 Offline
                23_444
                wrote on last edited by
                #7

                Bingo! Hey thanks, Here was where I wasn't understanding: Be aware that the default behavior for WM_CLOSE just posts a WM_COMMAND for IDCANCEL (so it'll end up calling IDCANCEL). Thanks for taking the time to write again and explaining why the window wasn't really destroyed when the WM_CLOSE was called. I'll also strongly consider your other suggestions. :)

                1 Reply Last reply
                0
                • 2 23_444

                  Need your thoughts and/or opinion. Question at the bottom. When user closes the modeless dialog box you can trap the WM_CLOSE message to insure proper cleanup. According to Help CWnd::OnClose The framework calls this member function as a signal that the CWnd or an application is to terminate. The default implementation calls DestroyWindow. I found two ways to approach the user who closes the modeless dialog box by clicking the x on the upper right hand corner of the window Looking at the first example below. I found out that if you don't call DestroyWindow() from your OnClose() and you don't want multiple instances of your modeless opened you will need to set the pointer to NULL here (otherwise your pointer value can't be used as a flag to prohibit other instances of your modeless dialog from being opened). PostNcDestroy apparently isn't run until the parent is destroyed. Once the parent/owner is closed then a PostNcDestroy is run for each modeless that opened - one right after another. void CDialogDerived::OnClose() { CDialog::OnClose(); m_pParent->m_pModelessDialog = NULL; } void CDialogDerived::PostNcDestroy() { CDialog::PostNcDestroy(); m_pParent->m_pModelessDialog = NULL; //in case destroy window is called from your code and OnClose is never run delete this; } Example 2. This seems like a cleaner approach as the Dialog is destroyed immediately and thus your pointer is set to NULL immediately void CDialogDerived::OnClose() { CDialog::OnClose(); DestroyWindow(); } void CDialogDerived::PostNcDestroy() { CDialog::PostNcDestroy(); m_pParent->m_pModelessDialog = NULL; delete this; } Any thoughts pro and con to either of these approaches? I'm curious why the PostNcDestroy is not run promptly with the OnClose call on the first example. Thanks!

                  2 Offline
                  2 Offline
                  23_444
                  wrote on last edited by
                  #8

                  I believe that fact that the Dialog was not getting destroyed was because the WM_CLOSE message is being overridden by CDialog and calling and IDCANCEL. That would make sense. Before I posted the question though I attempted to follow the WM_CLOSE message to see where it was going - hence the reference to CWnd::Close from Help at the top of the question. When I put a break point at the OnClose function -user clicks the x at upper right hand part of dialog(Created through ClassWizard capturing the WM_CLOSE message) I am lead to this. _AFXWIN_INLINE void CWnd::OnClose() { Default(); } Continuing I am lead to LRESULT CWnd::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam) Message being passed is 16 and IDCANCEL is defined as 2 Now I'm scratching my head. Wouldn't I see an IDCANCEL call or something like that. CWnd is supposed to destroy the window Thanks

                  S 1 Reply Last reply
                  0
                  • 2 23_444

                    I believe that fact that the Dialog was not getting destroyed was because the WM_CLOSE message is being overridden by CDialog and calling and IDCANCEL. That would make sense. Before I posted the question though I attempted to follow the WM_CLOSE message to see where it was going - hence the reference to CWnd::Close from Help at the top of the question. When I put a break point at the OnClose function -user clicks the x at upper right hand part of dialog(Created through ClassWizard capturing the WM_CLOSE message) I am lead to this. _AFXWIN_INLINE void CWnd::OnClose() { Default(); } Continuing I am lead to LRESULT CWnd::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam) Message being passed is 16 and IDCANCEL is defined as 2 Now I'm scratching my head. Wouldn't I see an IDCANCEL call or something like that. CWnd is supposed to destroy the window Thanks

                    S Offline
                    S Offline
                    Shog9 0
                    wrote on last edited by
                    #9

                    (btw - no harm in starting a new thread with offshoot topics like this :) ) This question takes you into the fun and exciting world of Classic Win32. Well, perhaps i'm being generous with "fun and exciting"... but anyway... In a nutshell, this is how it works: in basic ol' Win32 (and Win16 for that matter), dialogs are not quite the same as "regular" windows. They aren't created in the same way, they don't get passed messages in the same way, and the default behavior for unprocessed messages isn't the same either. MFC does a lot to hide this from you, but at its core it still behaves in much the same way. Which makes things interesting when you're creating a non-modal by deriving a class from CDialog, because you inherit a lot of defaults that you really don't want. And one of those behaviors is what happens when you call ::DefWindowProc() with WM_CLOSE as the message. As you've found, dialogs do not call DestroyWindow() - they post WM_COMMAND with WPARAM set to 2 (IDCANCEL). And because the message is posted, you don't get a nice call stack leading back to OnClose() from OnCancel(). Why is this so? Because you don't close dialogs - real modal dialogs - by calling DestroyWindow(). They have their own message loops that need to be cleaned up, and those take care of actually destroying the window, so you call EndModalLoop() in MFC, or EndDialog() in Win32. And that is what the default behavior for OnClose()/OnOk() end up doing... which as you've noticed, is nearly useless for non-modal dialogs.

                    ---- Scripts i've known... CPhog 0.9.9 - make CP better. Forum Bookmark 0.2.5 - bookmark forum posts on Pensieve Print forum 0.1.1 - printer-friendly forums

                    2 1 Reply Last reply
                    0
                    • S Shog9 0

                      (btw - no harm in starting a new thread with offshoot topics like this :) ) This question takes you into the fun and exciting world of Classic Win32. Well, perhaps i'm being generous with "fun and exciting"... but anyway... In a nutshell, this is how it works: in basic ol' Win32 (and Win16 for that matter), dialogs are not quite the same as "regular" windows. They aren't created in the same way, they don't get passed messages in the same way, and the default behavior for unprocessed messages isn't the same either. MFC does a lot to hide this from you, but at its core it still behaves in much the same way. Which makes things interesting when you're creating a non-modal by deriving a class from CDialog, because you inherit a lot of defaults that you really don't want. And one of those behaviors is what happens when you call ::DefWindowProc() with WM_CLOSE as the message. As you've found, dialogs do not call DestroyWindow() - they post WM_COMMAND with WPARAM set to 2 (IDCANCEL). And because the message is posted, you don't get a nice call stack leading back to OnClose() from OnCancel(). Why is this so? Because you don't close dialogs - real modal dialogs - by calling DestroyWindow(). They have their own message loops that need to be cleaned up, and those take care of actually destroying the window, so you call EndModalLoop() in MFC, or EndDialog() in Win32. And that is what the default behavior for OnClose()/OnOk() end up doing... which as you've noticed, is nearly useless for non-modal dialogs.

                      ---- Scripts i've known... CPhog 0.9.9 - make CP better. Forum Bookmark 0.2.5 - bookmark forum posts on Pensieve Print forum 0.1.1 - printer-friendly forums

                      2 Offline
                      2 Offline
                      23_444
                      wrote on last edited by
                      #10

                      Yeah, its starting to make sense. But why when I hovered over the nMsg in the DefWindowProc did the message come back as 16. I know IDCANCEL is 2 #define IDOK 1 #define IDCANCEL 2 #define IDABORT 3 #define IDRETRY 4 #define IDIGNORE 5 #define IDYES 6 #define IDNO 7 #if(WINVER >= 0x0400) #define IDCLOSE 8 #define IDHELP 9 Still scratching. Oh and by the way thanks for your help.

                      S 1 Reply Last reply
                      0
                      • 2 23_444

                        Yeah, its starting to make sense. But why when I hovered over the nMsg in the DefWindowProc did the message come back as 16. I know IDCANCEL is 2 #define IDOK 1 #define IDCANCEL 2 #define IDABORT 3 #define IDRETRY 4 #define IDIGNORE 5 #define IDYES 6 #define IDNO 7 #if(WINVER >= 0x0400) #define IDCLOSE 8 #define IDHELP 9 Still scratching. Oh and by the way thanks for your help.

                        S Offline
                        S Offline
                        Shog9 0
                        wrote on last edited by
                        #11

                        Here's a little trick: in the debugger, put a number (or variable) in the watch window, and follow the name with , wm - it'll display the name of the window message that the number maps to. But you're not gonna see IDCANCEL being passed in nMsg anyway - it's passed in the wparam field, while the message is WM_COMMAND.

                        ---- Scripts i've known... CPhog 0.9.9 - make CP better. Forum Bookmark 0.2.5 - bookmark forum posts on Pensieve Print forum 0.1.1 - printer-friendly forums

                        2 1 Reply Last reply
                        0
                        • S Shog9 0

                          Here's a little trick: in the debugger, put a number (or variable) in the watch window, and follow the name with , wm - it'll display the name of the window message that the number maps to. But you're not gonna see IDCANCEL being passed in nMsg anyway - it's passed in the wparam field, while the message is WM_COMMAND.

                          ---- Scripts i've known... CPhog 0.9.9 - make CP better. Forum Bookmark 0.2.5 - bookmark forum posts on Pensieve Print forum 0.1.1 - printer-friendly forums

                          2 Offline
                          2 Offline
                          23_444
                          wrote on last edited by
                          #12

                          Sounds neat, I wish I could get it to work. Both wparam and lparam are zero with nMsg = 16. I using Visual C++ 6.0 so maybe the watch stuff is a new edition. IDCANCEL, wm gives me an error message in the watch window. I also looked up the value of WM_COMMAND and it is 273

                          S 1 Reply Last reply
                          0
                          • 2 23_444

                            Sounds neat, I wish I could get it to work. Both wparam and lparam are zero with nMsg = 16. I using Visual C++ 6.0 so maybe the watch stuff is a new edition. IDCANCEL, wm gives me an error message in the watch window. I also looked up the value of WM_COMMAND and it is 273

                            S Offline
                            S Offline
                            Shog9 0
                            wrote on last edited by
                            #13

                            mx483 wrote:

                            IDCANCEL, wm gives me an error message in the watch window.

                            Wrong way about. Try: 16, wm or nMsg, wm Put a breakpoint in OnCancel(), and look up the callstack when it gets hit - you'll see WM_COMMAND being processed then.

                            ---- Scripts i've known... CPhog 0.9.9 - make CP better. Forum Bookmark 0.2.5 - bookmark forum posts on Pensieve Print forum 0.1.1 - printer-friendly forums

                            2 1 Reply Last reply
                            0
                            • S Shog9 0

                              mx483 wrote:

                              IDCANCEL, wm gives me an error message in the watch window.

                              Wrong way about. Try: 16, wm or nMsg, wm Put a breakpoint in OnCancel(), and look up the callstack when it gets hit - you'll see WM_COMMAND being processed then.

                              ---- Scripts i've known... CPhog 0.9.9 - make CP better. Forum Bookmark 0.2.5 - bookmark forum posts on Pensieve Print forum 0.1.1 - printer-friendly forums

                              2 Offline
                              2 Offline
                              23_444
                              wrote on last edited by
                              #14

                              Thanks for being so patient. Yep It works, it was case sensitive. I see where the WM_CLOSE message is being posted. I can keep pressing F11 and trace into the functions where finally the DefWindowProc shows up. Then I can go to the call stack and see all this too. I think I'm back to wondering why (according to you) I should be seeing a WM_COMMAND message instead of a WM_CLOSE message. Hey thanks you are teaching me a bunch!

                              S 1 Reply Last reply
                              0
                              • 2 23_444

                                Thanks for being so patient. Yep It works, it was case sensitive. I see where the WM_CLOSE message is being posted. I can keep pressing F11 and trace into the functions where finally the DefWindowProc shows up. Then I can go to the call stack and see all this too. I think I'm back to wondering why (according to you) I should be seeing a WM_COMMAND message instead of a WM_CLOSE message. Hey thanks you are teaching me a bunch!

                                S Offline
                                S Offline
                                Shog9 0
                                wrote on last edited by
                                #15

                                mx483 wrote:

                                I think I'm back to wondering why (according to you) I should be seeing a WM_COMMAND message instead of a WM_CLOSE message.

                                You'll see both - WM_CLOSE first, then (if you let the default handler handle it) WM_COMMAND.

                                ---- Scripts i've known... CPhog 0.9.9 - make CP better. Forum Bookmark 0.2.5 - bookmark forum posts on Pensieve Print forum 0.1.1 - printer-friendly forums

                                2 1 Reply Last reply
                                0
                                • S Shog9 0

                                  mx483 wrote:

                                  I think I'm back to wondering why (according to you) I should be seeing a WM_COMMAND message instead of a WM_CLOSE message.

                                  You'll see both - WM_CLOSE first, then (if you let the default handler handle it) WM_COMMAND.

                                  ---- Scripts i've known... CPhog 0.9.9 - make CP better. Forum Bookmark 0.2.5 - bookmark forum posts on Pensieve Print forum 0.1.1 - printer-friendly forums

                                  2 Offline
                                  2 Offline
                                  23_444
                                  wrote on last edited by
                                  #16

                                  Thanks for your patience and thoughtful comments. Jay

                                  1 Reply Last reply
                                  0
                                  Reply
                                  • Reply as topic
                                  Log in to reply
                                  • Oldest to Newest
                                  • Newest to Oldest
                                  • Most Votes


                                  • Login

                                  • Don't have an account? Register

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular
                                  • World
                                  • Users
                                  • Groups