Silverfrost Forums

Welcome to our forums

How To Sense ESC Key (Non Blocking)?

18 Jun 2014 6:40 #14231

Hi,

I've been tasked with modifying an existing legacy Fortran program. My background: I'm somewhat familiar with C programming, trying to learn Fortran now. The program is quite large and involves controlling electronic instrumentation with massive number crunching. It executes a main loop with many many iterations, each iteration taking several seconds to run. I am able compile and debug it with the Silverfrost 7.0 Compiler under Visual Studio 2010.

My task is to be able to interrupt processing the loop iterations when the ESC key is pressed. I've found some related example code but all seem to block execution while waiting for input. I need an interface that will check for ESC key and continue if it was not pressed, or set a flag if it was.

Any suggestions? I've already learned a great deal from this Forum and appreciate the help both past and present 😃

Tim

19 Jun 2014 11:02 #14236

Have you tried:

SUBROUTINE GET_KEY_OR_YIELD@(KEY) INTEGER (KIND=2) KEY

19 Jun 2014 12:44 #14237

If you'd use Clearwin+ adding modern GUI to your code then there are other options in addition to the one above Ian mentioned. You can for example click on specified buttons, images, radiobuttons, icons, graphs, line on graphs etcetcetc or mouse wheel or different mouse button and keyboard combinations which can change some variable on click. Keyboard input can be also handled via accelerator keys. This change then is interpreted by your code the way you want.

26 Jun 2014 11:08 #14273

Sorry for the late response I've been away for a week...

Thanks Ian The GET_KEY_OR_YIELD routine sounds exactly like what I need. I can't get it to build though, my compiler cant find that routine. Do you have an example of its actual use? Thanks

Dan: thanks, I wish I had time to investigate this but my task for now is to simply be able to break out of a loop from a key press.

Tim

26 Jun 2014 11:30 #14274

Put the statement :

      include <windows.ins>

at the top of the routine using the function. Ian

26 Jun 2014 12:59 #14278

I guess I'm still missing something...

Here's the compiler message and the code in question. Line 17 is the declaration for the KEY variable. Line 38 is the call to GET_KEY_OR_YIELD.

Note: this S/W was written by someone else 30 years ago, please pardon the coding style/practices 😃

------ Build started: Project: RATS_PTLOA, Configuration: Debug .NET ------ Building project RATS_PTLOA... Updating References... Compiling file: brktst.f C:\FTN_RATS\RATS PTLOA\brktst.F(17) : comment 981: Specifying the kind of the type INTEGER with a constant is non-portable - 'SELECTED_INT_KIND(4)' would be better C:\FTN_RATS\RATS PTLOA\brktst.F(38 ) : error 32: Statement not recognised There were compile errors, abandoning link... Build log saved at: 'file://C:\FTN_RATS\RATS PTLOA\Debug\NET\buildlog.txt' RATS_PTLOA build failed. ========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ========== SUBROUTINE HPIBX(NAMP,ICOUN,A)

      USE NetDeclarations
      include <windows.ins> 
      COMMON/STUDA/IA(25),IB(25),IC(25)
      COMMON/LUS/LU,LU1,IDCB(144)
      COMMON/RDPD/MDBF(150)
      DIMENSION BUF(3,25),A(*),AMAX(3),AMIN(3)

      CHARACTER (LEN=*), PARAMETER :: NUL = CHAR(0)                
      CHARACTER*128 ACQDEF                                      
      CHARACTER*128 ACQTST                                     
      CHARACTER*128 ACQDAT                                         
      INTEGER       ISCNUM                                         
      INTEGER       ISTTUS                                      
      INTEGER (KIND=2) KEY

    
      NRDS=NAMP
      PIR=0.017453292
      SMSN=0.
      SMCN=0.
      DO 10 I=1,NRDS
C     TRIGGER THE BUS DEVICE
      ICYCL=0

      CALL USDELAY(100)

      IERCNT = IERCNT+1 
      ISTAT=IAND(ISTAT,Z'100') 
      LW=0!ISSW(15)
      ICYCL=ICYCL+1
      IF(ICYCL.GE.1000) GO TO 700
      IF(LW.GT.256)WRITE(LU,1050)ISTAT
