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 with Message Loop

Modeless Dialog with Message Loop

Scheduled Pinned Locked Moved C / C++ / MFC
comhelp
24 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.
  • M Manish K Agarwal

    Thanks a lot. PeekMessage approach is working with a small correction if (!bRet) to if (**bRet**) i.e. removed NOT operator.

    Manish Agarwal manish.k.agarwal @ gmail DOT com

    P Offline
    P Offline
    pasztorpisti
    wrote on last edited by
    #4

    You are welcome! I haven't put in any checks on my PeekMessage() so you couldn't negate it! :-) Both peekmessage and getmessage are needed, with careful parametrization of PeekMessage(). Of course the PeekMessage doc says that it returns nozero if there is a message available so you have to check for (bRet). Can you please post the resulting code? We may be able to spot other errors and it can help other people in the future.

    1 Reply Last reply
    0
    • M Manish K Agarwal

      Thanks a lot. PeekMessage approach is working with a small correction if (!bRet) to if (**bRet**) i.e. removed NOT operator.

      Manish Agarwal manish.k.agarwal @ gmail DOT com

      P Offline
      P Offline
      pasztorpisti
      wrote on last edited by
      #5

      I have already found a bug in my solution: If there is no message in the queue when PeekMessage() is executed then control is immediately transferred to the GetMessage() call so the next incoming message will be removed for sure by your loop no matter what the message is. To avoid this you should probably call WaitMessage() before PeekMessage().

      M 1 Reply Last reply
      0
      • P pasztorpisti

        I have already found a bug in my solution: If there is no message in the queue when PeekMessage() is executed then control is immediately transferred to the GetMessage() call so the next incoming message will be removed for sure by your loop no matter what the message is. To avoid this you should probably call WaitMessage() before PeekMessage().

        M Offline
        M Offline
        Manish K Agarwal
        wrote on last edited by
        #6

        My final code looks like as below and it does not require handling of WM_SYSCOMMAND/SC_CLOSE or any other message as my test shows that we always get WM_CLOSE irrespective of how we are closing it.

        for (;;)
        {
        WaitMessage();
        PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE);

        if (Msg.message == WM_CLOSE)
        {
        // Do not remove the WM_CLOSE from message Queue and leave it for IE.
        break;
        }

        BOOL bRet = GetMessage(&Msg, NULL, 0, 0);
        if (!bRet)
        break;

        // original code from your while loop
        if (PreTranslateMessage( &Msg ) == 0 )
        {
        if (m_MainDialog.m_hWnd == (HWND) NULL || !::IsDialogMessage(m_MainDialog.m_hWnd, &Msg))
        {
        TranslateMessage( &Msg );
        DispatchMessage(&Msg);
        }
        }

        if (m_MainDialog.bClosed == true)
        {
        break;
        }
        }

        Manish Agarwal manish.k.agarwal @ gmail DOT com

        P 1 Reply Last reply
        0
        • M Manish K Agarwal

          My final code looks like as below and it does not require handling of WM_SYSCOMMAND/SC_CLOSE or any other message as my test shows that we always get WM_CLOSE irrespective of how we are closing it.

          for (;;)
          {
          WaitMessage();
          PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE);

          if (Msg.message == WM_CLOSE)
          {
          // Do not remove the WM_CLOSE from message Queue and leave it for IE.
          break;
          }

          BOOL bRet = GetMessage(&Msg, NULL, 0, 0);
          if (!bRet)
          break;

          // original code from your while loop
          if (PreTranslateMessage( &Msg ) == 0 )
          {
          if (m_MainDialog.m_hWnd == (HWND) NULL || !::IsDialogMessage(m_MainDialog.m_hWnd, &Msg))
          {
          TranslateMessage( &Msg );
          DispatchMessage(&Msg);
          }
          }

          if (m_MainDialog.bClosed == true)
          {
          break;
          }
          }

          Manish Agarwal manish.k.agarwal @ gmail DOT com

          P Offline
          P Offline
          pasztorpisti
          wrote on last edited by
          #7

          Thank you for posting, WM_CLOSE should be okay. You don't check the return value of PeekMessage (that should always be zero but its better to make sure...) and you should check Msg.hwnd whether its the main window hwnd or something else (it could be one of your dialog hwnds or any other HWND inside the IE process). I would write "if (PeekMessage()) { check for WM_CLOSE }". You can get the main window hwnd by performing the following operation on one of your activex hwnds that are placed directly/indirectly on your main window:

          HWND GetRootWindow(HWND hwnd)
          {
          for (;;)
          {
          HWND parent = GetParent(hwnd);
          if (!parent)
          return hwnd;
          hwnd = parent;
          }
          }

          WM_SYSCOMMAND/SC_CLOSE is gui specific (it indicates that someone pressed X on the window), noone should put critical handling on this message as your window can easily get simulated WM_CLOSE messages without gui interaction/WM_SYSCOMMAND/SC_CLOSE.

          M 1 Reply Last reply
          0
          • P pasztorpisti

            Thank you for posting, WM_CLOSE should be okay. You don't check the return value of PeekMessage (that should always be zero but its better to make sure...) and you should check Msg.hwnd whether its the main window hwnd or something else (it could be one of your dialog hwnds or any other HWND inside the IE process). I would write "if (PeekMessage()) { check for WM_CLOSE }". You can get the main window hwnd by performing the following operation on one of your activex hwnds that are placed directly/indirectly on your main window:

            HWND GetRootWindow(HWND hwnd)
            {
            for (;;)
            {
            HWND parent = GetParent(hwnd);
            if (!parent)
            return hwnd;
            hwnd = parent;
            }
            }

            WM_SYSCOMMAND/SC_CLOSE is gui specific (it indicates that someone pressed X on the window), noone should put critical handling on this message as your window can easily get simulated WM_CLOSE messages without gui interaction/WM_SYSCOMMAND/SC_CLOSE.

            M Offline
            M Offline
            Manish K Agarwal
            wrote on last edited by
            #8

            Thanks again for your detailed reply. I will take care of this.

            Manish Agarwal manish.k.agarwal @ gmail DOT com

            P 2 Replies Last reply
            0
            • M Manish K Agarwal

              I am creating a modeless dialog from an ActiveX which loads in the Internet Explorer 9/Windows 7 using following code: Where CMyActiveXCtrl class is of COleControl type.

              void CMyActiveXCtrl::OnBnClickedTest()
              {
              m_MainDialog.bClosed = false;
              m_MainDialog.ShowWindow( SW_SHOW );

              MSG Msg;

              BOOL bRet;

              while (bRet = GetMessage(&Msg, NULL, 0, 0))
              {
              if (bRet == -1)
              {
              MessageBoxA(this->m_hWnd, "Message loop error", "My ActiveX", MB_OK);
              break;
              }

                   if (PreTranslateMessage( &Msg ) == 0 )
                   {
                        if (!::IsDialogMessage(m\_MainDialog.m\_hWnd, &Msg)) 
                        { 
                            TranslateMessage( &Msg );
                            DispatchMessage(&Msg);
                        }
                   }
              
                   if (m\_MainDialog.bClosed == true)
                   {
                       break;
                   }
              

              }// while
              }

              m_MainDialog.bClosed set true on modeless dialog close/destroy. Now when my modeless dialog is opened in ActiveX and the user closes the browser window using IE > File > Exit or clicks on top right "X" button, IE main windows closes (no longer visible) but it leaves an orphan IE process in the task manager. The same code working fine on Windows XP/ IE 8. Can anyone suggest me what could be the problem with above message loop in OnBnClickedTest() else without that message loop, it works fine.

              Manish Agarwal manish.k.agarwal @ gmail DOT com

              E Offline
              E Offline
              Erudite_Eric
              wrote on last edited by
              #9

              There is one message pump and one message handler per process, why would you want to duplicate the message pump of IE in a dialog box onclick handler? Its uterly stupid.

              P 1 Reply Last reply
              0
              • M Manish K Agarwal

                Thanks again for your detailed reply. I will take care of this.

                Manish Agarwal manish.k.agarwal @ gmail DOT com

                P Offline
                P Offline
                pasztorpisti
                wrote on last edited by
                #10

                Later when I have time I will post the object oriented version (with Thread class) of the sample code, you can probably still learn a lot from these small examples.

                1 Reply Last reply
                0
                • M Manish K Agarwal

                  Thanks again for your detailed reply. I will take care of this.

                  Manish Agarwal manish.k.agarwal @ gmail DOT com

                  P Offline
                  P Offline
                  pasztorpisti
                  wrote on last edited by
                  #11

                  You are welcome! Ignore my previous post, I posted something here and the deleted it later but you probably received a mail notification! :-)

                  1 Reply Last reply
                  0
                  • E Erudite_Eric

                    There is one message pump and one message handler per process, why would you want to duplicate the message pump of IE in a dialog box onclick handler? Its uterly stupid.

                    P Offline
                    P Offline
                    pasztorpisti
                    wrote on last edited by
                    #12

                    For example because he may want dialogbox features on his dialog using IsDialogMessage() that wouldn't be done by the main loop of IE. Such dialogbox features include for example hotkeys like closing the dialog with ENTER/ESC, traversing the controls with TAB. Of course this own loop is a bit hacky but still can be a good balance between invested time and functionality. Sometimes its not you writing the code - it can be heritage from another guy who worked for the company years ago and your boss wont give you time to put together a better solution especially if the current one works in a more or less satisfactory way. The world is not perfect, and one day you will have to realize this.

                    E 2 Replies Last reply
                    0
                    • P pasztorpisti

                      For example because he may want dialogbox features on his dialog using IsDialogMessage() that wouldn't be done by the main loop of IE. Such dialogbox features include for example hotkeys like closing the dialog with ENTER/ESC, traversing the controls with TAB. Of course this own loop is a bit hacky but still can be a good balance between invested time and functionality. Sometimes its not you writing the code - it can be heritage from another guy who worked for the company years ago and your boss wont give you time to put together a better solution especially if the current one works in a more or less satisfactory way. The world is not perfect, and one day you will have to realize this.

                      E Offline
                      E Offline
                      Erudite_Eric
                      wrote on last edited by
                      #13

                      You never heard of windows hooks then?

                      1 Reply Last reply
                      0
                      • P pasztorpisti

                        For example because he may want dialogbox features on his dialog using IsDialogMessage() that wouldn't be done by the main loop of IE. Such dialogbox features include for example hotkeys like closing the dialog with ENTER/ESC, traversing the controls with TAB. Of course this own loop is a bit hacky but still can be a good balance between invested time and functionality. Sometimes its not you writing the code - it can be heritage from another guy who worked for the company years ago and your boss wont give you time to put together a better solution especially if the current one works in a more or less satisfactory way. The world is not perfect, and one day you will have to realize this.

                        E Offline
                        E Offline
                        Erudite_Eric
                        wrote on last edited by
                        #14

                        You still havent answered. Just because a dialog is interested in some messages and register for them why should it duplicate the message pump? Thwere is one message pumop, one queue, one handler per process. Period.

                        P 1 Reply Last reply
                        0
                        • E Erudite_Eric

                          You still havent answered. Just because a dialog is interested in some messages and register for them why should it duplicate the message pump? Thwere is one message pumop, one queue, one handler per process. Period.

                          P Offline
                          P Offline
                          pasztorpisti
                          wrote on last edited by
                          #15

                          The hook can indeed be a good solution. This still isn't a reason for you to talk to other people here using an arrogant style with degrading words. You can be the best programmer in the world if you are missing basic social skills and the respect towards others, noone wants people like you in his team. Respect is mutual or nonexistent.

                          E 1 Reply Last reply
                          0
                          • P pasztorpisti

                            The hook can indeed be a good solution. This still isn't a reason for you to talk to other people here using an arrogant style with degrading words. You can be the best programmer in the world if you are missing basic social skills and the respect towards others, noone wants people like you in his team. Respect is mutual or nonexistent.

                            E Offline
                            E Offline
                            Erudite_Eric
                            wrote on last edited by
                            #16

                            Forget hooking, why shouold there be a duplicate message pump in the process? Dont you think it is stupid?

                            P 1 Reply Last reply
                            0
                            • E Erudite_Eric

                              Forget hooking, why shouold there be a duplicate message pump in the process? Dont you think it is stupid?

                              P Offline
                              P Offline
                              pasztorpisti
                              wrote on last edited by
                              #17

                              It is not stupid, but its an ugly workaround to a problem that has no fine solution. This own message loop workaround has several problems: it runs as long as our modeless dialogs are open and during this time it serves the messages to other windows as well, in this case if IE had its own modeless dialogs then dialog features wouldn't work on those dialogs as those are handled by IE's main message loops (same is true for other possible features that are implemented in the main loop of IE). We could probably find even more problems with this solution. The question is: how much time is available for the asker to finish this job and how much risk he takes if he chooses to implement dialog features for himself in his own dialogs by going with the message loop of IE. Sadly, programming for companies is often about saving time and playing safe and not taking risks for delivering correct solutions (unlike in hobby projects) especially if that would involve modifying legacy code that "still works". There are cases where the own loop is fine: for example the winapi MessageBox() does this (but its a modal dialog) and windows also running its own loop while you are moving a window by grabbing its title bar (and there can be other cases). There are probably many other cases where the own loop can be appropriate but a modeless dialog is definitely not among those.

                              E 1 Reply Last reply
                              0
                              • P pasztorpisti

                                It is not stupid, but its an ugly workaround to a problem that has no fine solution. This own message loop workaround has several problems: it runs as long as our modeless dialogs are open and during this time it serves the messages to other windows as well, in this case if IE had its own modeless dialogs then dialog features wouldn't work on those dialogs as those are handled by IE's main message loops (same is true for other possible features that are implemented in the main loop of IE). We could probably find even more problems with this solution. The question is: how much time is available for the asker to finish this job and how much risk he takes if he chooses to implement dialog features for himself in his own dialogs by going with the message loop of IE. Sadly, programming for companies is often about saving time and playing safe and not taking risks for delivering correct solutions (unlike in hobby projects) especially if that would involve modifying legacy code that "still works". There are cases where the own loop is fine: for example the winapi MessageBox() does this (but its a modal dialog) and windows also running its own loop while you are moving a window by grabbing its title bar (and there can be other cases). There are probably many other cases where the own loop can be appropriate but a modeless dialog is definitely not among those.

                                E Offline
                                E Offline
                                Erudite_Eric
                                wrote on last edited by
                                #18

                                You have already suggested using IsDialogMessage() so the dialog can register to receive required messages from the processes message handler. This is the suggested way of doing it so putting your own message pump in the dialog and peeking at messages IS stupid. Any suggestion that bad code should be implemented OR maintained is also stupid. If it is crap, chuck it out. Code is either 100% perfect or it is junk. Period. (I have spent 16 years in the WIndows kernel where this law is absoloutely true. ONE bug, and its a BSOD. Its either 100% perfect or unusable junk. )

                                P 1 Reply Last reply
                                0
                                • E Erudite_Eric

                                  You have already suggested using IsDialogMessage() so the dialog can register to receive required messages from the processes message handler. This is the suggested way of doing it so putting your own message pump in the dialog and peeking at messages IS stupid. Any suggestion that bad code should be implemented OR maintained is also stupid. If it is crap, chuck it out. Code is either 100% perfect or it is junk. Period. (I have spent 16 years in the WIndows kernel where this law is absoloutely true. ONE bug, and its a BSOD. Its either 100% perfect or unusable junk. )

                                  P Offline
                                  P Offline
                                  pasztorpisti
                                  wrote on last edited by
                                  #19

                                  Nothing is 100% perfect. Period. This is true even for drivers and we experience this at least monthly here (usb drivers for android, various drivers for 3d graphics). The size of driver code is usually much less than the legacy enterprise software codebase of some corporations so keeping drivers tidy is much easier than doing the same with some other software - especially because at a driver developer company you are probably expected to invest time in perfecting things while some other companies have to prioritize which part of the codebase to develop and you have time only to maintain the rest. It is usually not the programmer who decides about priorities.

                                  E 1 Reply Last reply
                                  0
                                  • P pasztorpisti

                                    Nothing is 100% perfect. Period. This is true even for drivers and we experience this at least monthly here (usb drivers for android, various drivers for 3d graphics). The size of driver code is usually much less than the legacy enterprise software codebase of some corporations so keeping drivers tidy is much easier than doing the same with some other software - especially because at a driver developer company you are probably expected to invest time in perfecting things while some other companies have to prioritize which part of the codebase to develop and you have time only to maintain the rest. It is usually not the programmer who decides about priorities.

                                    E Offline
                                    E Offline
                                    Erudite_Eric
                                    wrote on last edited by
                                    #20

                                    pasztorpisti wrote:

                                    Nothing is 100% perfect.

                                    So says someone who has never worked in the kernel...

                                    pasztorpisti wrote:

                                    usb drivers

                                    I didnt say all kernel engineers are perfect and the fact their crap code is so apparent to you is an indication that lack of perfection in kernel code is readilly apparent. Everything else you say is wrong and inexcusable. Yes there are crap companies, crap code and crap engineers. However it is your choice whether to be one or not.

                                    P 1 Reply Last reply
                                    0
                                    • E Erudite_Eric

                                      pasztorpisti wrote:

                                      Nothing is 100% perfect.

                                      So says someone who has never worked in the kernel...

                                      pasztorpisti wrote:

                                      usb drivers

                                      I didnt say all kernel engineers are perfect and the fact their crap code is so apparent to you is an indication that lack of perfection in kernel code is readilly apparent. Everything else you say is wrong and inexcusable. Yes there are crap companies, crap code and crap engineers. However it is your choice whether to be one or not.

                                      P Offline
                                      P Offline
                                      pasztorpisti
                                      wrote on last edited by
                                      #21

                                      Erudite_Eric wrote:

                                      So says someone who has never worked in the kernel...

                                      So says someone who thinks he knows everything... Are you sure about that statement? Maybe you are a mind reader, but I doubt that... You should stop insulting people and degrading others on the forum. You should search for a hacker forum that is usually full of people going with a style like yours. Maybe you are a good technician but at the same time you are like a 15 years old boy comparing his penis to that others'. This forum is here to help others with solutions not to offend and degrade each other. If you think you have a better solution to the problem than the ones already posted then submit yours without offending others. There is a difference between debate and offense/degrading words and you seemingly don't know where the line is between the two.

                                      E 1 Reply Last reply
                                      0
                                      • P pasztorpisti

                                        Erudite_Eric wrote:

                                        So says someone who has never worked in the kernel...

                                        So says someone who thinks he knows everything... Are you sure about that statement? Maybe you are a mind reader, but I doubt that... You should stop insulting people and degrading others on the forum. You should search for a hacker forum that is usually full of people going with a style like yours. Maybe you are a good technician but at the same time you are like a 15 years old boy comparing his penis to that others'. This forum is here to help others with solutions not to offend and degrade each other. If you think you have a better solution to the problem than the ones already posted then submit yours without offending others. There is a difference between debate and offense/degrading words and you seemingly don't know where the line is between the two.

                                        E Offline
                                        E Offline
                                        Erudite_Eric
                                        wrote on last edited by
                                        #22

                                        So you have worked in the Windows kernel? What drivers did you write?

                                        pasztorpisti wrote:

                                        This forum is here to help others with solutions

                                        and not to give them stupid advice.

                                        P 1 Reply Last reply
                                        0
                                        • E Erudite_Eric

                                          So you have worked in the Windows kernel? What drivers did you write?

                                          pasztorpisti wrote:

                                          This forum is here to help others with solutions

                                          and not to give them stupid advice.

                                          P Offline
                                          P Offline
                                          pasztorpisti
                                          wrote on last edited by
                                          #23

                                          I never worked with the windows kernel and wrote drivers only for linux for newly created hardware pieces several years ago. In my opinion programming kernel is just like programming anything else with a different api and a bit different rules and more pain in the ass. That's it. By the way, the kernel has nothing to do with the question into which we are posting this useless stuff. And sorry but this is the end of our conversation. I'm visiting codeproject to spend a little of my free time with useful things like helping others and solve technical problems/debating about them. Comparing penises is not my business.

                                          E 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