Announcement

Collapse
No announcement yet.

Using EXIT Command

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

  • Using EXIT Command

    Is it possible to use the exit command to sense a DDT button
    press or Escape key press? I'd like to exit a block structure
    such as FOR/NEXT or DO/LOOP if one of these events occurs but I'm
    not sure how to do it. Are there any other simple ways to interrupt
    a block structure if one has an impatient user?

    Thanks

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

  • #2
    Youy can run your Loop in a THREAD and Terminate / Stop the THREAD
    if the User wants to interrupt it.

    ------------------
    E-Mail (home): mailto:[email protected][email protected]</A>
    E-Mail (work): mailto:[email protected][email protected]</A>

    Comment


    • #3
      Originally posted by Sven Blumenstein:
      Youy can run your Loop in a THREAD and Terminate / Stop the THREAD
      if the User wants to interrupt it.

      Ok, I've looked at the thread command and it looks rather straight
      forward to run my loop in a thread. THREAD CLOSE seems to be the
      closest thing to terminating or stopping a thread as you noted above,
      but the command description says it won't stop a thread if it is still
      running - it simply releases its handle. Thus, I'm still confused
      as to how you kill a loop for impatient users - could you provide
      a snippet of code?

      Thanks

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

      Comment


      • #4
        The easiest way is to use a GLOBAL LONG and periodically test it's value from within the thread.


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

        Comment


        • #5
          I do something like this
          Code:
             #Compile Exe
             #Dim All
             #Register None
             #Include "Win32Api.INC"
          
             Sub DOGUIMessage(hDlg As Long)
                Dim Msg As tagMsg
                While PeekMessage(Msg, %NULL, %NULL, %NULL, %PM_REMOVE)
                   If IsFalse(IsDialogMessage(hDlg, Msg)) Then
                      TranslateMessage Msg
                      DispatchMessage Msg
                   End If
                Wend
             End Sub
          
             CallBack Function DlgProc
                Static Terminate As Long
                Local i As Long, j As Long
                Select Case CbMsg
                   Case %WM_INITDIALOG
                      Control Add Label,  CbHndl, 101, "",      10, 10, 50, 15
                      Control Add Button, CbHndl, 102, "Start", 10, 30, 50, 15
                      Control Add Button, CbHndl, 103, "Stop",  10, 50, 50, 15
                   Case %WM_COMMAND
                      If CbCtl = 102 Then
                         Terminate = 0
                         Do
                            If Terminate Then MsgBox "Terminated": Exit Do
                            For i = 1 To 1000000: Next: Incr j
                            Control Set Text CbHndl, 101, Format$(j)
                            DoGUIMessage CbHndl
                         Loop
                     ElseIf CbCtl = 103 Then
                        Terminate = 1
                     End If
          
                End Select
             End Function
          
             Function PbMain
                Dim hDlg As Long
                Dialog New 0, "Test", ,, 100, 100, %WS_CAPTION Or %WS_SYSMENU Or %WS_MINIMIZEBOX To hDlg
                Dialog Show Modal hDlg Call DlgProc
             End Function



          ------------------
          E-MAIL: [email protected]

          Comment


          • #6
            Originally posted by Semen Matusovski:
            I do something like this
            Code:
               Sub DOGUIMessage(hDlg As Long)
                  Dim Msg As tagMsg
                  While PeekMessage(Msg, %NULL, %NULL, %NULL, %PM_REMOVE)
                     If IsFalse(IsDialogMessage(hDlg, Msg)) Then
                        TranslateMessage Msg
                        DispatchMessage Msg
                     End If
                  Wend
               End Sub
            Thanks Semen. I used a combination of your code above and Lance's
            suggestion about going global to do what I wanted to do without using
            threads. My success seems to be a result of your code snippet above -
            what does the sub do? Is it some sort of message eater?

            Just curious


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

            Comment


            • #7
              > Is it some sort of message eater?

              Correctly to say - a processor, because this block does exactly the same work as DDT message pump and equal Dialog Doevents upto the "end of query".
              Forgot to mention. In sample above it's necessary to prevent double enterance for WM_COMMAND, CbCtl = 102.
              (special static variable, which indicates that process already running).

              [This message has been edited by Semen Matusovski (edited July 27, 2001).]

              Comment


              • #8
                Semen,

                The following code is based on your example and the idea of a message
                processor to free up time slices. I tried DIALOG DOEVENTS instead
                of your sub program and everything seems to work fine - the user is
                able to start and interrupt the process at will. I was wondering,
                however, if I'm overlooking something or have I found another way
                to do what I originally wanted to do.

                -Just curious
                Code:
                #COMPILE EXE
                #REGISTER NONE
                #INCLUDE "Win32Api.INC"
                 
                GLOBAL terminate_flag AS INTEGER
                 
                CALLBACK FUNCTION do_something()
                    'set the terminate flag to zero
                    terminate_flag=0
                    'run some process
                    DO
                    IF terminate_flag THEN EXIT DO
                    '
                    'code to do something in the loop
                    '
                    'make sure this process doesn't hog the cpu
                    DIALOG DOEVENTS
                    LOOP
                END FUNCTION
                 
                CALLBACK FUNCTION terminate_process()
                    IF MSGBOX ("Are you sure you want to terminate the count?", %MB_YESNO, "Title Bar") = 7 THEN EXIT FUNCTION
                    'set the terminate flag if user chooses yes
                    terminate_flag=1
                END FUNCTION
                 
                CALLBACK FUNCTION exit_dialog()
                    IF MSGBOX ("Are you sure you want to exit?", %MB_YESNO, "Title Bar") = 7 THEN EXIT FUNCTION
                    terminate_flag=1
                    DIALOG END CBHNDL
                END FUNCTION
                 
                ' the main program
                FUNCTION PBMAIN
                    DIM hDlg AS LONG
                    'create a dialog
                    DIALOG NEW 0, "Title",,, 100, 100, %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX TO hDlg
                    'add a dynamic label
                    CONTROL ADD LABEL,  hDlg, 101, "", 10, 10, 50, 15, %SS_SUNKEN
                    'and some buttons
                    CONTROL ADD BUTTON, hDlg, 102, "Start", 10, 30, 50, 15, CALL do_something
                    CONTROL ADD BUTTON, hDlg, 103, "Stop", 10, 50, 50, 15, CALL terminate_process
                    CONTROL ADD BUTTON, hDlg, 104, "Exit", 10, 70, 50, 15, CALL exit_dialog
                    'now show it
                    DIALOG SHOW MODAL hDlg
                END FUNCTION
                ------------------

                Comment


                • #9
                  In this case, DIALOG DOEVENTS is not "freeing timeslices" as such, but is giving a helping hand to the message pump so UI interactions are handled smoothly while the time-consuming processing code is executing.

                  This is a common strategy, easy to implement, and works well.

                  If you actually want to release the current timeslice (say, to reduce the CPU loading), use SLEEP %NULL (or SLEEP 0).

                  Note that your INTEGER (GLOBAL var) should be a LONG rather than an INTEGER (LONG is more efficient then INTEGER in Win32, and it works best for inter-Thread signalling without the need to use Synchronization Objects).

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

                  Comment


                  • #10
                    So would I replace DIALOG DOEVENTS with SLEEP 0 or would I simply
                    add SLEEP 0 to my code after DIALOG DOEVENTS?

                    Thanks for the advice on LONG vs INTEGER - I'll make the switch.


                    Originally posted by Lance Edmonds:
                    In this case, DIALOG DOEVENTS is not "freeing timeslices" as such, but is giving a helping hand to the message pump so UI interactions are handled smoothly while the time-consuming processing code is executing.

                    This is a common strategy, easy to implement, and works well.

                    If you actually want to release the current timeslice (say, to reduce the CPU loading), use SLEEP %NULL (or SLEEP 0).

                    Note that your INTEGER (GLOBAL var) should be a LONG rather than an INTEGER (LONG is more efficient then INTEGER in Win32, and it works best for inter-Thread signalling without the need to use Synchronization Objects).



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

                    Comment


                    • #11
                      > if I'm overlooking something or have I found another way

                      I think, first.
                      Dialog Doevents processes one message only and it's not clear how often you should execute it.
                      From one side, if to do Dialog DoEvebts too often, you will lose a lot of time, because Dialog Doevents (GetMessage ?) doesn't return control immediatelly, if there are no messages in query.
                      From another side, if to do Dialog DoEvents not very often, remains messages in query and will begin repaint and other problems. OS posts a waste of messages.

                      My sub (actually nothing new for patent ) allows periodically to process ALL events, which are currently in query.

                      About Sleep ...
                      I cut a fragment from real app not successful (here Sleep is present, but outside this sub - one Sleep per some DoGUIMessage - I have reasons).
                      In geberal case it's possible to add Sleep 0 after Wend.

                      [This message has been edited by Semen Matusovski (edited July 30, 2001).]

                      Comment

                      Working...
                      X