'=========================================================================== ' Subject: QBASIC ROUTINES Date: 11-06-95 (03:31) ' Author: Douggie Green Code: QBasic ' Origin: comp.lang.basic.misc Packet: DOS.ABC '=========================================================================== '> I need some advise. I'm writing a small program with menus and one of '> selection should display contents of the diskette or HD. '> I know I can do it going to Shell, but I want to have them displayed in '> a small box on the same screen with menus. I'd like to have a feature '> of tagging these files and process them later. 'Um, well, I was going to wait until I'd plugged in a few more snippets, 'but seeing as one of the things this does is read directories and display 'file info, here it is. 'This is a beta posting of the new code snipets faq format. It currently 'runs in screen 0 only as the hi-liting routines only work in this mode. 'This will change (hopefully). 'This file will become the new code faq in a week or so. 'There are no attributations(!) yet, or many comments. I think most of the 'code is fairly self-explanatory. 'Comments, criticisms, suggestions to me at :- 'Douggie@blissinx.demon.co.uk '-----------------------------begin--cut here------------------------------- DEFINT A-Z DECLARE SUB Inverse (x%, y%, w$) 'Invert the word and it's backgound (toggle) DECLARE SUB ShowBitMap (data$) 'Display a 16 colour bitmap DECLARE SUB OpenHelpWindow () 'Does what it says! DECLARE SUB OpenAboutWindow () 'More of the same DECLARE SUB PageDown () 'Show more files if there's more than a DECLARE SUB PageUp () 'screenful - PageUp does the reverse DECLARE SUB OpenDropDown (x%, w%, d%) 'Open and close dropdown menus DECLARE SUB CloseDropDown (x%, w%, d%) DECLARE SUB ShowKeyboardStatus () 'Status of Num lock, Insert, Alt, etc. DECLARE SUB DoCommand (comm$) 'All commands are launched from here. DECLARE SUB FileInfoWindow (filenumber%) DECLARE SUB ShowFileDetails (filename$) DECLARE SUB AlertWindow (message$) DECLARE FUNCTION IsDirectory% (entry$) DECLARE FUNCTION DropDownMenu$ (menu%) DECLARE FUNCTION GetWhichCommand% (menu$) DECLARE FUNCTION BitClear% (Number%, bit%) DECLARE FUNCTION BitSet% (Number%, bit%) DECLARE FUNCTION BitTest% (Number%, bit%) DECLARE FUNCTION QueryWindow% (question$) DECLARE SUB ShowFiles (first%, last%) DECLARE SUB DrawBorder (x%, y%, w%, d%, bordertype%) DECLARE SUB WriteWindow (x%, y%, w%, d%, windw() AS ANY) DECLARE SUB ClearWindow (x%, y%, w%, d%) DECLARE SUB ReadWindow (x%, y%, w%, d%, windw() AS ANY) DECLARE SUB DrawScreen () DECLARE SUB Pause (message$) DECLARE FUNCTION ScanWord$ (x%, y%, att%) DECLARE FUNCTION Rstr$ (x%, LX%) DECLARE SUB Interrupt (IntNum%, Regs AS ANY) 'Interrupt interface DECLARE SUB GetMousePos (xp%, yp%) 'All these routines use interrupts DECLARE FUNCTION ButtonStatus% (button$) DECLARE FUNCTION ButtonRelease% (button$) DECLARE SUB SetMousePos (xmpos%, ympos%) DECLARE FUNCTION InitMouse% () DECLARE SUB ShowMouse () DECLARE SUB HideMouse () DECLARE FUNCTION ReadThisDir% () DECLARE FUNCTION GetBootDrive$ () DECLARE FUNCTION GetFreeSpace% (drive$) DECLARE FUNCTION GetDosVer$ () DECLARE FUNCTION GetDefaultDrive$ () DECLARE FUNCTION GetCurrentDir$ () DECLARE FUNCTION Dir$ (DTA AS ANY, attr%) DECLARE FUNCTION KeyBoardStatus% () 'Last of the interrupt driven routines TYPE DataTransferArea Reserved1 AS STRING * 21 attribute AS STRING * 1 FileTime AS INTEGER filedate AS INTEGER filesize AS LONG filename AS STRING * 13 END TYPE TYPE DirectoryRecord filename AS STRING * 13 filesize AS LONG filedate AS STRING * 12 FileTime AS STRING * 14 fileattb AS STRING * 2 END TYPE DIM SHARED FileDetails(200) AS DirectoryRecord DIM SHARED TempFileDetails AS DirectoryRecord TYPE RegTypeX ax AS INTEGER bx AS INTEGER cx AS INTEGER dx AS INTEGER BP AS INTEGER si AS INTEGER DI AS INTEGER flags AS INTEGER ds AS INTEGER ES AS INTEGER END TYPE DIM SHARED Regs AS RegTypeX TYPE windowdetails character AS STRING * 1 attribute AS STRING * 1 END TYPE CONST Rshift = 0, Lshift = 1, Ctrl = 2, Alt = 3, Scrollock = 4 CONST NumLock = 5, CapsLock = 6, Insert = 7 CONST kpageup = 73, kpagedown = 81 CONST ret = 13, maxfiles = 95, maxsize = 2000 DIM SHARED windw(maxsize) AS windowdetails DIM SHARED page, fst, lst, count AS INTEGER COMMON SHARED selection$ '-------------------------start of main code------------------------- SCREEN 0 CLS mousebuttons = InitMouse '' This will usually return 2, even with 3 button '' mice IF mousebuttons = 0 THEN PRINT "Mouse not present" END END IF DrawScreen CALL SetMousePos(30, 10) '' x,y format, based on 80x25 screen ShowMouse count = ReadThisDir% 'How many files in this directory? ShowFiles 0, maxfiles 'List first page of files DO 'Main control loop ShowKeyboardStatus 'Alt, numlock status etc. IF ButtonRelease("l") THEN 'Deal with the mouse first GetMousePos mxp, myp word$ = ScanWord$(mxp, (myp), attr) IF word$ <> "" AND myp = 0 THEN 'Got a menubar command maincomm = GetWhichCommand%(word$) 'Find which menu to open menuselection$ = DropDownMenu$(maincomm) 'Get the actual command (Help etc) DoCommand menuselection$ 'Do it END IF IF word$ <> "" AND IsDirectory(word$) THEN 'This is a directory (.. etc) CHDIR MID$(word$, 2, LEN(word$) - 2) 'Trim the "<" and ">" selection$ = "": word$ = "" 'Clear these to avoid problems DrawScreen 'Change directory, re-read and count = ReadThisDir% 'update the display ShowFiles 0, maxfiles END IF IF word$ <> "" AND myp < 22 AND myp > 1 THEN 'It's a filename IF attr = 7 THEN 'Not a hi-lited filename, so it's a new IF selection$ <> "" THEN 'selection Inverse selxpos, selypos, selection$ 'un-hilite the old selection selection$ = "" 'and clear it END IF END IF IF selection$ = word$ THEN 'clicked on the old selection selection$ = "" 'so clear it ELSE selection$ = word$ 'new selection, so store co-ords for future selypos = myp selxpos = mxp END IF Inverse mxp, myp, word$ 'hilite the new selection or un-hilite the 'current selection LOCATE 25, 1: PRINT STRING$(26, 32); LOCATE 25, 1: PRINT "Selection : "; selection$; END IF 'End of the filename handler END IF 'End of mouse interface bits a$ = INKEY$ 'Now handle any key presses ctrlkey = 0 'simple toggle IF a$ <> "" THEN IF LEN(a$) = 2 THEN keypress = ASC(RIGHT$(a$, 1)): ctrlkey = 1 IF ctrlkey THEN 'handle control keys (pageup, pagedown etc) IF keypress = kpageup THEN PageUp IF keypress = kpagedown THEN PageDown END IF END IF LOOP UNTIL a$ = " " 'End of main loop END ''hex data for interrupt routines DATA &H55, &H8B, &HEC, &H83, &HEC, &H08, &H56, &H57, &H1E, &H55, &H8B, &H5E DATA &H06, &H8B, &H47, &H10, &H3D, &HFF, &HFF, &H75, &H04, &H1E, &H8F, &H47 DATA &H10, &H8B, &H47, &H12, &H3D, &HFF, &HFF, &H75, &H04, &H1E, &H8F, &H47 DATA &H12, &H8B, &H47, &H08, &H89, &H46, &HF8, &H8B, &H07, &H8B, &H4F, &H04 DATA &H8B, &H57, &H06, &H8B, &H77, &H0A, &H8B, &H7F, &H0C, &HFF, &H77, &H12 DATA &H07, &HFF, &H77, &H02, &H1E, &H8F, &H46, &HFA, &HFF, &H77, &H10, &H1F DATA &H8B, &H6E, &HF8, &H5B, &HCD, &H21, &H55, &H8B, &HEC, &H8B, &H6E, &H02 DATA &H89, &H5E, &HFC, &H8B, &H5E, &H06, &H1E, &H8F, &H46, &HFE, &HFF, &H76 DATA &HFA, &H1F, &H89, &H07, &H8B, &H46, &HFC, &H89, &H47, &H02, &H89, &H4F DATA &H04, &H89, &H57, &H06, &H58, &H89, &H47, &H08, &H89, &H77, &H0A, &H89 DATA &H7F, &H0C, &H9C, &H8F, &H47, &H0E, &H06, &H8F, &H47, &H12, &H8B, &H46 DATA &HFE, &H89, &H47, &H10, &H5A, &H1F, &H5F, &H5E, &H8B, &HE5, &H5D, &HCA DATA &H02, &H00 menubar: DATA 3,"Disk","File","Help" menuitems: DATA 2,7,3,"Format","Dir","Shell" DATA 10,5,5,"List","Edit","Info","View","Exit" DATA 72,6,2,"Help","About" about: DATA 4,"The new BASIC code FAQ","Version 0.1 - 2/NOV/95" DATA "email Douggie@blissinx.demon.co.uk" DATA "or basicfaq@blissinx.demon.co.uk" help: DATA 3,"Use pageup and pagedown if the list" DATA "of files is bigger than the screen" DATA "Press the space bar to exit the program." SUB AlertWindow (m$) ln = LEN(m$) x = 40 - ((ln + 2) / 2) y = 10: w = ln + 4: d = 4 ReadWindow x, y, w, d, windw() ClearWindow x, y, w, d DrawBorder x, y, w, d, 2 'nbeep LOCATE y + 1, x + ((w - ln) / 2) PRINT m$; LOCATE y + 2, x + ((w - 2) / 2) PRINT "Ok"; DO IF ButtonRelease("l") THEN GetMousePos tx, ty IF ty = y + 1 THEN ans$ = ScanWord$(tx, (ty), dum) IF ans$ = "Ok" THEN 'flash tx, ty + 1, ans$ 'writewindow x, y, w, d, windw%() END IF END IF END IF key$ = INKEY$ IF key$ <> "" THEN ky = ASC(key$) LOOP UNTIL ans$ = "Ok" OR ky = ret WriteWindow x, y, w, d, windw() END SUB FUNCTION BitClear% (Number%, bit%) BitClear% = Number% AND (32767 - 2 ^ bit%) END FUNCTION FUNCTION BitSet% (Number%, bit%) BitSet% = Number% OR 2 ^ bit% END FUNCTION FUNCTION BitTest% (Number%, bit%) BitTest% = -SGN(Number% AND 2 ^ bit%) END FUNCTION FUNCTION ButtonRelease (b$) Regs.ax = &H6 IF LEFT$(UCASE$(b$), 1) = "L" THEN Regs.bx = 0 ELSE Regs.bx = 1 Interrupt &H33, Regs ButtonRelease = Regs.bx '' Count of releases, reset to 0 each call. END FUNCTION FUNCTION ButtonStatus (b$) '' b$ should be either "l" or "r". When called once, will return the '' number of times the specified button has been pressed since the last '' call. When used in a loop, as in this demo prog, it works like INKEY$ '' Could be split into ButtonDown() and ButtonCount() Regs.ax = &H5 IF LEFT$(UCASE$(b$), 1) = "L" THEN Regs.bx = 0 ELSE Regs.bx = 1 Interrupt &H33, Regs ButtonStatus = Regs.bx '' Count of presses, reset to 0 each call. IF Regs.ax > 0 THEN ButtonStatus = Regs.ax '' Is a button down? ''if so, return which button END FUNCTION SUB ClearWindow (x, y, w, d) ty = y COLOR 7, 0 FOR k = 1 TO d - 1 LOCATE y + k, x PRINT STRING$(w, 32) NEXT k END SUB SUB CloseDropDown (x, w, d) y = 2 w = w + 2 d = d + 2 WriteWindow x, y, w, d, windw() END SUB FUNCTION Dir$ (dt AS DirectoryRecord, attribute) STATIC DIM dtarec AS DataTransferArea Null$ = CHR$(0) '----- Set up our own DTA so we don't destroy COMMAND$ Regs.ax = &H1A00 'Set DTA function Regs.dx = VARPTR(dtarec) 'DS:DX points to our DTA Regs.ds = -1 'Use current value for DS CALL Interrupt(&H21, Regs) 'Do the interrupt IF ASC(dt.filename) > 32 THEN FileSpecZ$ = dt.filename + Null$ Regs.ax = &H4E00 Regs.cx = attribute Regs.dx = SADD(FileSpecZ$) Regs.ds = -1 ELSE Regs.ax = &H4F00 END IF dtarec.filename = "" CALL Interrupt(&H21, Regs) IF Regs.flags AND 1 THEN Dir$ = "" ELSE Day = dtarec.filedate AND &H1F Month = (dtarec.filedate AND &H1E0) \ 32 Year = (dtarec.filedate AND &HFE00) \ 512 + 1980 dt.filedate = Rstr$(Month, 2) + "-" + Rstr$(Day, 2) + "-" + Rstr$(Year, 4) Seconds = (dtarec.FileTime AND &H1F) * 2 Minutes = (dtarec.FileTime AND &H7E0) \ 32 Hours = (dtarec.FileTime < 0) * (-16) + ((dtarec.FileTime AND &H7FFF) \ 2048) Abbr$ = " am" IF Hours = 12 THEN Abbr$ = " pm" IF Hours = 0 THEN Hours = 12 IF Hours > 12 THEN 'Reset to 12 hour clock Hours = Hours MOD 12 Abbr$ = " pm" END IF dt.FileTime = Rstr$(Hours, 2) + ":" + Rstr$(Minutes, 2) + ":" + Rstr$(Seconds, 2) + Abbr$ dt.filename = dtarec.filename dt.filesize = dtarec.filesize dt.fileattb = STR$(ASC(dtarec.attribute)) 'PRINT dt.fileattb Dir$ = dt.filename END IF END FUNCTION SUB DoCommand (cm$) IF cm$ = "About" THEN OpenAboutWindow EXIT SUB END IF IF cm$ = "Help" THEN OpenHelpWindow EXIT SUB END IF IF cm$ = "Exit" THEN END END IF IF cm$ = "Format" THEN AlertWindow ("Write your own code for this!") EXIT SUB END IF IF cm$ = "Shell" THEN HideMouse CLS PRINT "Type EXIT to resume" SHELL ("") d = InitMouse DrawScreen ShowFiles 0, count ShowMouse EXIT SUB END IF ' handle actions on the selected file IF cm$ <> "" AND selection$ = "" THEN AlertWindow ("No file selected!"): EXIT SUB IF cm$ = "Info" THEN ShowFileDetails (selection$) END IF IF cm$ = "Edit" THEN HideMouse SHELL ("edit " + selection$) d = InitMouse ShowMouse END IF IF cm$ = "View" THEN ShowBitMap selection$ DrawScreen ShowFiles 0, count ShowMouse END IF IF cm$ = "List" THEN HideMouse CLS SHELL ("type " + selection$ + " | more ") Pause "Press a key to continue" DrawScreen ShowFiles 0, count ShowMouse END IF END SUB SUB DrawBorder (x, y, w, d, b) IF b = 1 THEN tlc% = 201: trc% = 187: blc% = 200: brc% = 188: vb% = 186: hb% = 205 ELSEIF b > 1 THEN tlc% = 218: trc% = 191: blc% = 192: brc% = 217: vb% = 179: hb% = 196 END IF IF b = 3 THEN tlc% = 194: trc% = 194 IF b <> 0 THEN LOCATE y, x: PRINT CHR$(tlc%); PRINT STRING$(w - 2, hb%); : PRINT CHR$(trc%) FOR k% = 1 TO d - 2 LOCATE y + k%, x: PRINT CHR$(vb%) LOCATE y + k%, x + w - 1: PRINT CHR$(vb%) NEXT LOCATE y + d - 1, x: PRINT CHR$(blc%); PRINT STRING$(w - 2, hb%); : PRINT CHR$(brc%) END IF END SUB SUB DrawScreen CLS PRINT "Disk File "; PRINT " Help " PRINT STRING$(80, 196); LOCATE 22, 1 PRINT STRING$(80, 196); LOCATE 23, 1: PRINT "Last booted from "; GetBootDrive$; LOCATE 23, 22: PRINT "Default drive "; GetDefaultDrive$; LOCATE 23, 40: PRINT "DOS version "; GetDosVer$; LOCATE 23, 58: PRINT "Free space "; GetFreeSpace%(GetDefaultDrive$); " K"; LOCATE 24, 1: PRINT "Current directory "; GetCurrentDir$; LOCATE 25, 1: PRINT STRING$(26, 32); LOCATE 25, 1: PRINT "Selection : "; selection$; END SUB FUNCTION DropDownMenu$ (menu) RESTORE menuitems FOR k = 0 TO menu - 1 READ xpos, wide, numofitems FOR j = 1 TO numofitems READ item$ NEXT NEXT READ xpos, wide, numofitems CALL OpenDropDown((xpos), (wide), (numofitems)) FOR k = 1 TO numofitems READ item$ LOCATE k + 2, xpos + 1 PRINT item$; NEXT DO GetMousePos x, y x = x + 1 but = ButtonRelease("l") a$ = INKEY$ LOOP UNTIL LEN(a$) OR but IF x > xpos AND x < xpos + wide AND y > 1 AND y < y + numofitems THEN com$ = ScanWord$(x - 1, y, d) 'Get the command as text comm = y - 2 'Get the command as an numeric offset END IF 'LOCATE 25, 1: PRINT com$, comm; CloseDropDown xpos, wide, numofitems DropDownMenu$ = com$ END FUNCTION SUB FileInfoWindow (k) x = 25: y = 10 w = 30: d = 6 ReadWindow x, y, w, d, windw() ClearWindow x, y, w, d DrawBorder x, y, w, d, 2 LOCATE y + 1, x + 2 PRINT "File name ; "; FileDetails(k).filename LOCATE y + 2, x + 2 PRINT "File size ;"; FileDetails(k).filesize; " Bytes" LOCATE y + 3, x + 2 PRINT "File date ; "; FileDetails(k).filedate LOCATE y + 4, x + 14 PRINT "Ok"; DO IF ButtonRelease("l") THEN GetMousePos tx, ty IF ty = y + 3 THEN ans$ = ScanWord$(tx, (ty), dum) IF ans$ = "Ok" THEN 'flash tx, ty + 1, ans$ END IF END IF END IF key$ = INKEY$ IF key$ <> "" THEN ky = ASC(key$) LOOP UNTIL ans$ = "Ok" OR ky = ret WriteWindow x, y, w, d, windw() END SUB SUB flash (x, y, a$) HideMouse LOCATE y, x COLOR 0, 7 PRINT a$; FOR k = 1 TO 20000: NEXT LOCATE y, x COLOR 7, 0 PRINT a$; FOR k = 1 TO 20000: NEXT ShowMouse END SUB FUNCTION GetBootDrive$ 'Returns the drive the system was last re-booted from as a letter plus 'a colon, eg, C: or A: Regs.ax = &H3305 CALL Interrupt(&H21, Regs) GetBootDrive$ = CHR$((Regs.dx MOD 256) + 64) + ":" END FUNCTION FUNCTION GetCurrentDir$ 'Returns the current working directory, this may or may NOT be the directory 'the program was started from DIM buf AS STRING * 80 Null$ = CHR$(0) Regs.ax = &H4700 Regs.dx = 0 'The default drive, 1=A, 2=B, 3=C, 4=D etc 'A null string ("") is returned if the root 'directory is found (ie, C:\ or A:\ ) Regs.ds = -1 'Use current DS Regs.si = VARPTR(buf) CALL Interrupt(&H21, Regs) 'Do the interrupt IF Regs.flags AND 1 THEN PRINT "An error has occured in Function GetCurrentDir$. Error no. is "; PRINT Regs.flags PRINT "This program is terminating." END ELSE Null = INSTR(buf, Null$) GetCurrentDir$ = MID$(buf, 1, Null - 1) END IF END FUNCTION FUNCTION GetDefaultDrive$ Regs.ax = &H1900 CALL Interrupt(&H21, Regs) GetDefaultDrive$ = CHR$((Regs.ax MOD 256) + 65) + ":" END FUNCTION FUNCTION GetDosVer$ 'Returns major and minor version as a string of the format "6.20) Regs.ax = &H3306 CALL Interrupt(&H21, Regs) 'Do the interrupt GetDosVer$ = Rstr$(Regs.bx AND &HFF, 1) + "." + Rstr$(Regs.bx \ &HFF, 2) END FUNCTION FUNCTION GetFreeSpace% (d$) 'd$ can be either upper or lower case 'Returns disk free space rounded to the nearest kilobyte 'If the drive doesn't exist, GetFreeSpace% returns 0 'If there is no disk in the (floppy) drive, the system will lock up, 'requiring a soft reset (Ctrl+Alt+Del) Regs.ax = &H3600 Regs.dx = (ASC(d$) AND &HDF) - 64 'Turn drive letter into (1 - No. of drives) CALL Interrupt(&H21, Regs) GetFreeSpace% = Regs.bx * ((Regs.ax * Regs.cx) / 1024) END FUNCTION SUB GetMousePos (xp, yp) Regs.ax = &H3 Interrupt &H33, Regs xp = Regs.cx / 8 '' These values may need changing depending on yp = Regs.dx / 8 '' your screen mode END SUB FUNCTION GetWhichCommand% (menu$) RESTORE menubar READ numofitems FOR comm = 0 TO numofitems - 1 READ menuitem$ IF menuitem$ = menu$ THEN EXIT FOR END IF NEXT GetWhichCommand% = comm END FUNCTION SUB HideMouse Regs.ax = &H2 Interrupt &H33, Regs END SUB FUNCTION InitMouse Regs.ax = &H0 Interrupt &H33, Regs IF Regs.ax <> 0 THEN InitMouse = Regs.bx ELSE InitMouse = 0 END FUNCTION SUB Interrupt (IntNum, Regs AS RegTypeX) STATIC STATIC filenum, IntOffset, Loaded ' use fixed-length string to fix its position in memory ' and so we don't mess up string pool before routine ' gets its pointers from caller DIM IntCode AS STRING * 200 IF NOT Loaded THEN ' loaded will be 0 first time FOR k = 1 TO 145 READ h% MID$(IntCode, k, 1) = CHR$(h%) NEXT '' determine address of interrupt no. offset in IntCode IntOffset = INSTR(IntCode$, CHR$(&HCD) + CHR$(&H21)) + 1 Loaded = -1 END IF SELECT CASE IntNum CASE &H25, &H26, IS > 255 ' ignore these interrupts CASE ELSE DEF SEG = VARSEG(IntCode) ' poke interrupt number into POKE VARPTR(IntCode) * 1& + IntOffset - 1, IntNum ' code block CALL Absolute(Regs, VARPTR(IntCode$)) ' call routine END SELECT END SUB SUB Inverse (x, y, w$) HideMouse att = SCREEN(y + 1, x, 1) LOCATE y + 1, x IF att = 112 THEN COLOR 7, 0 ELSE COLOR 0, 7 PRINT w$; COLOR 7, 0 ShowMouse END SUB FUNCTION IsDirectory% (entry$) FOR k = 1 TO count IF entry$ = LEFT$(FileDetails(k).filename, LEN(entry$)) AND FileDetails(k).fileattb = " 1" THEN IsDirectory% = k EXIT FOR END IF NEXT END FUNCTION FUNCTION KeyBoardStatus% Regs.ax = &H200 CALL Interrupt(&H16, Regs) KeyBoardStatus% = Regs.ax END FUNCTION SUB nbeep SOUND 2500, 2 END SUB SUB OpenAboutWindow RESTORE about READ numofitems x = 20: y = 10 w = 40: d = numofitems + 2 ReadWindow x, y, w, d, windw() ClearWindow x, y, w, d DrawBorder x, y, w, d, 2 FOR k = 1 TO numofitems LOCATE y + k, x + 2 READ item$ PRINT item$ NEXT DO LOOP UNTIL LEN(INKEY$) OR ButtonRelease("l") WriteWindow x, y, w, d, windw() END SUB SUB OpenDropDown (x, w, d) y = 2 w = w + 2 d = d + 2 ReadWindow x, y, w, d, windw() ClearWindow x, y, w, d DrawBorder x, y, w, d, 3 END SUB SUB OpenHelpWindow RESTORE help READ numofitems x = 20: y = 10 w = 45: d = numofitems + 2 ReadWindow x, y, w, d, windw() ClearWindow x, y, w, d DrawBorder x, y, w, d, 1 FOR k = 1 TO numofitems LOCATE y + k, x + 2 READ item$ PRINT item$ NEXT DO but = ButtonRelease("l") a$ = INKEY$ LOOP UNTIL LEN(a$) OR but WriteWindow x, y, w, d, windw() END SUB SUB PageDown page = page + 1 fst = page * maxfiles IF fst > count + 1 THEN BEEP page = page - 1 EXIT SUB END IF lst = fst + maxfiles 'scrllbarps = scrllbarps + scrllinterval ShowFiles fst, lst END SUB SUB PageUp page = page - 1 IF page < 0 THEN BEEP page = page + 1 EXIT SUB END IF fst = page * maxfiles lst = fst + maxfiles ShowFiles fst, lst END SUB SUB Pause (m$) IF m$ <> "" THEN PRINT m$; WHILE a$ = "" a$ = INKEY$ WEND END SUB FUNCTION QueryWindow (m$) IF LEN(m$) < 10 THEN fill = (10 - LEN(m$)) / 2 fill$ = STRING$(fill, 32) m$ = fill$ + m$ + fill$ END IF x = 40 - ((LEN(m$) + 2) / 2) y = 10: w = LEN(m$) + 2: d = 5 ReadWindow x, y, w, d, windw() ClearWindow x, y, w, d DrawBorder x, y, w, d, 2 LOCATE y + 1, x + 1 PRINT m$ tx = x + ((w - 1) / 2) - 4 LOCATE y + 3, tx PRINT "Yes No" ty = y b = -1 DO IF ButtonRelease("l") THEN GetMousePos tx, ty IF ty = y + 3 THEN ans$ = ScanWord$(tx, (ty), dum) 'flash tx, ty, ans$ b = INSTR("NY", LEFT$(ans$, 1)) - 1 ' querywindow = b END IF IF ty <> y + 3 THEN 'nbeep WriteWindow x, y, w, d, windw() EXIT FUNCTION END IF END IF c$ = "" c$ = INKEY$ IF c$ <> "" THEN c$ = UCASE$(c$) b = INSTR("NY", c$) - 1 END IF LOOP UNTIL ans$ <> "" OR b <> -1 WriteWindow x, y, w, d, windw() QueryWindow = b END FUNCTION FUNCTION ReadThisDir% FOR k = 1 TO count TempFileDetails.filename = "" FileDetails(k).filename = "" NEXT TempFileDetails.filename = "*.*" 'adjust this as appropriate attr = 16 found$ = Dir$(TempFileDetails, attr) 'check for the first file count = 1 DO WHILE LEN(found$) IF TempFileDetails.fileattb = " 1" THEN TempFileDetails.filename = "<" + TempFileDetails.filename MID$(TempFileDetails.filename, INSTR(TempFileDetails.filename, CHR$(0))) = ">" END IF FileDetails(count) = TempFileDetails count = count + 1 TempFileDetails.filename = "" found$ = Dir$(TempFileDetails, attr) '' Notice the null filespec. LOOP ReadThisDir% = count END FUNCTION SUB ReadWindow (x, y, w, d, windw() AS windowdetails) l = 0 ty = y + d tx = x + w HideMouse FOR k = y TO ty FOR j = x TO tx LOCATE k, j windw(l).character = CHR$(SCREEN(k, j)) windw(l).attribute = CHR$(SCREEN(k, j, 1) - 7) l = l + 1 NEXT j NEXT k ShowMouse END SUB FUNCTION Rstr$ (x%, LX%) x$ = STR$(x%) Rstr$ = RIGHT$("00000" + RIGHT$(x$, LEN(x$) - 1), LX%) END FUNCTION FUNCTION ScanWord$ (x, y, att) y = y + 1: x = x + 1 '' need to adjust because the mouse routines return HideMouse c = SCREEN(y, x) ''Get the character under the mouse cursor att = SCREEN(y, x, 1) ''and it's atribute IF c > 39 AND c < 123 THEN ''We're over a word so... LOCATE y, x DO ''Find the start of the word c = SCREEN(y, x) x = x - 1 LOOP UNTIL c < 39 OR c > 123 OR x = 0 IF x > 0 THEN x = x + 2 ''We end up at the x position *before* the word IF x = 0 THEN x = 1 ''SCREEN and LOCATE need this, just in case. DO ''Read the word c = SCREEN(y, x) w$ = w$ + CHR$(c) x = x + 1 LOOP UNTIL c < 39 OR c > 123 OR x = 0 w$ = LEFT$(w$, LEN(w$) - 1) ''We end up past the word, so trim it. x = x - LEN(w$) - 1 END IF ScanWord$ = w$ ShowMouse END FUNCTION SUB SetMousePos (xmpos, ympos) Regs.ax = &H4 Regs.cx = xmpos * 8 '' These values may need changing depending on Regs.dx = ympos * 8 '' your screen mode Interrupt &H33, Regs END SUB ' 2) --------------------------begin SHOWBMP2.BAS--------------------- ''This is at least twice as fast as the previous routine. 'By Kim Christensen 'This routine will read in a Windows Bitmap file and display it. 'Only 16 color Bitmaps are supported. Even with SCREEN 13: I am 'only using that mode to "blow up" the picture a bit. 'Comments? Questions? Suggestions? : uv317@freenet.victoria.bc.ca 'No flames please! :) SUB ShowBitMap (data$) 'INPUT "Filename"; data$ IF LTRIM$(RTRIM$(data$)) = "" THEN END OPEN data$ FOR BINARY AS #1 IF LOF(1) = 0 THEN AlertWindow ("File not found!"): CLOSE : KILL data$: END table$ = INPUT$(54, #1) 'Get the file header (54 bytes) DIM table&(30) 'Create numerical array for header DEF SEG = VARSEG(table&(1)) pointer% = VARPTR(table&(1)) 'Poke the data from string "table$" into numerical array "table&" FOR x% = 0 TO 51 POKE pointer% + x%, ASC(MID$(table$, x% + 3, 1)) NEXT DEF SEG 'Check for valid file type IF MID$(table$, 1, 2) <> "BM" OR table&(4) <> 40 THEN AlertWindow ("Not a valid *.BMP file!"): CLOSE : EXIT SUB END IF IF table&(8) <> 0 THEN AlertWindow ("This program will not diplay RLE encoded files"): CLOSE : EXIT SUB END IF IF ASC(MID$(table$, 29, 1)) <> 4 THEN AlertWindow ("Only 16 color bitmaps are supported!"): CLOSE : EXIT SUB END IF 'Set the video mode for best picture fit IF (table&(5) < 321) AND (table&(6) < 201) THEN SCREEN 13 ELSE SCREEN 12 END IF LOCATE 2, 1 PRINT " Image is "; table&(5); " by "; table&(6) thecolors$ = INPUT$(table&(3) - 54, #1) 'Read in pallette info DEF SEG = VARSEG(pal&) pointer% = VARPTR(pal&) 'Poke the pallette info from the string "thecolors$" 'into pal& and reduce to 6 bits per byte. FOR x% = 0 TO 63 STEP 4 POKE pointer%, (ASC(MID$(thecolors$, x% + 3, 1))) \ 4 POKE pointer% + 1, (ASC(MID$(thecolors$, x% + 2, 1))) \ 4 POKE pointer% + 2, (ASC(MID$(thecolors$, x% + 1, 1))) \ 4 POKE pointer% + 3, 0 PALETTE x% \ 4, pal& NEXT DEF SEG 'Read in Bitmap data and set pixels accordingly y% = table&(6) 'Put number of vertical pixels into y% DO data$ = INPUT$((((table&(5) - 1) OR 7) + 1) \ 2, #1) IF (table&(5) \ 2) < LEN(data$) THEN linelength% = table&(5) \ 2 ELSE linelength% = LEN(data$) END IF FOR x% = 1 TO linelength% pixel% = ASC(MID$(data$, x%, 1)) PSET (x% * 2 + 1, y%), pixel% AND 15 PSET (x% * 2, y%), pixel% \ 16 NEXT y% = y% - 1 LOOP UNTIL EOF(1) OR INKEY$ <> "" Pause "" SCREEN 0 END SUB SUB ShowFileDetails (filename$) 'first check it's in the list we made FOR k = 1 TO count IF filename$ = LEFT$(FileDetails(k).filename, LEN(filename$)) THEN FileInfoWindow (k) EXIT FOR END IF NEXT END SUB SUB ShowFiles (first, last) k = 3: l = first HideMouse DO l = l + 1 y = k MOD 22: x = ((k \ 22)) * 16 IF y < 3 THEN y = 3: k = k + 3 IF x = 0 THEN x = 1 LOCATE y, x: PRINT FileDetails(l).filename; k = k + 1: LOOP UNTIL l = last ShowMouse END SUB SUB ShowKeyboardStatus k% = KeyBoardStatus% LOCATE 25, 40 IF BitTest%(k%, Insert) THEN PRINT "Ins "; ELSE PRINT "Over"; IF BitTest%(k%, Lshift) THEN PRINT "Lshift"; ELSE PRINT " "; IF BitTest%(k%, Rshift) THEN PRINT "Rshift"; ELSE PRINT " "; IF BitTest%(k%, Alt) THEN PRINT "Alt"; ELSE PRINT " "; IF BitTest%(k%, Ctrl) THEN PRINT "Ctrl"; ELSE PRINT " "; IF BitTest%(k%, NumLock) THEN PRINT "Num"; ELSE PRINT " "; IF BitTest%(k%, CapsLock) THEN PRINT "Caps"; ELSE PRINT " "; IF BitTest%(k%, Scrollock) THEN PRINT "Scroll"; ELSE PRINT " "; END SUB SUB ShowMouse Regs.ax = &H1 Interrupt &H33, Regs END SUB SUB WriteWindow (x, y, w, d, windw() AS windowdetails) l = 0 ty = y + d tx = x + w HideMouse FOR k = y TO ty FOR j = x TO tx LOCATE k, j COLOR 7, 0 IF ASC(windw(l).attribute) THEN COLOR 0, 7 PRINT windw(l).character; l = l + 1 NEXT j NEXT k ShowMouse END SUB