No announcement yet.

Capture PB-DOS Graphics screens in WinXP

  • Filter
  • Time
  • Show
Clear All
new posts

  • Capture PB-DOS Graphics screens in WinXP


    WinXP won't allow PrintScreen to capture a PB-DOS Graphics screen to the clipboard, which pretty much makes my PB-DOS design software worthless.

    This was addressed here two years ago with final conclusion "no can do." Has anybody found a workable answer since then? I've tried the best of the Screen Capture utilities with no luck - they can do DOS text screens, but not graphics screens.

    Is there a coding workaround - capture the screen in my code and somehow spit it out as a BMP or something?


    Dan Raymer


  • #2

    just a little idea (I did not think thoroughly through it,
    neither test it, but it should work) :

    You could write a DOS TSR which can be called with a hot key,
    or via an interrupt, to save the current display to a file.
    This would, of course, mean that you write yourself a routine
    for capturing the screen contents in every video mode you expect
    to encounter (and this may be a lot if you include SVGA modes...)
    - You might hook the "PrintScreen" key as the hotkey for this routine.

    You would then need a batch file which would first install the TSR,
    then execute the program of which you want to capture the output,
    then uninstall the TSR.

    I know this is complicated, but if in two years no one else found
    a better solution, then I doubt there is one.


    Hans Ruegg


    • #3
      The best and free screen grabber I have found on the web
      if PRTSCN32

      Just Goggle for it.

      Best of luck




      • #4
        ...still looking! And when I Google for PRTSCN32, all I get is a posting on a Powerbasic jForum - this one!

        Won't You Please, Please Help Me!



        • #5
          OK, now I've found PrntScrn32, but it has no luck with a full-screen Dos Window either, and WinXP forces graphics screens to full screen. So, any more ideas out there?



          • #6
            Somewhere I used to have the code to stuff a screen into a BMP.
            It wasn't difficult code as it worked pixel by pixel left to right
            bottom to top. The trick was the header and the pallet. You should
            be able to bypass that, though, if you convert your colors to 24bit.

            Here's the header UDT and, if you want I'll post the code to display
            a BMP. That might help you get started.

            TYPE BMPheaderTYPE
              Ident     AS INTEGER      ' 19778 = CVI("BM") if .BMP format
              Fsize     AS LONG         ' File size in bytes
              Reserved  AS STRING * 4   ' junk
              Offset    AS LONG         ' file offset to start of data
              Version   AS LONG         ' 40 = Windows 3.x  12 = OS/2
              Cols      AS LONG         ' width in pixel columns
              Rows      AS LONG         ' height in pixel rows
              Planes    AS INTEGER      ' number of color planes
              ClrBits   AS INTEGER      ' number of bits per color
              Packed    AS LONG         ' 0 if not packed
              PackSize  AS LONG         ' actual length of data
              ''''''''''''''''''''''''''' OS/2 stops here
              Xscale    AS LONG         '
              Yscale    AS LONG         '
              Colors    AS LONG         ' actual # of colors used
              ImpColors AS LONG         ' important colors used 0 = all
            END TYPE
            [email protected]



            • #7
              PLEASE, post the complete code! It's PB-DOS, right?




              • #8

                It was PB DOS. If I can find it, I'll throw it up.

                [email protected]



                • #9
                  I'm curious...

                  Does the technique of reading a character position from memory from
                  the known place in memory for line position, cursor position, and
                  attributes with PB for DOS, then storing it in one of the other
                  allowed 'screens' in DOS also work in WIN XP?

                  Can you then simply use direct memory writes, rewrites, to move
                  chunks of the screen around and replace them at will the same way
                  you do in PB DOS, but in WIN XP?

                  Say you snip a part of the screen from memory at: ]

                              DEF SEG = &HB000
                              FOR NZ% = MCLL% TO MCLR%
                                 HXX% = PEEK(NZ% + 8000)
                                 POKE (NZ%), HXX%
                              NEXT NZ%
                  Then plug it back in there after fiddling with that same space on
                  the screen with something else you do?

                  I've used this technique in PB for DOS for many years to work out
                  help boxes in all my work. But is this over for me if I attempt
                  to run DOS stuff under WIN XP as well?


                  Mike Luther
                  [email protected]
                  Mike Luther
                  [email protected]


                  • #10
                    Does the technique of reading a character position from memory from
                    the known place in memory for line position, cursor position, and
                    attributes with PB for DOS, then storing it in one of the other
                    allowed 'screens' in DOS also work in WIN XP?
                    Works OK in an XP's WDM.
                    In my DOS Core Wars simulator I write directly to video memory in Screen 13, and that works too under XP.


                    Try Online TrID file identifier! Recognize over 1.400 filetypes and counting...
                    Give a powerfull scriptable Lua interface to your application with PowerBLua
                    PBTracer - Tracer / Profiler for PowerBASIC (soon!)

                    [This message has been edited by Marco Pontello (edited October 26, 2004).]
                    -- The universe tends toward maximum irony. Don't push it.

                    File Extension Seeker - Metasearch engine for file extensions / file types
                    Online TrID file identifier | TrIDLib - Identify thousands of file formats


                    • #11
                      Are you looking for



                      • #12
                        In PDS 7.1 used this code with Quick Pack for primative screens
                        For row = 1 to lastrow
                          Call ReadScrn(0,row,1,Buf$)
                          For org = 1 to 80
                             Char = asc(mid$(buf$,org,1))
                             if char <32 or char > 22 then mid(buf$,org,1) = "."
                           Mid$(buf$,80,1) = " "
                        'Also have code to save to clipboard from DOS programs or
                        'write to disk and use SHELL


                        [This message has been edited by Mike Doty (edited October 26, 2004).]


                        • #13
                            'Write a file to the Windows 95+ clipboard
                            'DOS programs can SHELL "FILENAME"
                            $COMPILE EXE
                            $DIM ALL
                            $INCLUDE "WIN32API.INC"
                          FUNCTION WriteToClipBoard(BYVAL content AS STRING) AS LONG
                            ON ERROR GOTO WriteToClipBoardError
                            LOCAL where AS LONG, hData AS LONG, bytes AS LONG
                            content = content + CHR$(0)
                            bytes = LEN(content)
                            IF bytes < 2 THEN EXIT FUNCTION
                            hData = GlobalAlloc(&H2002, bytes)    ' get memory of clipboard
                            where = GlobalLock(hData)             ' lock it
                            POKE$ where, content                  ' paste text into memory
                            GlobalUnlock hData                    ' unlock memory
                            IF ISFALSE OpenClipboard(0) THEN      ' if clipboard isn't available
                              GlobalFree hData                    ' free up memory
                              FUNCTION = 0
                              EXIT FUNCTION
                             END IF
                            EmptyClipboard                          ' empty whatever's in there now
                            SetClipBoardData %CF_TEXT, hData        ' %CF_TEXT = for text
                            CloseClipboard                          ' release clipboard
                            FUNCTION = -1                           ' success
                          EXIT FUNCTION
                            RESUME WriteToClipBoardExit
                          END FUNCTION
                          FUNCTION PBMAIN() AS LONG
                            ON ERROR GOTO PbMainError
                            DIM LineNum AS LONG
                            DIM FILNAME AS STRING
                            DIM Content AS STRING
                            DIM Ecode AS LONG
                            FilName$ = COMMAND$
                            LineNum = 10:FilName$ = COMMAND$
                            IF DIR$(FilName$) = "" THEN EXIT FUNCTION
                            LineNum = 20:OPEN FilName$ FOR BINARY SHARED AS #1
                            LineNum = 30:GET$ #1, LOF(1), content$
                            lineNum = 40: REPLACE CHR$(0) WITH CHR$(32) IN content$ 'replace nulls
                            LineNum = 50:Ecode& = WriteToClipBoard(content$ + CHR$(0))
                            CLOSE #1
                          EXIT FUNCTION
                          MSGBOX "Error writing to clipboard at line "+STR$(LineNum)+ "Error number"+STR$(ERR)
                          RESUME PbMainExit
                          END FUNCTION



                          • #14
                            I am answering from far away from my working place, so I do not have
                            detail information or code ready... but on the issue of grabbing
                            graphics data directly from video memory:
                            Yes, this works very well with Screen 13 and several other video
                            modes, but not with all of them! In Screen 12, for example, you
                            have 4 planes which use the same memory segment, and you have to
                            alter some VGA port values in order to access different planes.
                            In most SVGA modes also, there is memory bank switching needed.
                            So, if you use only Mode 13, you will not have any problem, but
                            other modes are more complicated.
                            I remember having seen a code snipped posted somewhere (was it
                            in the download section?) for grabbing the screen image in Mode 12.


                            Hans Ruegg


                            • #15
                              Hello Lurkers,

                              With some help from Powerbasic Forum friends, I got this to work very well:

                              IF S$="B" THEN 'Make a full screen Bitmap when B pressed
                              FOR idum=1 TO 99 'next free filename+number
                              IF DIR$(BMPName$)="" THEN EXIT FOR
                              NEXT idum

                              WINDOW 'SAVEBMP messes up if Window coordinates changed
                              SAVEBMP BMPName$,16,0,0,639,479 'VGA resolution = 640x480
                              WHILE INKEY$<>"":WEND 'EMPTY KEYBOARD BUFFER
                              locate 12,4
                              PRINT " Bitmap Image ";BMPName$;" has been captured. Press any key to continue. "
                              GOSUB WAITFOR 'waits until key or mouse button pressed
                              GOTO 5445 'back to start so WINDOW command given
                              END IF

                              ' RDS-BMP Utility for screen 12 capture (slightly modified freeware)

                              ' If WINDOW ()-() is used to change coordinates, must return to default by
                              ' using WINDOW without options, then restore options afterwards
                              ' SAVEBMP.BAS - Public domain PowerBASIC sub to capture screen 12
                              ' images to 4/8 bit BMP files (no compression).
                              ' Call using: SAVEBMP BMPFileName$, Colors%, X1%, Y1%, X2%, Y2%
                              ' BMPFileName$ - The .BMP filename. SAVEBMP kills the file if it
                              ' exists!
                              ' Colors% - SAVEBMP saves .BMP files in either 8-bit (256
                              ' colors) or 4-bit (16 colors). Colors% should be
                              ' 16 or 256. Any other value is equal to 256.
                              ' X1%,Y1% - Coordinates for the upper-left corner. The
                              ' values must be valid, as SAVEBMP does not check
                              ' these values for validity.
                              ' X2%,Y2% - Coordinates for the lower-right corner. The
                              ' values must be valid, as SAVEBMP does not check
                              ' these values for validity.
                              ' There are differences in speed and output file's size between 4
                              ' and 8 bit .BMP file processing.
                              ' The SUB makes use of Coridon Henshaw's GetPalette SUB, so if you
                              ' wish to use SAVEBMP in another program, GetPalette will have to go
                              ' with it.

                              ' DPR-I rem'd out since I use default $STRING 32 'See line 72

                              DECLARE SUB SAVEBMP (BMPFileName$, Colors%, X1%, Y1%, X2%, Y2%)
                              DECLARE SUB GETPALETTE (Attr%, Red%, Green%, Blue%)

                              ' SCREEN 12 (already done in my code)

                              TYPE BMPFileHeader
                              FileType as string*2
                              Size as long
                              Reserved1 as integer
                              Reserved2 as integer
                              OffBits as long
                              END TYPE

                              TYPE BMPInfoHeader
                              Size as long
                              ImageWidth as long
                              ImageHeight as long
                              Planes as integer
                              BitCount as integer
                              Compression as long
                              SizeImage as long
                              XPelsPerMeter as long
                              YPelsPerMeter as long
                              ClrUsed as long
                              ClrImportant as long
                              END TYPE

                              SUB GETPALETTE (Attr%, Red%, Green%, Blue%)

                              OUT &H3C7, Attr%
                              Red% = INP(&H3C9)
                              Green% = INP(&H3C9)
                              Blue% = INP(&H3C9)

                              END SUB

                              SUB SAVEBMP (BMPFileName$, Colors%, X1%, Y1%, X2%, Y2%)
                              dim FileHeader as BMPFileHeader
                              dim InfoHeader as BMPInfoHeader

                              if Colors%<>16 then
                              WriteIterations%=5 ' Every 5 lines, Buffer$ reaches 32K, so write
                              ' data to file
                              WriteIterations%=10 ' Each byte holds 2 pixels, so write every 10
                              ' lines
                              end if

                              BMPWidth%=X2%-X1%+1 ' Width and
                              BMPHeight%=Y2%-Y1%+1 ' height of the image

                              'Each raster must be a multiple of 4 bytes, this next line takes
                              'care of 'padded' bytes at the end of rasters of odd-width images-
                              IF BMPWidth% / 4 <> BMPWidth% \ 4 THEN PadBytes% = 4 - (BMPWidth% MOD 4)

                              ' BITMAPFILEHEADER
                              FileHeader.FileType="BM" 'BMP format marker
                              if Colors%=16 then
                              FileHeader.Size=((BMPWidth% + PadBytes%) * BMPHeight%)\2 + 118
                              FileHeader.OffBits=118 ' 16*4+54
                              FileHeader.Size=(BMPWidth% + PadBytes%) * BMPHeight% + 1078
                              FileHeader.OffBits=1078 '256*4+54
                              end if

                              ' BITMAPINFOHEADER
                              if Colors%=16 then
                              end if
                              InfoHeader.Compression=0 ' No compression
                              InfoHeader.SizeImage=(BMPWidth%+PadBytes%)*BMPHeight% ' Image size in bytes
                              InfoHeader.XPelsPerMeter=0 ' Picture dimensions in pixels per meter
                              if Colors%=16 then
                              InfoHeader.ClrUsed=16 ' Colors used in picture
                              InfoHeader.ClrImportant=16 ' Important colors in picture
                              InfoHeader.ClrUsed=256 ' Colors used in picture
                              InfoHeader.ClrImportant=256 ' Important colors in picture
                              end if

                              if dir$(BMPFileName$)<>"" then kill BMPFileName$
                              open BMPFileName$ for binary as #1
                              put #1,,FileHeader
                              put #1,,InfoHeader

                              'Save palette data-
                              Buffer$ = ""
                              for i% = 0 to Colors%-1
                              GETPALETTE i%, Red%, Green%, Blue%
                              'Palette is saved B, G, R with unused byte trailing-
                              Buffer$ = Buffer$ + CHR$(Blue% * 4)
                              Buffer$ = Buffer$ + CHR$(Green% * 4)
                              Buffer$ = Buffer$ + CHR$(Red% * 4)
                              Buffer$ = Buffer$ + CHR$(0)
                              next i%
                              put #1,,Buffer$

                              for i%=(BMPHeight%-1) to 0 step -1 ' scan lines, beginning from bottom

                              if Colors%=16 then
                              for j%=0 to (BMPWidth%-1) step 2 ' scan columns, 2 pixels per byte
                              next j%
                              for j%=0 to (BMPWidth%-1) ' scan columns, 1 pixel per byte
                              next j%
                              end if

                              line (j%,i%)-(0,i%),0 'Wipes screen during scan. Remove if not needed.

                              if PadBytes%>0 then
                              for j%=1 to PadBytes%
                              next j%
                              end if

                              if i%/WriteIterations%=i%\WriteIterations% then
                              put #1,,Buffer$
                              end if
                              next i%
                              close #1

                              END SUB