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

Just starting out? Need help? Post your questions and find answers here.
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,

please provide us with more informations.

Is it a 'windows' program, or is it a 'console' program?
Because else half of the tips are wasted time.

If it is a windows program, use a global variable for Exit and put your messure loop
in an own thread. Than use the addKeyboardshortcut in the main program.
When you exit the main program, the thread is also closed.
If you have to close something inside the thread, than test this variable inside the
thread, and when everything is finished, than set a global Quit variable to true.
So the main program can now also terminate.

If you want that the loop acts direct, without delay, you should not use one long delay for the
next meassure event, you should build a loop which counts 100ms delays if the counter is 600,
than start your meassurement. So the maximum delay to react on the key is 100ms.

But the best way is to use a window timer. It is more exact.

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 »

Here's a complete and documented example, hope it is usefull:

(I've also added this example to the Survival Guide, it may help other people.)

Code: Select all

EnableExplicit
;
Enumeration
  ;
  ; actions
  ;
  #continue
  #exit
  ;
  ; menu entries
  ;
  #f_stop
  ;
  ; gui elements
  ;
  #w_main
  #g_counter_all
  #g_counter_null
  #g_counter_timer
  ;
  ; timers
  ;
  #t_timer
  ;
EndEnumeration
;
OpenWindow(#w_main,0,0,240,140,"ShortcutGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TextGadget(#g_counter_all,10,10,200,20,"all events 0")
TextGadget(#g_counter_null,10,30,200,20,"null events 0")
TextGadget(#g_counter_timer,10,50,200,20,"timer events 0")
AddKeyboardShortcut(#w_main, #PB_Shortcut_S, #f_stop)
AddWindowTimer(#w_main,#t_timer,2*1000)
;
Global counter_all = 0
Global counter_null = 0
Global counter_timer = 0
;
Global action, event, eventmenu, eventtimer
;
Repeat
  ;
  ; grab events, wait maximal 250 msec for an event
  ;
  event = WaitWindowEvent(250)
  eventmenu = EventMenu()
  eventtimer = EventTimer()
  ;
  ; we'll keep looping until action has been set to #exit
  ;
  action = #continue
  ;
  Select event
  Case #PB_Event_CloseWindow
    ;
    ; close window button
    ;
    action = #exit
    ;
  Case #PB_Event_Menu
    ;
    ; menu, toolbar button or keyboard shortcut
    ;
    Select eventmenu
    Case #f_stop
      action = #exit
    EndSelect
    ;
  Case #PB_Event_Timer
    ;
    ; timer events
    ;
    Select eventtimer
    Case #t_timer
      counter_timer = counter_timer+1
      SetGadgetText(#g_counter_timer,"timer events "+Str(counter_timer))
    EndSelect
    ;
  Case 0
    ;
    ; called every time waitwindowevent() timed out
    ;
    counter_null = counter_null+1
    SetGadgetText(#g_counter_null,"null events "+Str(counter_null))
    ;
  Default
    ;
    ; called every time anything else caused the loop to run
    ;
  EndSelect
  ;
  ; called on every event loop (on each windows message, waitwindowevent() timeout, timer message etc.)
  ;
  counter_all = counter_all+1
  SetGadgetText(#g_counter_all,"all events "+Str(counter_all))
  ;
Until action = #exit
Last edited by blueznl on Sat Jan 08, 2011 12:43 pm, edited 1 time in total.
( 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... )
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,

also from me a short and easy example (the way I would do it)

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)
 
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
    
  Select WaitWindowEvent()
    Case #PB_Event_Timer
      If EventTimer() = 0
        ChangeSysTrayIcon(0, ImageID(1))
        RunProgram("ping.exe", "127.0.0.1", GetPathPart(ProgramFilename()), #PB_Program_Wait)
        Counter + 1
        ChangeSysTrayIcon(0, ImageID(0))
      EndIf
       
    Case #PB_Event_SysTray
      If EventType() = #PB_EventType_RightClick
        DisplayPopupMenu(0, WindowID(0))
      EndIf
            
    Case #PB_Event_Menu
      Select EventMenu()
        Case 1
          Text$ = "I'm Wims meassure program." + #CR$
          Text$ + "Running since " + StrSec((ElapsedMilliseconds() - Starttime) / 1000) + #CR$
          Text$ + "Meassured " + Str(Counter) + " times"
          MessageRequester("Hi!", Text$)
        Case 2
          Exit = #True
      EndSelect
  EndSelect
    
Until Exit
A simplified version without thread...

I start a ping as demo.
If the program is not in the search path, you need the full path to the program :!:

Bernd

P.S.: If you want to see the tray icon change faster, reduce the 60 seconds :mrgreen:
Last edited by infratec on Sat Jan 08, 2011 6:18 pm, edited 2 times in total.
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 Folks, thanks!!

I will try this examples for my prog.

by the way : i bought now pb.. so api's etc will work...

I will report here my findings with the above info..

thanks again. !!!

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 »

hi Bernd,
I first tried your demo...
It works fine and i understand what happens.

But...

The calling of an other program works not as i want......

i can only call a program.pb
then the PB editor starts with this program....but is does not start it.

when i call program.exe nothing happened....

what i like is; in this place i start a program to run... ( my measuring program)

What do i not understand?....


by the way: it is very handy to split your operating program from my working program!
i like that very much.

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 »

Hi blueznl,
i tested your program demo.

It has the same problem as all inkey() programs....
when i put a long calculation program after case #t_timer
then i can not stop it anymore... it gives a crash....

what to do?

Wim
C64
Enthusiast
Enthusiast
Posts: 151
Joined: Sat Dec 18, 2010 4:40 am

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

Post by C64 »

wimapon wrote:How can i make a repeat ---- until loop which stops when i press the "s" key
For Microsoft Windows only:

Code: Select all

Repeat
  ;Do whatever here.....
  Delay(1); So you dont lock up teh CPU.
Until GetAsyncKeyState_(#VK_S) & $8000 ;Stop due to "S" press.
Baldrick
Addict
Addict
Posts: 860
Joined: Fri Jul 02, 2004 6:49 pm
Location: Australia

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

Post by Baldrick »

wimapon wrote:Hi blueznl,
i tested your program demo.

It has the same problem as all inkey() programs....
when i put a long calculation program after case #t_timer
then i can not stop it anymore... it gives a crash....

what to do?

Wim
You do realise that when you call a procedure from the main loop it will complete the functions before it returns to your main loop.
While this is happening your main loop will be not be receiving any messages at all which will simply hang your main window form?
From this it seems to me that you probably need to rethink your whole idea & break your long procedure into several smaller 1's ordered through the main loop in such a way as to return quickly & allow the main loop to do it's thing.
I would think in your case probably much better this way than to use threading which can get you into just as much strife if you start trying to make them communicate with the main loop
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 c64,
Your program does not stop when i put some calculation lines in it...
Wim
User avatar
KJ67
Enthusiast
Enthusiast
Posts: 218
Joined: Fri Jun 26, 2009 3:51 pm
Location: Westernmost tip of Norway

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

Post by KJ67 »

Threads are your friend Wim. You should think about doing as Baldrick point out and divide you code.

(Just avoid getting into situations yet where different thread read/write the same data. That is next lesson, you find more about it later under Mutex / Semaphore in blueznl’s The PureBasic Survival Guide).

Put all GUI (windows, events, menus etc., etc. ) in one main thread. Then see how many cores you have & start one thread on each for the calculation. This will (A) keep you GUI working all time and (B) speed up your calculations a lot.

If you look back on my code there are markings “;- ***” in it where I suggest you think about injecting you sampling, calculation and writing to the disk. As this is then done in a new thread, the main GUI (Procedure main()) will not be blocked by the calculations. If you can divide you calculations in a effective way, maybe later you can start thinking in multi-thread layout.
The best preparation for tomorrow is doing your best today.
C64
Enthusiast
Enthusiast
Posts: 151
Joined: Sat Dec 18, 2010 4:40 am

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

Post by C64 »

wimapon wrote:hi c64,
Your program does not stop when i put some calculation lines in it...
Wim
Of course it does, if you used it exactly as I posted it. Post your code to show what you added to it.
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 C64
This is the code... the real measuring program contains about 500 lines

Code: Select all


Repeat
  ;Do whatever here.....
  
  For i = 1 To 10000
    For j = 1 To 1000
    Next j
  Next i
  
  
  Delay(1); So you dont lock up teh CPU.
Until GetAsyncKeyState_(#VK_S) & $8000 ;Stop due to "S" press.


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,

if you want to run an external program (.exe) you need the command

Code: Select all

RunProgram()
I think in your case with the options Wait and Hide.

I changed my example above :!:
I calls now every 10 second a "ping 127.0.0.1".
That you see something I did not use the flag #PB_Program_Hide.



If you want to "start" (use) a PB sourcecode,
you can use

Code: Select all

IncludeFile "MyCalc.pb"
But better is to include the file on top and you have a procedure in this file.
This procedure can than be called everywhere in your program.

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 Bernd,
I think you allready gave the right program...
I did something wrong.. i started a program which only said "hello" in the debugger.
This debugger did not show the "hello"....

Now i used the console.. and then i could see that this program was running after
calling it by: runprogram ( "hello.exe")


So i think at you answered two questions
1: how can i stop a running loop
2: how can i call an other program.

So Bernd,
You are fantastic...
thank you verymuch.

My problem at the moment is: there are coming so much new things to me, that
i lose my way in pure basic... but... i will return to the translating of my old programs
to pure basic.. then i will encounter this new features automatic..( i think)

by the way: i have now the official pure basic V 4.51
i am going to test it inow in Linux...(Ubuntu)


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,

you are welcome :!:

I coming also from the oldschool programming way.
I hate programming languages where I 'click' everything together and as
result I get a megabyte for saying "Hello World!".

One advantage for me was, that I also knew PLC (SPS) programming,
which also acts on events and has also not a continious program flow.

I can only repeat:
It was one of the best decissions to buy PB :!:

But when you want to use your programs also in Linux you still can not use the
'Windows API' stuff :wink:

But I always find solutions for my programs to be 'cross compatible'.

If you have problems, that not everything works in Linux, look inside the Linux
section of this forum. I think there is a 'installation instruction' for Ubuntu.
In my case one debian packet was not installed which was needed, but the
check program 'checkinstall.sh' said that everything was ok.
But I can not remember which paket it was. :cry:

Bernd
Post Reply