Announcement

Collapse
No announcement yet.

DIALOG DOEVENTS..

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • DIALOG DOEVENTS..

    Shouldn't DIALOG DOEVENTS make sure all pending messages are processed?
    Seems it only clears one message.

    Have to use 4-5 DIALOG DOEVENTS in a row to make sure controls are properly
    updated between for example OpenFile dialog close and extensive file read.
    Is most noticeable in slow machines, which average user has, so must do this.

    Tested API routines to confirm:
    Code:
      'this gives me EXACT same behaviour as one DIALOG DOEVENTS
      LOCAL Msg AS tagMsg
      IF PeekMessage(Msg, 0, 0, 0, %PM_REMOVE) THEN
        TranslateMessage Msg
        DispatchMessage Msg
      END IF
     
      'this makes sure all pending messages are processed, and gives
      'me same behaviour as 4-5 DIALOG DOEVENTS in a row.
      LOCAL Msg AS TAGMSG
      WHILE PeekMessage(Msg, 0, 0, 0, %PM_REMOVE)
         TranslateMessage Msg
         DispatchMessage Msg
      WEND
    Is not a problem - I know fix, but maybe someone at PB can confirm?


    ------------------

  • #2
    Borje,

    I'm confused, as you're a highly competent programmer, so I'll ask
    anyway. Is there a particular reason why your code cannot do the
    conventional loop, i.e.:

    Code:
    DO
        DIALOG DOEVENTS TO Count&
    LOOP WHILE Count&
    ?


    ------------------

    Comment


    • #3
      While not very experienced I have found loop mentioned by Clay
      to be very effective at allowing multipe processes to run
      smoothly.

      Michael Vickery

      ------------------
      mailto:[email protected][email protected]</A>

      Comment


      • #4
        Ah, guys, you didn't understand.
        When a modal dialog begins to execute long calculations, it should periodically clean message query.
        To use Dialog Doevents in current form is impossible.
        Meanwhile While PeekMessage ... should include IsDialogMessage / TranslateAccelerator.

        Because DDT is somewhere black box, much easy to use own wrappers. But in this case advantages of DDT will be lost.

        So, I agree that should be Dialog DoEvents UptoTheEndOfQuery


        ------------------

        Comment


        • #5
          Yes, correct Semen. Also important to take a deep breath before an action starts.

          Good example is between OpenFile dialog os closed and file read starts. If OpenFile
          dialog was over another control, this one can end up not being redrawn properly for
          a couple of seconds while huge file is read or contents is sent to RichEdit, whatever.

          And yes, IsDialogMessage / TranslateAccelerator is a must. Above was test only.


          ------------------

          Comment


          • #6
            Maybe I'm a little confused...but in this case isn't this faster:

            Code:
              WHILE GetMessage(Msg,%NULL,0,0)
                TranslateMessage Msg
                DispatchMessage Msg
              WEND
            so all the messages are processed immediately...isn't PeekMessage used
            only for interrupting normal process?

            Brad

            ------------------
            Wash DC Area
            mailto:[email protected][email protected]</A>

            Comment


            • #7
              Brad --

              Ok. simple sample.

              When you will click a button and move another window over the dialog, last will not be repainted.
              Now show, where do you want to add GetMessage and what happends

              Code:
              #Compile Exe
              #Dim All
              #Include "WIN32API.INC"
              
              %IDD_DIALOG1    = 101
              %IDC_BUTTON1    = 1001
              %IDC_TEXTBOX1   = 1002
              
              CallBack Function DlgProc
              
                  Select Case CbMsg
                      Case %WM_COMMAND
                          Select Case CbCtl
                              Case %IDC_BUTTON1
                                  Dim i As Local Dword
                                  Dim j As Local Dword
                                  If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then
                                      For i = 1 To 1000000 ' Long Process
                                         For j = 1 To 1000000
                                         Next
                                         SetWindowText CbHndl, Str$(i)
                                      Next
                                  End If
                          End Select
                  End Select
              
              End Function
              
              Function PbMain
                  Local hDlg As Dword
                  Dialog New 0, "Dialog1", 317, 243, 195, 106, %WS_POPUP Or %WS_BORDER _
                      Or %WS_DLGFRAME Or %WS_CAPTION Or %WS_SYSMENU Or %WS_CLIPSIBLINGS Or _
                      %WS_VISIBLE Or %DS_MODALFRAME Or %DS_3DLOOK Or %DS_NOFAILCREATE Or _
                      %DS_SETFONT, %WS_EX_WINDOWEDGE Or %WS_EX_CONTROLPARENT Or %WS_EX_LEFT _
                      Or %WS_EX_LTRREADING Or %WS_EX_RIGHTSCROLLBAR, To hDlg
                  Control Add Button, hDlg, %IDC_BUTTON1, "Click me and move another window over the dialog", 5, 65, 185, 15
                  Control Add TextBox, hDlg, %IDC_TEXTBOX1, "TextBox1", 45, 15, 110, 25
                  Dialog Show Modal hDlg, Call DlgProc
              End Function
              ------------------


              [This message has been edited by Semen Matusovski (edited November 17, 2002).]

              Comment


              • #8
                looks like ms wrote that..

                brad, i'm not talking dialog message loop here, i only need to process
                all pending messages before an action starts, or inside tight loops like
                the one semen shows. so processor can do other things too during loop.

                good example of what i'm talking about is code viewer i just posted
                to source code forum: http://www.powerbasic.com/support/pb...ad.php?t=23591

                try it, and remove the multiple dialog doevents right after openfile
                dialog is closed. in my slow system, a shadow of the dialog is left
                on screen while richedit (ms code - no "doevents" there..) works
                with inserted text and button under dialog sort of disappears for a while.

                try one dialog doevents. same thing happens. try 6-8 or more, and screen
                is properly updated before action starts.


                ------------------
                so maybe should be named dialog doevent instead, without the s..


                [this message has been edited by borje hagsten (edited november 17, 2002).]

                Comment


                • #9
                  Borje --

                  > Try one DIALOG DOEVENTS. Same thing happens.
                  > Try 6-8 or more, and screen is properly updated
                  > before action starts.

                  What is wrong with Clay's suggestion?

                  Code:
                  DO
                     DIALOG DOEVENTS TO Count&
                  LOOP WHILE Count& <> 0
                  DIALOG DOEVENTS will return 0 when there are no more events to process, so that
                  code will do exactly what you are describing: it will process window messages
                  until the queue is empty, then exit.

                  If you want to reduce the amount of typing you do, create SUB MyDoEvents that
                  contains that code. "MyDoEvents" is fewer keystrokes than DIALOG DOEVENTS.

                  I guess agree that it might be more convenient if DIALOG DOEVENTS worked the
                  way you are describing, but I don't see any pressing functionality reason that
                  it should be changed. The way it is, it is possible to process events one at a time
                  (if your program needs to do that) or to handle "all pending events" with a loop. If
                  DIALOG DOEVENTS was changed you would not have any choice.

                  -- Eric

                  P.S. Generally speaking, I am opposed to changing the way existing PowerBASIC
                  functions work because it might break existing code. But perhaps a new option
                  would make everybody happy...

                  Code:
                  DIALOG DOEVENTS ALL
                  ------------------
                  Perfect Sync Development Tools
                  Perfect Sync Web Site
                  Contact Us: mailto:[email protected][email protected]</A>




                  [This message has been edited by Eric Pearson (edited November 17, 2002).]
                  "Not my circus, not my monkeys."

                  Comment


                  • #10
                    Eric --
                    DIALOG DOEVENTS will return 0 when there are no more events to process, so that
                    code will do exactly what you are describing: it will process window messages
                    until the queue is empty, then exit.
                    PB documentation talks:
                    Code:
                    DIALOG DOEVENTS is usually used to create a "message pump" for modeless dialog boxes.  If the optional TO clause is included, the number of active dialogs is returned in the count& variable, once all of the pending messages have been processed.
                    Unlike I have problems with English, but the number of active dialogs is not equal the number of messages
                    Test 'results' of Dialog Doevents
                    Code:
                    #Compile Exe
                    #Dim All
                    #Include "WIN32API.INC"
                    
                    %IDD_DIALOG1    = 101
                    %IDC_BUTTON1    = 1001
                    %IDC_TEXTBOX1   = 1002
                    
                    CallBack Function DlgProc
                    
                        Select Case CbMsg
                            Case %WM_COMMAND
                                Select Case CbCtl
                                    Case %IDC_BUTTON1
                                        Dim i As Local Dword
                                        Dim j As Local Dword
                                        If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then
                                            For i = 1 To 1000000 ' Long Process
                                               For j = 1 To 1000000
                                               Next
                                               SetWindowText CbHndl, Str$(i)
                                               Dim Count As Long
                                               Do
                                                   Dialog DoEvents To Count
                                               Loop While Count <> 0
                                            Next
                                            
                                        End If
                                End Select
                        End Select
                    
                    End Function
                    
                    Function PbMain
                        Local hDlg As Dword
                        Dialog New 0, "Dialog1", 317, 243, 195, 106, %WS_POPUP Or %WS_BORDER _
                            Or %WS_DLGFRAME Or %WS_CAPTION Or %WS_SYSMENU Or %WS_CLIPSIBLINGS Or _
                            %WS_VISIBLE Or %DS_MODALFRAME Or %DS_3DLOOK Or %DS_NOFAILCREATE Or _
                            %DS_SETFONT, %WS_EX_WINDOWEDGE Or %WS_EX_CONTROLPARENT Or %WS_EX_LEFT _
                            Or %WS_EX_LTRREADING Or %WS_EX_RIGHTSCROLLBAR, To hDlg
                        Control Add Button, hDlg, %IDC_BUTTON1, "Click me and move another window over the dialog", 5, 65, 185, 15
                        Control Add TextBox, hDlg, %IDC_TEXTBOX1, "TextBox1", 45, 15, 110, 25
                        Dialog Show Modal hDlg, Call DlgProc
                    End Function



                    ------------------

                    Comment


                    • #11
                      Borje --

                      You are correct, I did not correctly remember what the TO value returns, and I didn't look it up
                      before I posted my response.

                      -- Eric


                      ------------------
                      Perfect Sync Development Tools
                      Perfect Sync Web Site
                      Contact Us: mailto:[email protected][email protected]</A>

                      [This message has been edited by Eric Pearson (edited November 17, 2002).]
                      "Not my circus, not my monkeys."

                      Comment


                      • #12
                        Yes, cannot use a loop like that inside modal dialog - it will always
                        return >=1 for current dialog = hang. But suggestion gave me an idea
                        that DDT should accept 100%:
                        Code:
                        MACRO NewEvents         'in PB/DLL 6.x, change to SUB/END SUB
                          LOCAL Msg AS tagMsg
                          DO WHILE PeekMessage(Msg, 0, 0, 0, %PM_NOREMOVE) 'peek only, not remove
                             DIALOG DOEVENTS                               'let DDT handle all pending messages
                          LOOP
                        END MACRO
                        Tested and seems to work exactly like it should.


                        ------------------

                        Comment


                        • #13
                          When a modal dialog begins to execute long calculations, it should periodically clean message query.
                          I think you may have meant message "queue" rather than "query?"

                          Regardless, I just wonder why you are using a MODAL dialog with some kind of embedded message-queue processing. Seems to me the modeless dialog is the tool designed to handle messages for more than one dialog at a time.

                          That, or throw the modal dialog into its own thread with its own message loop.

                          (As acknowledged, I am not a 'DDT' guy. But this is what I'd do 'SDK-style').

                          MCM


                          Michael Mattias
                          Tal Systems (retired)
                          Port Washington WI USA
                          [email protected]
                          http://www.talsystems.com

                          Comment


                          • #14
                            Michael, see what I speak about above. DIALOG DOEVENTS seems
                            to be designed for MODELESS message pump (help file sort of confirms
                            this), but cannot be used as-is in MODAL dialogs, because it only
                            processes one message at a time. Test also confirms.

                            Like Semen says, MODAL DDT is like black box, but even the blackest
                            box can be opened with enough brutal force..

                            Just added the PeekMessage/DOEVENTS macro above to Code Viewer I
                            posted to Sorce code forum, because that macro works perfect.


                            ------------------
                            Spell like a Swede - one massage at a time..?


                            [This message has been edited by Borje Hagsten (edited November 17, 2002).]

                            Comment


                            • #15
                              Michael --
                              Of course, you are correct about queue, but for me this word is associated with young girls.
                              A thread is alternative, but not comfortable (a lot of additional code + it's necessary to transfer variables).



                              ------------------

                              Comment


                              • #16
                                Borje --

                                If I'm not mistaken your strategy will fail if your program has more than one dialog, such as a parent and child.

                                Semen --

                                > for me this word [queue] is associated with young girls.

                                ????

                                -- Eric


                                ------------------
                                Perfect Sync Development Tools
                                Perfect Sync Web Site
                                Contact Us: mailto:[email protected][email protected]</A>

                                [This message has been edited by Eric Pearson (edited November 17, 2002).]
                                "Not my circus, not my monkeys."

                                Comment


                                • #17
                                  Just tested with both modal and modeless child dialogs - no problem.
                                  But understand DIALOG DOEVENTS little better now. It seems to clear
                                  calling thread's message queue, so it may handle more than one message.

                                  But if so, what I don't understand is that repeated calling also clears
                                  other pending messages. Did following test in mentioned code viewer, right
                                  after OpenFile dialog is closed.
                                  Code:
                                                   LOCAL Msg AS tagMsg, c AS LONG
                                                   DO WHILE PeekMessage(Msg, 0, 0, 0, %PM_NOREMOVE) 'peek only, not remove
                                                      INCR c
                                                      DIALOG SET TEXT CBHNDL, STR$(c)
                                                      SLEEP 300
                                                      DIALOG DOEVENTS                               'let DDT handle all pending messages
                                                   LOOP
                                  Result varies between 4-7 iterations, depending on what happened in
                                  OpenFile dialog, like changing folder adds to following message count.
                                  IOW, not enough with one DOEVENTS, must use something like the above
                                  before continuing.


                                  ------------------




                                  [This message has been edited by Borje Hagsten (edited November 17, 2002).]

                                  Comment


                                  • #18
                                    Borje, Semen

                                    Very Interesting Thread
                                    This variation may be of interest?

                                    Code:
                                    #COMPILE EXE
                                    #DIM ALL
                                    #INCLUDE "WIN32API.INC"
                                    
                                    %IDD_DIALOG1    = 101
                                    %IDC_BUTTON1    = 1001
                                    %IDC_TEXTBOX1   = 1002
                                    
                                    CALLBACK FUNCTION DlgProc
                                    
                                        SELECT CASE CBMSG
                                            CASE %WM_COMMAND
                                                SELECT CASE CBCTL
                                                    CASE %IDC_BUTTON1
                                                        DIM i AS LOCAL DWORD
                                                        DIM j AS LOCAL DWORD
                                                        
                                                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                                                            FOR i = 1 TO 1000000 ' Long Process
                                                               FOR j = 1 TO 1000000
                                                               NEXT
                                                               SetWindowText CBHNDL, STR$(i)
                                                                  DIALOG DOEVENTS
                                                               
                                                            NEXT
                                                        END IF
                                                END SELECT
                                        END SELECT
                                    
                                    END FUNCTION
                                    
                                    FUNCTION PBMAIN
                                        LOCAL hDlg AS DWORD,Msg AS tagMsg
                                        DIALOG NEW 0, "Dialog1", 317, 243, 195, 106, %WS_POPUP OR %WS_BORDER _
                                            OR %WS_DLGFRAME OR %WS_CAPTION OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR _
                                            %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
                                            %DS_SETFONT, %WS_EX_WINDOWEDGE OR %WS_EX_CONTROLPARENT OR %WS_EX_LEFT _
                                            OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
                                        CONTROL ADD BUTTON, hDlg, %IDC_BUTTON1, "Click me and move another window over the dialog", 5, 65, 185, 15
                                        CONTROL ADD TEXTBOX, hDlg, %IDC_TEXTBOX1, "TextBox1", 45, 15, 110, 25
                                        DIALOG SHOW MODAL hDlg, CALL DlgProc
                                    
                                      WHILE GetMessage(Msg, %NULL, 0, 0)
                                        TranslateMessage Msg
                                        DispatchMessage Msg
                                      WEND
                                    END FUNCTION
                                    ------------------
                                    Wash DC Area
                                    mailto:[email protected][email protected]</A>

                                    Comment


                                    • #19
                                      Eric --
                                      Our dictionaries give some meanings of the word "queue".
                                      One of it is equal 'tress' (hair).
                                      Note, our dictionaries are British English orientied.
                                      Probably, our dictionares are living in 15-16 century.
                                      But let's ask British residents


                                      ------------------

                                      Comment


                                      • #20
                                        During a GETMESSAGE() your app REMAINS *in* Windows kernel/user until a message happens.
                                        This message will let your app do another cycle in the local do/loop.
                                        A dialog doevents loop seems incorrect if it is just polling for messages.
                                        Maybe i'm incorrect about the DDT variant.


                                        ------------------
                                        http://www.hellobasic.com
                                        hellobasic

                                        Comment

                                        Working...
                                        X