Announcement

Collapse
No announcement yet.

Working around old QBasic DEF SEG

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

  • Working around old QBasic DEF SEG

    I have just installed PBCC and am converting a large number of QB programs.

    I have some code using DEF SEG and PEEK and POKE at characters on the screen to audit them .

    Here is the Code
    TADDR% is the address of the color monitor data buffer (&HB800). I am Peeking at a character a time and putting it inot IBUFF$.

    FOR IDBPTR = 1 TO LEN(IBUFF$)
    DEF SEG=TADDR%: MID$(IBUFF$,IDBPTR,1) = CHR$(PEEK(IDPOS)): DEF SEG
    IDPOS = IDPOS + 2
    NEXT IDBPTR

    Can someone tell me how PBCC would handle this. I expect PBCC has different capabilities for screen use, but I am a novice. What I think I want to do is to get all my programs converted so they run as they do today, then start putting new function in. So right now I just want to figure out how PBCC would implement this.

  • #2
    You might use the screen function which is basically the same as QBs.
    and the SCREENATTR for the color attribute

    ASCIIVAL&=SCREEN(ROW&,COL&)
    C%=SCREENATTR(ROW&,COL&)
    Last edited by Fred Buffington; 9 Dec 2008, 06:04 PM.
    Client Writeup for the CPA

    buffs.proboards2.com

    Links Page

    Comment


    • #3
      Thanks, Fred. That will require some recoding, but it is a better solution.

      Comment


      • #4
        Wouldn't keeping track of what you or the user put on the screen be an even better solution?

        Nuthin' goes on that screen save what you PRINT or the user types when you give him a LINE INPUT or INKEY$/WAITKEY$ to do it with.

        Screen-scraping like this was fairly popular 'back in the day' when you could have TSR programs putting stuff on your MS-DOS screen from somewhere other than within your program... but ain't no such thing under Windows.


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

        Comment


        • #5
          I agree with Michael.

          I modify an old QB4.0 program for a company in IL that reads the characters from the screen to redo lcase to ucase and fractions to decimal and also to
          print to the printer. Extremely slow, in my opinion, but it's their program.
          Client Writeup for the CPA

          buffs.proboards2.com

          Links Page

          Comment


          • #6
            Well, I am still horsing around with this.

            Has anyone out there ever found a way to get the address of a CONSOLE SCREEN buffer?

            Comment


            • #7
              yes - http://www.powerbasic.com/support/pb...=screen+scrape

              Comment


              • #8
                another possibility is to use contools.
                Code:
                sResult$ = ConsolePEEK(lType&, _
                                       lRow&, _
                                       lColumn&, _
                                       lLength&)
                Contools is a third party add-on that is highly recommended by PB.
                The consolepeek gets the info from the input buffer according to the hlp file.
                It also has neat things like texboxes, Progress bar, and lots more.
                Client Writeup for the CPA

                buffs.proboards2.com

                Links Page

                Comment


                • #9
                  del
                  Last edited by Jerry Fielden; 10 Dec 2008, 10:45 PM. Reason: Not compatible with thread

                  Comment


                  • #10
                    >You might be interested in doing block copy and paste for the console screens.

                    PCOPY, PAGE
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                    • #11
                      Just note that QB pages start at 0 and PB pages start at 1 for pcopy and page. (QB uses screen(mode,colorswitch,apage,vpage instead of page)
                      Last edited by Fred Buffington; 10 Dec 2008, 10:59 PM.
                      Client Writeup for the CPA

                      buffs.proboards2.com

                      Links Page

                      Comment


                      • #12
                        Has anyone out there ever found a way to get the address of a CONSOLE SCREEN buffer
                        I'm not sure there is a user-accessible address to anything. I am sure you should not be doing anything with it even if you can find it.

                        Lots of stuff in Windows does not work the way MS-DOS did.... specifically, Windows is really, really, REALLY short on "real" things and very, very, VERY long on "virtual" things.

                        That said, Windows supports doing a lot of things with a simple function call to its API, things you could not do under MS-DOS except by PEEK'ing and POKE'ing or calling an &h10 or &h21 interrupt.

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

                        Comment


                        • #13
                          Originally posted by Michael Mattias View Post
                          Lots of stuff in Windows does not work the way MS-DOS did.... specifically, Windows is really, really, REALLY short on "real" things and very, very, VERY long on "virtual" things.
                          this (extract from code via link in post #7 above) is a way of getting the console:

                          Code:
                                                  getWindowThreadProcessID(hWnd,BYVAL VARPTR(dwPid))
                                                  IF AttachConsole(@dwpid) = 0 THEN
                                                      ? "failed to attach console",%MB_TASKMODAL,"error"
                                                      EXIT SELECT
                                                  END IF
                                                  hConsole = GetStdHandle(%STD_OUTPUT_HANDLE)
                                                  GetConsoleWindow
                                                  IF 0 = readConsoleOutputCharacter(hConsole, BYVAL VARPTR (szbuffer), 2000, BYVAL 0, lcount) THEN
                                                      ? "failed to read console",%MB_TASKMODAL,"error"
                                                      EXIT SELECT
                                                  END IF
                                                  ? STR$(lcount) + szbuffer
                                                  FreeConsole ()
                          Nothing like reading the console buffer at 0xB800, is it?

                          Also, ISTR that the buffer supplied is a "Read Only" buffer - you cannot write to the screen of that DOS application, more's the pity. PLEASE someone tell my I'm wrong!

                          Comment


                          • #14
                            Chris you can use the same buffer/string when you write back using ReadConsoleOutputCharacter API. I do it all the time with WriteConsoleOutput after doing a ReadConsoleOutput. Or did I misunderstand you?

                            Notice the SUB CopyArea that uses ReadConsoleOutput API can read in 1 charecter by making a call like CopyArea 1, 1, 1, 1, Buf$, it also reads in its Color attribute in that one call. To write that one Character back to the bottom right, just use PasteArea 24, 80, 24, 80, Buf$

                            I don't use Read & WriteConsoleOutputCharacter because I have to make an extra call to also get its color. Thanks to Semen, I started using the WriteConsoleOutput method.

                            Below is a couple of subs I wrote to let me block copy any portion of a screen and put it back, even 1 character. Also a little speed test using Pcopy verses the APIs. You won't see a screen for a while because of the printing in Page.





                            Code:
                            #COMPILE EXE
                            #REGISTER NONE
                             #INCLUDE "C:\PBCC40\WINAPI\WIN32API.INC"
                             
                             
                             SUB CopyArea (r1&, c1&, r2&, c2&, Buf$)       'Copy any area up to full screen
                                 LOCAL SIZE AS DWORD
                                 LOCAL Rectangl AS SMALL_RECT
                                 Buf$ = SPACE$((c2&+1-c1&) * (r2&+1-r1&) * 4)
                                 SIZE = MAKDWD(c2&+1-c1&, r2&+1-r1&)
                                 Rectangl.xTop = r1&-1                                ' Set Row and column
                                 Rectangl.xLeft = c1&-1                           ' address of all 4 sides
                                 Rectangl.xBottom = r2&-1                        ' of a Rectangl for Read
                                 Rectangl.xRight = c2&-1                                    ' or for Write.
                                 ReadConsoleOutput GETSTDOUT, BYVAL STRPTR(Buf$), BYVAL SIZE, 0&, Rectangl
                             END SUB
                            
                            
                             SUB PasteArea (r1&, c1&, r2&, c2&, Buf$)        'Paste area up to full screen
                                LOCAL SIZE AS DWORD
                                LOCAL Rectangl AS SMALL_RECT
                                SIZE = MAKDWD(c2&+1-c1&, r2&+1-r1&)           'Size of rectangle
                                Rectangl.xTop = r1&-1                       ' Set Row and column
                                Rectangl.xLeft = c1&-1                      ' address of all 4 sides
                                Rectangl.xBottom = r2&-1                    ' of a Rectangle for Read
                                Rectangl.xRight = c2&-1                     ' or for Write.
                                WriteConsoleOutput GETSTDOUT, BYVAL STRPTR(Buf$), BYVAL SIZE, 0&, Rectangl
                                Buf$ = ""
                             END SUB
                                                                          
                             
                             '====================================================================================
                             '                     M a i n
                             '====================================================================================
                             
                            FUNCTION PBMAIN()
                                
                            ' Using PCOPY and Print, printing 24x80 screen 100 times
                                
                             t&=TIMER
                             PCOPY 1,2 : PAGE 2, 1
                             FOR xx& = 1 TO 100
                              FOR row& = 1 TO 24
                               FOR col&= 1 TO 80
                                 tmp$= CHR$(row& + 64)
                                 tAtrib&=row& + 15
                                 bg&= tAtrib&\16  : fg& = tAtrib& MOD 16
                                 LOCATE row&, col& : COLOR fg&, bg&
                                 PRINT Tmp$;
                               NEXT
                              NEXT
                             NEXT xx&
                             PCOPY 2, 1 : PAGE 1, 1
                             t2&= TIMER-t&
                             COLOR 0, 15
                             LOCATE 25, 60: PRINT STR$(t2&);
                            
                            WAITKEY$
                            
                            
                            ' Using Write & Fill Console APIs.........Much faster than Pcopy method
                            
                            COLOR 0,0: CLS
                            
                            
                            
                             hOut& = GETSTDOUT
                             t&=TIMER
                             FOR xx& = 1 TO 100
                              FOR row& = 0 TO 23
                               FOR col&= 1 TO 80
                                 tmp$= CHR$(row& + 64)
                                 tAtrib&=row& + 15
                                 WriteConsoleOutputCharacter hOut&, BYCOPY Tmp$, LEN(Tmp$), MAKDWD(col&, row&), 0
                                 FillConsoleOutputAttribute hOut&, tAtrib&, LEN(Tmp$), MAKDWD(col&, row&), 0
                               NEXT
                              NEXT
                             NEXT xx&
                             t2&=TIMER-t&
                             COLOR 0,15
                             LOCATE 25, 60: PRINT STR$(t2&);
                             WAITKEY$
                            
                            
                            ' Somebody else had written the first two test, I added this last test to show the WriteConsoleOutput method.
                            
                            ' Using WriteConsoleOutput API to do the 100 Screens
                            
                               CopyArea 1, 1, 24, 80, Buf$    'Copy it into Buf$ before using CLS
                               
                                 COLOR 0,0: CLS
                            
                               t&=TIMER
                            
                               FOR xx& = 1 TO 100
                                 PasteArea 1, 1, 24, 80, Buf$
                               NEXT xx&
                               
                               
                              t2&=TIMER-t&
                              COLOR 0,15
                              LOCATE 25, 60: PRINT STR$(t2&);
                              WAITKEY$
                              
                              
                            END FUNCTION


                            On my machine it takes 25 seconds to print the 24x80 screen 100 times wrapped in PCOPY.

                            It takes 8 seconds using the second test, using WriteConsoleOutputCharacter

                            It took a whooping 1 second using the PasteArea Sub, the WriteConsoleOutput method.

                            I've been testing this method for almost 10 years and, no failure yet. My Screen Making program, everything in it uses this method.

                            Comment


                            • #15
                              >>Has anyone out there ever found a way to get the address of a CONSOLE SCREEN buffer?
                              >yes - http://www.powerbasic.com/support/pb...=screen+scrape


                              That link does not "get the address" of a CONSOLE SCREEN buffer; it does, however, scrape the screen.

                              "Get the address" is one "how"; the link provides another "how"; the code on this page is yet another "how."

                              You might think "Scrape the screen" is the "what," but you'd be wrong about that. "Scrape the screen" is just another "how", the "what" being, " how do I get what is currently on my screen?"

                              Oh, yes, another "how?" "Keep track of what you put on it."
                              Michael Mattias
                              Tal Systems (retired)
                              Port Washington WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment


                              • #16
                                Roy,

                                Here's an example of ReadConsoleOutputCharacter and WriteConsoleOutputCharacter, plucking a box out of the center of the screen and displaying it at a different location, reading in one character at a time.

                                You don't need to know the screen address in memory to do this.

                                It might be the closes thing to your dos peek and poke.




                                Code:
                                #COMPILE EXE
                                
                                
                                 #INCLUDE "C:\PBCC40\WINAPI\WIN32API.INC"
                                
                                
                                
                                 SUB fillscreen()
                                  PCOPY 1, 2 :PAGE 2, 1
                                  COLOR 1, 11
                                  FOR r& = 1 TO SCREENY                   ' Fill 25x80 screen with chars .
                                    FOR c& = 1 TO SCREENX
                                        PRINT CHR$(176);
                                    NEXT c&
                                  NEXT r&
                                  SLEEP 500
                                   COLOR 14, 1 : LOCATE 10, 32                               'make a box
                                   LOCATE 11, 32:PRINT CHR$(201, 205, 205, 205, 205, 205, 205, 205, 205, _
                                              205, 205, 205, 205, 205, 205, 187)
                                   LOCATE 12, 32:PRINT CHR$(186) + "  This is an  " + CHR$(186)
                                   LOCATE 13, 32:PRINT CHR$(186) + "   API Test   " + CHR$(186)
                                   COLOR 15, 4
                                   LOCATE 14, 32:PRINT CHR$(186) + " for copying  " + CHR$(186)
                                   LOCATE 15, 32:PRINT CHR$(186) + " Text AREAS   " + CHR$(186)
                                   LOCATE 16, 32:PRINT CHR$(200, 205, 205, 205, 205, 205, 205, 205, 205, _
                                              205, 205, 205, 205, 205, 205, 188)
                                   PCOPY 2, 1 : PAGE 1, 1
                                
                                 END SUB
                                
                                
                                 FUNCTION PBMAIN ()
                                    LOCAL col AS LONG, nbr AS LONG
                                    LOCAL Row AS LONG
                                
                                    LOCAL Buffer() AS STRING      ' Array for the characters
                                    LOCAL Buffer2() AS LONG     ' Array for its colors
                                
                                    CONSOLE SET SCREEN 25, 80
                                
                                    FillScreen                    ' Fill up the screen
                                
                                    REDIM Buffer(1 TO 2000)
                                    REDIM Buffer2(1 TO 2000)
                                
                                   'Picking out the Box in the center of the screen
                                
                                   FOR row = 10 TO 15
                                     FOR col = 31 TO 46
                                       INCR nbr
                                
                                       Buffer(nbr) = SPACE$(1)
                                     
                                       ReadConsoleOutputCharacter _              'Read a Character
                                       GETSTDOUT, BYVAL STRPTR(Buffer(nbr)), _
                                       1, BYVAL MAKDWD(col, Row), 0
                                       
                                       ReadConsoleOutputAttribute _               'Read its color
                                       GETSTDOUT, Buffer2(nbr), _
                                       1, BYVAL MAKDWD(col, Row), 0
                                       
                                
                                     NEXT col
                                   NEXT row
                                
                                   SLEEP 3000
                                    COLOR 0,7:CLS
                                   PRINT " The screen is cleared to reshow box in bottom right corner"
                                   PRINT " using the WriteConsoleOutputCharacter API without any color added"
                                   SLEEP 3000
                                
                                   nbr = 0      ' Reset nbr is needed
                                
                                  FOR row = 19 TO 24
                                    FOR col = 64 TO 79
                                
                                       INCR nbr
                                
                                       WriteConsoleOutputCharacter _               'Write a character
                                       GETSTDOUT,  BYVAL STRPTR(Buffer(nbr)), _
                                       1, BYVAL MAKDWD(col, row), 0
                                
                                     '  WriteConsoleOutputAttribute _                'Write its colors
                                     '  GETSTDOUT,  Buffer2(nbr), _
                                     '  1, BYVAL MAKDWD(col, row), 0
                                
                                   NEXT col
                                  NEXT row
                                
                                
                                   SLEEP 3000
                                
                                   nbr = 0      ' Reset nbr is needed
                                
                                  FOR row = 19 TO 24
                                    FOR col = 64 TO 79
                                
                                       INCR nbr
                                
                                      ' WriteConsoleOutputCharacter _               'Write a character
                                      ' GETSTDOUT,  BYVAL STRPTR(Buffer(nbr)), _
                                      ' 1, BYVAL MAKDWD(col, row), 0
                                
                                       WriteConsoleOutputAttribute _                'Write its colors
                                       GETSTDOUT,  Buffer2(nbr), _
                                       1, BYVAL MAKDWD(col, row), 0
                                
                                   NEXT col
                                  NEXT row
                                
                                  PRINT
                                  PRINT "Now showing its color using the WriteConsoleOutputAttribute API"
                                
                                
                                
                                 WAITKEY$
                                
                                END FUNCTION
                                Last edited by Jerry Fielden; 14 Dec 2008, 03:58 PM. Reason: Changed Buffer2 to Long

                                Comment


                                • #17
                                  It might be the closes thing to your dos peek and poke
                                  Any use of pointer variables are PEEKs and POKEs. e.g
                                  Code:
                                  Z? =   PEEK(address) 
                                  'is equivalent to 
                                  LOCAL pB AS BYTE PTR 
                                  pb =  VARPTR(something) or any other address. 
                                  Z? =  @pB
                                  The only (!!) real difference between PEEKing/POKEing in MS-DOS and Windows is, under MS-DOS the address is REAL and under Windows it is VIRTUAL.

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

                                  Comment


                                  • #18
                                    Got this working fine. Thanks for your help, Mike Did it with Screen and Print commands.
                                    Roy

                                    Comment


                                    • #19
                                      Jerry, got my routine working with Screen and Print commands, so thank for your help.
                                      Roy

                                      Comment


                                      • #20
                                        Fred. Used this method and it works. Thank. Roy

                                        Comment

                                        Working...
                                        X