Announcement

Collapse
No announcement yet.

How to transform TurboBasic to PBCC ??

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

  • How to transform TurboBasic to PBCC ??

    Hi
    Sorry to bother you with an old question but I am a new user of PBCC and would like to know what it can do and what not.
    In my old TurboBasic code I frequntly used ON KEY(n) GOSUB statements to do various things, regardless where the program was actually running, when the KEYn was pressed. In the old good days Turbos compiler put an event trapping test after each sentence of the code to do that but, what about PBCC? Is that still possible with some clever trick, which I have not yet succeeded to find?
    Last edited by Aimo Niemi; 8 Nov 2009, 10:43 AM. Reason: error in the heading

  • #2
    Interesting... in the "upgrading from DOS" section of the PB/CC 5.0.2 help file, "Keyword Differences" section, there is no mention at all of the "ON xxxxx" statements at all. (Although other obsolete language elements such as BLOAD/BSAVE, CLEAR, DEF SEG, INP/OUT/WAIT, etc are included in that section.)

    However, were that clearly overlooked entry included as it should have been, it would simply tell you "not supported."

    The bottom line is, you will have to query the keystrokes yourself (WAITKEY$ is good) and 'do something' when a "key of interest" has been received. Sorry, there are no "clever tricks" available.

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

    Comment


    • #3
      Aimo:

      As far as I remember, On Key(n) statement doesn't work alone, but nested in a pair of Key On/ Key Off statements. That can be replaced in PBCC with Waitkey$ or Inkey$ nested in a Do/ Loop pair with an exit granted by a key being pressed. I think you can find a lot of examples of this in the PBCC forum.

      Best regards,

      Comment


      • #4
        ...(WAITKEY$ is good)...there are no "clever tricks" available...
        WAITKEY$ is okay if you want to stall the rest of your program while it's waiting for a keystroke.

        "no clever tricks"? Not quite. Selecting INKEY$ checks the keyboard buffer and keeps on trucking. If there's something there, okay. If not, well, that's okay as well.

        The only thing is that you have to INKEY$ at each point you would like the program to jump to when that key is pressed.

        Added: Also, Aimo, in CC you cannot GOSUB to a routine outside the confines of the function you are in. You have to put the sub routine in the function calling it or change it to a SUB or FUNCTION.
        Last edited by Mel Bishop; 8 Nov 2009, 11:39 AM.
        There are no atheists in a fox hole or the morning of a math test.
        If my flag offends you, I'll help you pack.

        Comment


        • #5
          WAITKEY$ is okay if you want to stall the rest of your program while it's waiting for a keystroke.
          I acknowledge I don't do much with the Console Compiler, but wouldn't a console application looking for "F5" normally be in some kind of "wait for keystroke" state anyway?

          I suppose you could say you want this to work the MS-DOS worked, where after each statement the keyboard buffer was checked and if a magic key were found the program would branch to the nominated subroutine.

          BUt since the compiler is not inserting those event checks, you'd have to do it yourself. I suppose you could use a MACRO to pull it off...

          Code:
           
          MACRO FUNCTION CheckForKey 
           MACROTEMP X
           DIM X AS STRING 
             X = INKEY$ 
             IF X$ = F3 
                GOSUB  F3_Key 
             ELSEIF X$ = F5 THEN 
                GOSUB F5_Key
             ....
          END MACRO 
          
          FUNCTION Something 
          .....
             Statement 
             CheckForKey
             Statement 
             checkforkey 
          
             ...
              EXIT FUNCTION 
          
          F3_Key:
           stuff
          RETURN 
          
          F5_Key: 
            stuff
          RETURN
          
          END FUNCTION
          It's a thought....

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

          Comment


          • #6
            ...a console application looking for "F5" normally be in some kind of "wait for keystroke" state anyway?
            It can be, but not necessairly. In TB/PB/DOS, on key(x) gosub y keeps the program moving until the appropriate key is pressed. Then it jumps to whereever.

            Consider:

            Code:
            function pbmain()
            do
            an$ = inkey$
            if an$ = chr$(27) then exit loop          'ESCape key pressed. Abort
            if an$ = F3 then gosub DoSomething
            'other traps here
            loop
            
            exit function
            
            DoSomething:
            ...process
            ...process
            return
            
            
            end function
            I think this would be the appropriate way to go.

            I used to have all the function key codes close at hand but not any more. It's easy enough to write a small utility to get these codes anyway.
            Last edited by Mel Bishop; 8 Nov 2009, 01:04 PM. Reason: Code repair
            There are no atheists in a fox hole or the morning of a math test.
            If my flag offends you, I'll help you pack.

            Comment


            • #7
              If you got your keystrokes from a subclassed GRAPHIC WINDOW (for example) then you could build a function/sub address array in a way analogous to ON KEY GOSUB and call them from the subclass function irrespective of the main loop logic.

              Comment


              • #8
                After some 20 years I was re-reading the Turbo Basic Owner's Handbook, and think maybe the code below is more connected to the specific need.


                Code:
                 
                #COMPILE EXE
                 
                FUNCTION PBMAIN() AS LONG
                CURSOR OFF
                DO
                 DO UNTIL INSTAT
                  SLEEP 1  'Reduce the CPU Usage demand
                 LOOP
                 O$=UCASE$(INKEY$)
                 IF O$=CHR$(27) THEN EXIT LOOP
                 SELECT CASE O$
                  CASE CHR$(0,59)'F1
                   PRINT "Pressed Function Key F1"
                   'Gosub Something/Call Something
                  CASE CHR$(0,60)'F2
                   PRINT "Pressed Function Key F2"
                  CASE CHR$(0,61)'F3
                   PRINT "Pressed Function Key F3"
                  CASE CHR$(0,62)'F4
                   PRINT "Pressed Function Key F4"
                  CASE CHR$(0,63)'F5
                   PRINT "Pressed Function Key F5"
                  CASE CHR$(0,64)'F6
                   PRINT "Pressed Function Key F6"
                  CASE CHR$(0,65)'F7
                   PRINT "Pressed Function Key F7"
                  CASE CHR$(0,66)'F8
                   PRINT "Pressed Function Key F8"
                  CASE CHR$(0,67)'F9
                   PRINT "Pressed Function Key F9"
                  CASE CHR$(0,68)'F10
                   PRINT "Pressed Function Key F10"
                  CASE CHR$(0,71)'Home
                   PRINT "Pressed Home Key"
                  CASE CHR$(0,72)'AUp
                   PRINT "Pressed Arrow Up Key"
                  CASE CHR$(0,73) 'PUp
                   PRINT "Pressed Page Up Key"
                  CASE CHR$(0,75) 'Left
                   PRINT "Pressed Left Arrow Key"
                  CASE CHR$(0,77) 'Right
                   PRINT "Pressed Right Arrow Key"
                  CASE CHR$(0,79) 'End
                   PRINT "Pressed End Key"
                  CASE CHR$(0,80) 'ADown
                   PRINT "Pressed Arrow Down Key"
                  CASE CHR$(0,81) 'PDown
                   PRINT "Pressed Page Down Key"
                  CASE CHR$(0,82) 'Ins
                   PRINT "Pressed Insert Key"
                  CASE CHR$(0,83) 'Del
                   PRINT "Pressed Delete Key"
                  END SELECT
                LOOP
                END FUNCTION

                Comment


                • #9
                  Aimo thanks all of you

                  Originally posted by Chris Holbrook View Post
                  If you got your keystrokes from a subclassed GRAPHIC WINDOW (for example) then you could build a function/sub address array in a way analogous to ON KEY GOSUB and call them from the subclass function irrespective of the main loop logic.
                  Thank you Chris. I will try to understand this. Meanwhile, I think, I must use INKEY$ and create my own event handling routine. And then, of course, I must try to find right places, where to put this routine so that it works as intended.
                  My difficulty lies in that I have written a calculator program (PcCalculator) where the user can create his own program loops and, if now his (or her) loop is too slow or if he accidentally creates a never-ending loop, then there must be some way to get rid of it. So, I must try to find all possible routes, where the user loop may visit and put then my event trapping routine there.
                  Last edited by Aimo Niemi; 8 Nov 2009, 07:55 PM.

                  Comment


                  • #10
                    This code should carry a health warning, as there are limits to what you can do with subclassing and GRAPHIC WINDOWS. But is does more or less answer Aimo's question, which included the words "clever trick"!

                    Code:
                    ' to demonstrate ONKEY behaviour using a subclassed graphic window
                    #compile exe
                    #debug display
                    #include "WIN32API.INC"
                    %KEY_ESC     = 27
                    
                    global hGW as dword
                    global GrDialogProc as long
                    global GrStaticProc as long
                    global ghstatic as dword
                    type tONKEY
                        key as long
                        procptr as dword
                    end type
                    global gONKEY() as tONKEY
                    
                    declare sub proto()
                    '-------------------------------------------------------------------------------
                    function GrProc(byval hWnd as dword, byval wMsg as dword, byval wParam as dword, byval lParam as long) as long
                      local s as string
                      local i as long
                    
                      select case wMsg
                        case %wm_char                          ' here we catch keys
                            s = "SUBCLASS PROC DETECTS <" + chr$(wparam) + ">"
                            sendmessage getparent(hWnd), %WM_SETTEXT, 0, strptr(s)
                            for i = lbound(gONKEY()) to ubound(gONKEY())
                                if gONKEY(i).key = wparam then
                                    call dword gONKEY(i).procptr using proto()
                                    exit for
                                end if
                            next
                      end select
                    
                      function = CallWindowProc(GrStaticProc, hWnd, wMsg, wParam, lParam)
                    
                    end function
                    '=============================================
                    '=============================================
                    ' OUR ONKEY SUBS - could be functions
                    ' but either way all must have the same type and params
                    '=============================================
                    '---------------------------------------------
                    sub procA
                        ? "IN PROC A"
                        graphic attach hGW, 0
                        graphic clear %cyan
                    end sub
                    '---------------------------------------------
                    sub procB
                        ? "IN PROC B"
                        graphic clear %red
                    end sub
                    
                    function pbmain () as long
                        local r as rect
                        local qtc as quad
                        local s, skey as string
                    
                        graphic window "ONKEY TEST", 100, 100, 450, 450 to hGW
                        '=========================================
                        ' START THE SUBCLASSING
                        '=========================================
                        ' Retrieve static handle of graphic window
                        ghStatic = GetWindow(hGW, %GW_CHILD)
                        ' Subclasses Graphic control
                        GrStaticProc = SetWindowLong(ghStatic, %GWL_WNDPROC, codeptr(GrProc))
                        '=========================================
                        graphic attach hGW, 0
                        graphic color %black, %white
                        graphic set pos ( 20, 340)
                        graphic print "ESC to exit"
                        '=========================================
                        ' LOAD UP THE ONKEY array - you can wrap this up in a function
                        '=========================================
                        dim gONKEY(0 to 1 ) as global tONKEY
                        gONKEY(0).key = asc("A"): gONKEY(0).procptr = codeptr(procA)
                        gONKEY(1).key = asc("B"): gONKEY(1).procptr = codeptr(procB)
                        '=========================================
                        ' MAIN PROGRAM LOOP - THIS ONE IS RATHER SIMPLE
                        '=========================================
                        do
                            graphic ellipse  (rnd(0, 350),rnd(0, 350) ) - (rnd(0, 350) ,rnd(0, 350) ), rnd(0, &hFFFFFF), rnd(0, 6)
                            graphic inkey$ to skey
                            sleep 50
                        loop until skey = $esc
                        '=========================================
                        ' CLEAN UP SUBCLASSING
                        '=========================================
                        SetWindowLong(ghStatic, %GWL_WNDPROC, grStaticProc)
                        '=========================================
                        ' FINISHED WITH GRAPHIC WINDOW
                        '=========================================
                        graphic window end
                    end function

                    Comment


                    • #11
                      If you re-did the program as a GUI program instead of a console program, you could assign keyboard accelerators to your 'keys of interest, ' the user could then hit the magic key OR click a buttton and that would be that.

                      MCM
                      PS: My imagination or...on your linked screen the 'proof' is not a proof since the evaluation with the X and Y substitutions does not equal zero? However, it IS close (0.000000003)
                      Michael Mattias
                      Tal Systems Inc. (retired)
                      Racine WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        Nice application!

                        Comment


                        • #13
                          Originally posted by Michael Mattias View Post
                          PS: My imagination or...on your linked screen the 'proof' is not a proof since the evaluation with the X and Y substitutions does not equal zero? However, it IS close (0.000000003)
                          Yes, you are right. That is one of the reasons I am now trying to transform the code. But, have you tried to calculate the example with a windows calculator? If you have, you may have noticed that the whole example is a joke - or a mine, if you are using WIN95 calculator or some
                          of its earlier versions.:laugh:

                          Comment


                          • #14
                            Aimo:

                            Just in case. When using a loop to run an iterative or recursive routine, a way to avoid an infinite loop is to add a second stop condition (normally the right result being obtained), for instance a loop counter. So if the loop counter reach a pre-determined value then the loop ends, and you can mark the result as inaccurate. Depending on the precision of the variable you use, sometimes those routines start oscillating around the right result instead of converging, so another way is to detect that oscillation.

                            Regards,
                            Last edited by Manuel Valdes; 9 Nov 2009, 02:02 PM.

                            Comment

                            Working...
                            X