i like to stop a loop by pressing the "s" key

Just starting out? Need help? Post your questions and find answers here.
wimapon
Enthusiast
Enthusiast
Posts: 290
Joined: Thu Dec 16, 2010 2:05 pm
Location: Delfzijl ( The Netherlands )
Contact:

Re: i like to stop a loop by pressing the "s" key

Post by wimapon »

Hi bernd,

does the program, you gave me here, use Windows API stuff?
a stupid question..but i realy don't know...
I do all the time, use your fantastic examples,, and change them a bit, so that
my programming goals are reached... without thinking about ... etc.
So, how can i recognize a API call?


Wim
infratec
Always Here
Always Here
Posts: 7591
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: i like to stop a loop by pressing the "s" key

Post by infratec »

Hi Wim,

all my examples contains no API calls.
An API procedure ends always with an underscore like

Code: Select all

GetAsyncKeyState_(#VK_S)
You also get no help for them if you place the cursor on them and you press F1.

But on the top of the 'Coding Questions' is a topic which gives you more informations.
But only for Windows API calls.
In Linux you can also use API calls.

But I prefere to avoid them in both worlds.

Bernd
infratec
Always Here
Always Here
Posts: 7591
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: i like to stop a loop by pressing the "s" key

Post by infratec »

But back to the topic:

An other solution (but I prefer the tray version when a program is always running)

Code: Select all

#WaitSeconds = 2

OpenWindow(0, 0, 0, 300, 200, "Press 'S' to stop", #PB_Window_SystemMenu)

AddKeyboardShortcut(0, #PB_Shortcut_S, 1)

Exit = #False
Starttime = Date() - #WaitSeconds
Repeat
  Event = WindowEvent()
  
  If Event = #PB_Event_Menu
    If EventMenu() = 1 : Exit = #True : EndIf
  Else : Delay(10) : EndIf

  If Date() - Starttime >= #WaitSeconds
    Starttime = Date()
    Debug "loop"
  EndIf
  
Until Exit
It is also less accurate.

The main point is WindowEvent() instead of WaitWindowEvent().

Bernd
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: i like to stop a loop by pressing the "s" key

Post by blueznl »

Wim, je wordt in de watten gelegd door de crowd hier :-)

Re. your question: if you're calling an EXTERNAL program, there's nothing you can do to abort that program, except by killing it.

If it's your own code you'll have to process any incoming events. For example you could sprinkle a bunch of 'if action = #continue' everywhere as part of any time consuming loops, and check for events within those loops. Something like this (this is pseudocode, not a running program :-)):

Code: Select all

procedure abort()
  if event <> 0
    procedurereturn = #true
  else
    procedurereturn #false
  endif
endprocedure
;
procedure main()
  action = #continue
  n = 0
  while n < 100000000000 and abort() = #false
    .. do time consuming stuff ..
  wend
endprocedure
;
main()
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
charvista
Addict
Addict
Posts: 949
Joined: Tue Sep 23, 2008 11:38 pm
Location: Belgium

Re: i like to stop a loop by pressing the "s" key

Post by charvista »

I have also been thinking about how to stop a loop or a calculation or whatever by pressing a key (here the S key).
Bernd, you are using it in the main loop, which is perfect, but I think it would be fantastic to have a function that simply checks the S-key.
The idea is to add an easy to use IF Halt() then cancel everything, and this anywhere. But only internal, no external programs
Here is my solution (no API calls :wink: ):

Code: Select all

Enumeration
    #Win
EndEnumeration

Procedure zHalt()
    AddKeyboardShortcut(#Win,#PB_Shortcut_S,777)
    Event=WaitWindowEvent()
    Select Event
        Case #PB_Event_Menu
            VK=EventMenu(); get Virtual Key
            If VK=777
                ProcedureReturn 1
            EndIf
    EndSelect
    ProcedureReturn 0
EndProcedure

Procedure DoSomeCalc()
    Repeat
        i+i
        If zHalt() : ProcedureReturn -1 : EndIf
    Until i=-4; which will never occur!!!
EndProcedure

Procedure Main()
    OpenWindow(#Win,100,100,1024,600,"Press 'S' to stop - Demo",#PB_Window_SystemMenu)
    
    Result=DoSomeCalc()
    
    If Result=-1
        MessageRequester("Result","Calculation aborted")
        ProcedureReturn
    Else
        MessageRequester("Result","Calculation normally finished")
    EndIf
EndProcedure

Main()
I just completed my example that blueznl comes with the same solution with abort()
Blueznl, you are faster than me :o
- Windows 11 Home 64-bit
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
wimapon
Enthusiast
Enthusiast
Posts: 290
Joined: Thu Dec 16, 2010 2:05 pm
Location: Delfzijl ( The Netherlands )
Contact:

Re: i like to stop a loop by pressing the "s" key

Post by wimapon »

Okay folks,
Still going strong here.

but i still have one tiny problem with my measuring program.
I am looking for a screen in which i can print which file is measured at this moment.

Console disapears..
debug does not work compiled. ( this would be a good one...)
messagerequester show one window for every measurement...

the screen must be always there when and every minute the file name of the
measured data, must be printed in sequence..
like:

17381000
17381001
17381002
17381003
17381004


So when i come in the measuring caravan, i can direct see that the program is
working nice...

Wim
infratec
Always Here
Always Here
Posts: 7591
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: i like to stop a loop by pressing the "s" key

Post by infratec »

Hi Wim,

more informations are needed:
Does your program print the filename?
Or should a directory scanned for the files?

In general if you want an additional window, simply open one :mrgreen:
You can use an EditorGadget or a ListViewGadget to add new lines.

Bernd
infratec
Always Here
Always Here
Posts: 7591
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: i like to stop a loop by pressing the "s" key

Post by infratec »

@Charvista

Hi,
I think your solution has some disadvantages.

1. It blocks (WaitWindowEvent())
2. If you need additional WindowEvents in your main code, you may loose some of them.

If you really want to do it 'async', than you have to create an own thread
which checks a global variable. This variable can be changed in the main
event loop.

But I thought that threads are to 'complicated' for someone who just discovered
windows programming.

Bernd
wimapon
Enthusiast
Enthusiast
Posts: 290
Joined: Thu Dec 16, 2010 2:05 pm
Location: Delfzijl ( The Netherlands )
Contact:

Re: i like to stop a loop by pressing the "s" key

Post by wimapon »

Hi infratec,
I use now 2 programs
One is the never ending loop which calls every second the second program.
This second program calculates the filename, makes eventualy a new directory ( new day) , does one measurement from the soundcard (1 second data), write this data
to the file, closes the file and stops.

So where can i , and how can i, continuously see which was the last measured file...?
(So i can see that the program is running and is okee)

some sort of directory search would bee okee... just the last file is perfect.
this directory search could be in the first program... and holds his window open
until the measuring program starts...

( you have to do very much... to look at the stars at an unusual way...)



Wim
infratec
Always Here
Always Here
Posts: 7591
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: i like to stop a loop by pressing the "s" key

Post by infratec »

Hi Wim,

the following code gives you an idea,
since it does not makes sense to scan always a complete directory with subdirectories.
Your program should 'print' the filename. Than you can catch this.

Code: Select all

Procedure.s StrSec(Seconds.i)
  
  Result$ = ""
  
  Help = Seconds / (60 * 60 * 24)
  Result$ = Str(Help) + "d"
  Seconds - (Help * 60 * 60 * 24)
  
  Help = Seconds / (60 * 60)
  Result$ + " " + Str(Help) + "h"
  Seconds - (Help * 60 * 60)
  
  Help = Seconds / 60
  Result$ + " " + Str(Help) + "m"
  Seconds - (Help * 60)
  
  Result$ + " " + Str(Seconds) + "s"
  
  ProcedureReturn Result$
  
EndProcedure

OpenWindow(0, 0, 0, 1, 1, "", #PB_Window_Invisible)

OpenWindow(1, 0, 0, 300, 200, "Info", #PB_Window_SystemMenu)
HideWindow(1, #True)

OldGadgetList = UseGadgetList(WindowID(1))
ListViewGadget(1, 10, 10, 280, 180)
;UseGadgetList(OldGadgetList)

CreatePopupMenu(0)
MenuItem(1, "Info")
MenuItem(2, "Quit")

LoadImage(0, #PB_Compiler_Home + "Examples\Sources - Advanced\MoviePlayer\Icons\Pause.ico")
LoadImage(1, #PB_Compiler_Home + "Examples\Sources - Advanced\MoviePlayer\Icons\Play.ico")
 
AddSysTrayIcon(0, WindowID(0), ImageID(0))
SysTrayIconToolTip(0, "I'm Wims meassure program")
 
AddWindowTimer(0, 0, 10*1000)    ; a 60 sec timer (for the Sampler())

Starttime = ElapsedMilliseconds()

Counter = 0
Exit = #False
Repeat
  
  Event = WaitWindowEvent()
  
  If EventWindow() = 0
    
    Select Event
      Case #PB_Event_Timer
        If EventTimer() = 0
          ChangeSysTrayIcon(0, ImageID(1))
          ;RunProgram("C:\WINDOWS\system32\ping.exe", "127.0.0.1", GetPathPart(ProgramFilename()), #PB_Program_Wait)
          Prog = RunProgram("ping.exe", "127.0.0.1", GetPathPart(ProgramFilename()), #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)
          If Prog
            While ProgramRunning(Prog)
              If AvailableProgramOutput(Prog)
                Line$ = ReadProgramString(Prog)
                If FindString(Line$, "TTL", 1)
                  AddGadgetItem(1, -1, Line$)
                EndIf
              EndIf
            Wend
            CloseProgram(Prog)
            Counter + 1
          EndIf
          ChangeSysTrayIcon(0, ImageID(0))
          
          SetWindowTitle(1, "Info: " + StrSec((ElapsedMilliseconds() - Starttime) / 1000))
          
        EndIf
         
      Case #PB_Event_SysTray
        If EventType() = #PB_EventType_RightClick
          DisplayPopupMenu(0, WindowID(0))
        EndIf
              
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            If GetMenuItemState(0, 1)
              SetMenuItemState(0, 1, #False)
              HideWindow(1, #True)
            Else
              SetMenuItemState(0, 1, #True)
              HideWindow(1, #False)
            EndIf
          Case 2
            Exit = #True
        EndSelect
    EndSelect
    
  Else
    
    If Event = #PB_Event_CloseWindow
      HideWindow(1, #True)
      SetMenuItemState(0, 1, #False)
    EndIf
    
  EndIf
    
Until Exit
Bernd
User avatar
charvista
Addict
Addict
Posts: 949
Joined: Tue Sep 23, 2008 11:38 pm
Location: Belgium

Re: i like to stop a loop by pressing the "s" key

Post by charvista »

@infratec
You are right infratec, when two WaitWindowEvent() were occurring at the same time, it would be conflicting and I could lose some keyboard or mouse events.....
But while calculating something, I think that the main loop's event is not reached until the calculation is finished.
During the calculation's procedure, only the possible events are checked within zHalt()...
So you can press the S key or click the Stop button that I added, and then only the event in the main procedure will be checked again... (there are none in my demo, anyway).
Edit: In other words, if you want to close the window, you should first Stop the calculations! :wink:

Code: Select all

    Enumeration
        #Win
        #BtnStop
        #TGad
    EndEnumeration

    Procedure zHalt()
        AddKeyboardShortcut(#Win,#PB_Shortcut_S,777)
        Event=WaitWindowEvent()
        Select Event
            Case #PB_Event_Menu
                VK=EventMenu(); get Virtual Key
                If VK=777
                    ProcedureReturn 1
                EndIf
            Case #PB_Event_Gadget
                Select EventGadget()
                    Case #BtnStop
                        ProcedureReturn 1
                EndSelect
        EndSelect
        ProcedureReturn 0
    EndProcedure

    Procedure DoSomeCalc()
        TextGadget(#TGad,100,50,200,20,"Calculation in progress........")
        Repeat
            i+i
            If zHalt() : FreeGadget(#TGad) : ProcedureReturn -1 : EndIf
        Until i=-4; which will never occur!!!
        FreeGadget(#TGad)
    EndProcedure

    Procedure Main()
        OpenWindow(#Win,100,100,1024,600,"Press 'S' to stop - Demo",#PB_Window_SystemMenu)
        ButtonGadget(#BtnStop,100,100,100,30,"Stop")
        Result=DoSomeCalc()
       
        If Result=-1
            FreeGadget(#BtnStop)
            MessageRequester("Result","Calculation aborted")
            ProcedureReturn
        Else
            MessageRequester("Result","Calculation normally finished")
        EndIf
    EndProcedure

    Main()
- Windows 11 Home 64-bit
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
wimapon
Enthusiast
Enthusiast
Posts: 290
Joined: Thu Dec 16, 2010 2:05 pm
Location: Delfzijl ( The Netherlands )
Contact:

Re: i like to stop a loop by pressing the "s" key

Post by wimapon »

Ohhhhh where is the time saying: print filenaam...... hi hi hi

but i will try it...
( no choice.....)

Wim
wimapon
Enthusiast
Enthusiast
Posts: 290
Joined: Thu Dec 16, 2010 2:05 pm
Location: Delfzijl ( The Netherlands )
Contact:

Re: i like to stop a loop by pressing the "s" key

Post by wimapon »

Okee folks,
I can live with this program now.....
It is not exact what i like to have, but for the time beeing it is very good usable.

Later, when i do know more of pb i will come back to this...

Now i must go on with my telescope in general.
Doing a lot of measuring and calibrating the soundcard, setting up a test-computer
in the caravan in the field, making some sort of climate control around this computer...
calibrating the (PB) FFT program and comparing the results with the setup from
last days...

your help was realy fantastic, and i am very greatfull.
I hope i may ask other questions.. ( which will come very soon, i think)


Wim
Post Reply