1050  FORMAT(O6)
      
      GET_KEY_OR_YIELD@(KEY) 
      IF (KEY.EQ.27) GOTO 700                                       

      WRITE(ACQDEF,50)NUL                                              
50    FORMAT('ACQ DEF',A1)                                             
      WRITE(ACQTST,52)NUL                                               
52    FORMAT('ACQ TST',A1)                                             
      WRITE(ACQDAT,54)NUL                                              
54    FORMAT('ACQ DAT',A1)                                              
      ISCNUM = 1                                                       
      ISTTUS = 0                                                       
      CALL RANGE_CONTROL__MEAS_ACQUIRE(ACQDEF, ACQTST, ISCNUM,         
     +ACQDAT, ISTTUS)                                                  
                                                            
      SMSN=SMSN+SIN(BUF(3,I)*PIR)
      SMCN=SMCN+COS(BUF(3,I)*PIR)
10    CONTINUE
      FN=FLOAT(NRDS)
      FNM=FLOAT(NRDS-1)
      DO 20 M=1,3
      K=M-1
      SUM=0.
      SUM2=0.
      VAR=0.
      AVG=0.
      STD=0.
      AMAX=-100.
      AMIN=10.
      DO 30 N=1,NRDS
      VAL=BUF(M,N)
      SUM=SUM+VAL
      SUM2=SUM2+VAL*VAL
      IF(BUF(M,N).GT.AMAX(M))AMAX(M)=BUF(M,N)
      IF(BUF(M,N).LT.AMIN(M))AMIN(M)=BUF(M,N)
30    CONTINUE
      AVG=SUM/FN
      VAR=(SUM2-FN*AVG*AVG)/FNM
      IF(VAR.GT.0) STD=SQRT(VAR)
      K=K+M
      A(K)=AVG
      IF(K.LT.5) A(K+1)=STD
20    CONTINUE
26 Jun 2014 2:05 #14281

Use:

      integer*2 key
.
.
.
.
      call get_key_or_yield@(key)
.
.
.

Note: integer1 is (Kind=1) integer2 is (kind=2) integer4 is (kind=3) integer8 is (kind=4)

Oh yes!, you are using .NET, I don't and I think there is an alternative use command for inserting the definitions specified in windows.ins, but I have no idea what it is. I'm old enough to think thast this style of coding is up to date. Ian

27 Jun 2014 1:33 #14288

Hi Ian, (Don't worry, I'm close to giving up on this!)

My program now compiles (THANKS!), but as the GET_KEY_OR_YIELD statement executes, a Standard Output window is popped open with a blinking prompt in the upper left. Program execution pauses at this point. If I type a key the proper key code is returned in the KEY variable, the window stays open, and program execution continues.

Apparently the subroutine call blocks, even though it is advertised to yield, which makes it unusable in my application.

Any ideas ?!! Thanks

Tim

27 Jun 2014 2:57 #14289

Hi Twitch,

Looks to me like you built a 'console app', and to get something that allows you to continue running while waiting for a keypress you probably need to create a proper Windows app.

So why not do the latter - all you really need is to put 'WINAPP' at the front of your code (preceded by 6 spaces if like me you code 'Gangnam style', i.e. Fortran 77 fixed format)

Eddie

30 Jun 2014 6:49 #14304

Hi Eddie,

Thanks for trying to help. My application already specifies 'WINAPP' at the top of the code. It also specifies: 'Windows Application' 'Yes' in the project properties linker settings page.

Is there some other way to suppress the standard output window?

Tim

9 Jul 2014 7:56 #14317

I'll bump this thread one more time in case anyone has any ideas and can chime in

Thanks

Tim

9 Jul 2014 9:30 #14318

Well, you could give your main application a class name using %nc; then launch an independent window with start_pprocess@ - maybe during startup with %sc). The second application contains just a button in its window, defined using %bt, and if you must, attach Esc as an accelerator key using %ac. Then, when your second app senses the button press, it can send a message to your primary application using send_text_message@ that tells it to shut down - and it can also shut itself down!

Eddie

Please login to reply.