No announcement yet.

More Message loop

  • Filter
  • Time
  • Show
Clear All
new posts

  • More Message loop

    This snippet is a message loop of sorts, but it does not terminate the application.

    While GetMessage(Msg, %NULL, 0, 0)
    If Msg.wParam=%WM_QUIT Then Exit Loop
    TranslateMessage Msg
    DispatchMessage Msg
    Function = Msg.wParam
    If Msg.wParam=%WM_QUIT Then Call PostQuitMessage (Msg.wParam)

    On quitting, the screen returns to the code page in the IDE (or the desktop if running the exe directly) but Ctrl+Alt+Del shows that the app is still running, and it then has to be terminated by quitting it in that window and the one it brings up in turn.

    The above additions re WM_QUIT is from Windows API help.

    The code sits at the tail of the main dialog and should not be there at all, since this on is modal. But on quitting a subsequent MODELESS sub-dialog, the intention is NOT to quit the app.

    What is the correct way to terminate an app, please, anybody?

  • #2

    You normally test if GetMessage() returns zero. That is done from
    your message handling proc, commonly called the WndProc function.

    This is a snippet of code that sends the PostQuitMessage that in
    turn allows GetMessage() to return zero and exit the Message Loop.

    Case %WM_DESTROY
    PostQuitMessage 0
    Exit Function

    If you are going to use a message loop, you are basically stuck
    with processing the actual messages in the message handling proc.

    There are a number of clear templates around that show the correct
    way to construct a message loop and message handling procedure.

    If you don't have one handy, you can try the code generator from
    my web sute that does this in the normal manner.

    Get the file called, it builds normal windows templates.

    Good luck,

    [email protected]

    hutch at movsd dot com
    The MASM Forum - SLL Modules and PB Libraries


    • #3
      A "normal" message pump for an SDK-style application looks like this:
      DIM wMsg&, Msg AS TAGMSG
        wMsg& = GetMessage(Msg, %NULL, 0, 0)
        TranslateMessage Msg
        DispatchMessage Msg
      LOOP WHILE wMsg&
      Function = Msg.wParam
      The app should use PostQuitMessage() in one of the dialog or window callback functions - this API places a %WM_QUIT message to the message queue, where upon it is picked up by the GetMessage() loop, and because %WM_QUIT = 0, wMsg& = 0 and the loop terminates cleanly.

      There is not enough of your code to be 100% of the exact cause of your problem, but it situation will occur if some particular part of the code (ie, a sub or function) is not exiting when it should.

      One problem with your code snippet is that after you receive a %WM_QUIT message and terminate your message loop, you try to post a quit message... this is a waste of time (and possible cause of your problem) as there is no message loop running to process the quit message! It's a bit like the horse coming back and locking the stall door from the outside

      However, as you wish to quit one of your dialogs, ending the message loop is no the right way to handle things - you should be using EndDialog() to kill the target dialog, and only use PostQuitMessage() when the whole app should terminate. Note that killing a window will also kill controls and dialogs that are children of that dialog. If your modeless dialog is a child of your modal dialog, then the modeless dialog will be destroyed when the modal dialog is destroyed.

      Dieny, have you got yourself a Windows programming book? These things are well documented in Petzold and the Rector/Newcomer books.

      PowerBASIC Support
      mailto:[email protected][email protected]</A>
      mailto:[email protected]


      • #4
        Thank you, Hutch and Lance.

        I have copied the loop as per your response, Lance, straight in at the end of WiNmain exactly as is, and removed other "message loops" from the callbacks of the MODELESS dialogs, so now there is only the one.
        I had the impression that EACH modeless dialog HAD to have its own message loop in its callback function or directly after the Show Modeless line. My hDlg& is created for each screen needed, then destroyed and recreated for the next.

        After putting in your message loop, I have been into the thing about six times to test, and so far it terminates every time without further ado. My problem is/was that I don't know WHERE the thing had to go. PostQuitMessage is mentioned in the Petzold examples which I have downloaded, but not actually used. So now I don't, either.

        I ordered the Petzold book in late March, and was given a three month delivery period, so in another month I MAY have it. Such is life in the hinterland. But, without a standard for comparison, I'd say one learns an awful lot whilst waiting for it! -- always given the indispensable Peer Forums and an ever-growing reference library of downloads from there. For example, at the outset (in WinMain) I create a set of fonts and brushes (globals) which are deleted (deleteObject) during %WM_DESTROY when closing the whole app. These are therefore ready for use whenever needed. Unless this attracts heavy resource overheads, it seems the simplest way to go.

        Thank you very much.



        • #5

          I have made a quick bare template using the operating system
          defined requirements and places message boxes at different places
          so you can see what order things occur in when a program loads
          and exits.

          I dont want to dump a piece of code this size in the peer forum
          so if you email me at [email protected], I will send it directly
          to you.

          [email protected]

          hutch at movsd dot com
          The MASM Forum - SLL Modules and PB Libraries


          • #6

            Quick example of where PostQuitMessage function goes in
            your main window procedure:

            CASE %WM_DESTROY
                  IF ISTRUE ghRichEd THEN FreeLibrary ghRichEd  'Free up richedit library?
                  IF ISTRUE ghFont THEN doFontDeinitialize      'Delete font object?
                  'DestroyMenu ghPopupMenu                      'Delete editor popup menu
                  PostQuitMessage 0                             'Exit main message loop
                  EXIT FUNCTION
            Hope this gives you some idea.