home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / bltq13a.zip / XB_SRC01.BAS < prev    next >
BASIC Source File  |  1993-04-22  |  18KB  |  596 lines

  1. DECLARE FUNCTION DoBackup% (dfHandle%, kfHandle%)
  2. DECLARE FUNCTION DoExpandFile% (kfHandle%)
  3. DECLARE FUNCTION DoReindex% (kfHandle%)
  4. DECLARE FUNCTION DoAdd% (kfHandle%)
  5. DECLARE FUNCTION DoAddAll% (kfHandle%)
  6. DECLARE FUNCTION DoClose% (dfHandle%, kfHandle%)
  7. DECLARE FUNCTION DoCreateOpenDataFile% (dfHandle%)
  8. DECLARE FUNCTION DoCreateOpenKeyFile% (dfHandle%, kfHandle%)
  9. DECLARE FUNCTION DoExit% ()
  10. DECLARE FUNCTION DoFirstThings% (dfHandle%, kfHandle%)
  11. DECLARE FUNCTION DoGetEqual% (kfHandle%, match$)
  12. DECLARE FUNCTION DoMemCheck% ()
  13. DECLARE SUB DoPrint (kfHandle%, k$)
  14. DECLARE FUNCTION DoShowFirst% (kfHandle%)
  15. DECLARE FUNCTION DoShowNext% (kfHandle%)
  16. DECLARE FUNCTION GetKeyInfo% (kfHandle%, kfKeyFlags%, kfKeyLen%)
  17. DECLARE FUNCTION IsShareLoaded% ()
  18.  
  19. DEFINT A-Z
  20.  
  21. REM $INCLUDE: 'BULLET.BI'
  22. 'XB_SRC01.BAS 31-May-92 chh
  23. 'code example of a BULLET program that uses many of the BULLET routines--
  24. '--though not really that well designed--an early ad-hoc design test bed
  25.  
  26. TYPE ScoreRecTYPE
  27. tag AS STRING * 1       'MUST HAVE DELETE TAG SPACE DEFINED FOR BULLET USE
  28. codename AS STRING * 6
  29. score AS STRING * 4     'true DBF format has NUMERIC in ASCII, not binary form
  30. END TYPE '11
  31. DIM SHARED gScoreRec AS ScoreRecTYPE  'the only global variable
  32.  
  33. CONST MAXDF = 1         'max data files to be used concurrently (1-250)
  34. CONST MAXKF = 1         'max key files to be used concurrently (1-250)
  35. CONST MAXFD = 2         'max fields to be used concurrently (SUM of all!)
  36.                         '          (this program has only 2 fields total)
  37.                         'these values mainly for DoMemCheck here
  38.  
  39.                         'all variables are local to main and
  40.                         'are passed if needed elsewhere rather
  41.                         'than declaring then SHARED (why not)
  42.                                    'because...
  43. DIM SHARED dfHandle AS INTEGER    'DOS file handle to data file
  44. DIM SHARED kfHandle AS INTEGER    'DOS file handle to key file
  45.  
  46. 'note: if you run this program more than once without first deleting the
  47. 'two files this creates, then the program will end with a error 201 since
  48. 'the key file was created to all unique keys only (easy enough to change)
  49. '--also, the Creating status will indicate error 80 (&H50) "Already exists"
  50.  
  51. CLS
  52. PRINT "XSRC01.BAS"
  53. PRINT "----------Key: CHARACTER, NLS, DUPLICATES ALLOWED"
  54. stat = DoFirstThings(dfHandle, kfHandle)
  55. PRINT "Using DOS handles:"; dfHandle; kfHandle
  56. IF stat = 0 THEN
  57.    INPUT "How may add loops (max=32000 loops, each loop is 14 recs)", a
  58.    ts! = TIMER
  59.    FOR i = 1 TO a
  60.       stat = DoAddAll(dfHandle)
  61.       IF stat THEN EXIT FOR
  62.    NEXT
  63.    te! = TIMER
  64.    PRINT "add rec time"; te! - ts!
  65.    IF stat = 0 THEN
  66.       ts! = TIMER
  67.       stat = DoReindex(kfHandle)
  68.       te! = TIMER
  69.       IF stat = 0 THEN
  70.          stat = stat2
  71.          PRINT "reindex time"; te! - ts!
  72.          match$ = "SHARKY" + CHR$(0) + CHR$(0)
  73.          stat = DoGetEqual(kfHandle, match$)
  74.       END IF
  75.    END IF
  76. END IF
  77. PRINT "status:"; stat;
  78. SELECT CASE stat
  79. CASE 202
  80.    PRINT "Normal End Of File"
  81. CASE 201
  82.    PRINT "Keyfile created for UNIQUE keys and attempt to insert key that already exists"
  83.    PRINT "Either allow duplicate keys (in CreateKXB) or delete key or delete file"
  84. CASE ELSE
  85.    PRINT "Look it up"
  86. END SELECT
  87. END
  88.  
  89. 'data filename, number of fields
  90. '(for each field) name, type, length, decimal count
  91. DataFileInfo:
  92. DATA ".\XSRC01.DBF"
  93. DATA 2
  94. DATA "CODENAME","C",6,0
  95. DATA "SCORE","N",4,0
  96.  
  97. 'key filename, key expression, key flags (see DOCs for flags)
  98. KeyFileInfo:
  99. DATA ".\XSRC01.DEX"
  100. DATA "CODENAME"
  101. DATA 2
  102.  
  103. 'sample data for data file
  104. 'codename,score
  105. SampleData:
  106. DATA "SHARKY",100
  107. DATA "Sharki",47
  108. DATA "BRande",48
  109. DATA "BRANDI",95
  110. DATA "BWANA",66
  111. DATA "SaysSo",87
  112. DATA "SAYSNO",50
  113. DATA "SEXIMA",69
  114. DATA "BERLIN",55
  115. DATA "MUNICH",44
  116. DATA "FURTH",77
  117. DATA "Goanna",61
  118. DATA "Spock1",67
  119. DATA "SPOCK2",99
  120. DATA "",0
  121.  
  122. FUNCTION DoAdd (dfHandle)
  123.  
  124. 'add a new entry into the database, locking all bytes in the key and data
  125. 'files if SHARE.EXE is loaded preventing other processes from accessing
  126. 'the two files while we're making changes to them
  127.  
  128. DIM AP AS AccessPack
  129. DIM AnyKeyBuffer AS STRING * 64
  130.  
  131. ShareLoaded = IsShareLoaded
  132.  
  133. AP.Func = LockXB                    'first lock the key file and data file
  134. AP.Handle = dfHandle
  135. AP.RecPtrOff = VARPTR(gScoreRec)    'point to the data record
  136. AP.RecPtrSeg = VARSEG(gScoreRec)
  137. AP.KeyPtrOff = VARPTR(AnyKeyBuffer) 'point to the key buffer
  138. AP.KeyPtrSeg = VARSEG(AnyKeyBuffer)
  139. AP.NextPtrOff = 0                   'point to the next key file (none)
  140. AP.NextPtrSeg = 0
  141.  
  142. LOCATE , 1
  143. statLock = 0
  144. IF ShareLoaded THEN
  145.    AP.Handle = kfHandle             'want the kfHandle for the xaction lock
  146.    PRINT "Initiating locks";
  147.    stat = BULLET(AP)
  148.    IF stat THEN statLock = AP.stat
  149.    AP.Handle = dfHandle
  150. END IF
  151.  
  152. stat = statLock
  153. IF stat = 0 THEN                    'and now do the add
  154.    'AP.Handle = kfHandle
  155.    'AP.Func = InsertXB                  'both key and the data record
  156.                                         '!not for this example, using ReindexXB
  157.    AP.Func = AddRecordXB            'of just data record
  158.    PRINT " - adding rec: "; gScoreRec.codename;
  159.    stat = BULLET(AP)
  160.  
  161.    'since for InsertXB (and UpdateXB and LockXB) return not the
  162.    'error status but rather the key file position number (since we
  163.    'can Insert/Update/Lock up to 32 key files plus a data file at one
  164.    'time) we must explicity check for the error status in AP.stat
  165.    '(can still check AP.Stat even if not a xaction-based routine!)
  166.    stat = AP.stat
  167.    IF stat = 0 THEN PRINT " recno:"; AP.RecNo;
  168. END IF
  169.  
  170. IF ShareLoaded AND (statLock = 0) THEN
  171.    AP.Func = UnlockXB                  'if lock was successful must unlock
  172.    AP.Handle = kfHandle
  173.    PRINT " - released locks";
  174.    stat = BULLET(AP)
  175.    IF stat THEN stat = AP.stat
  176.    PRINT stat
  177. END IF
  178. DoAdd = stat
  179.  
  180. END FUNCTION
  181.  
  182. FUNCTION DoAddAll (dfHandle)
  183.  
  184. 'read the DATA codename and score and add it to the data file
  185. 'and insert its key to the key file
  186.  
  187. 'done for each of the sample data items in SampleData:
  188.  
  189. 'dfHandle is not needed because it is known to BULLET from the Open()
  190.  
  191. RESTORE SampleData
  192. DO
  193.    READ cname$, score$                  'score$ as string because DBF format
  194.    IF LEN(cname$) = 0 THEN EXIT DO      'specifies all data in DBF files be
  195.                                         'in ASCII format
  196.    gScoreRec.codename = cname$
  197.    RSET gScoreRec.score = score$        'right-justify score in field
  198.    stat = DoAdd(dfHandle)               'insert gScoreRec and its key
  199. LOOP UNTIL stat
  200. DoAddAll = stat
  201.  
  202. END FUNCTION
  203.  
  204. FUNCTION DoBackup (dfHandle, kfHandle)
  205.  
  206. 'backup the current files
  207.  
  208. DIM CP AS CopyPack
  209. DIM BUname AS STRING * 64
  210.  
  211. BUname = ".\XSRC01.D!F" + CHR$(0)
  212. CP.Func = BackupFileXB
  213. CP.Handle = dfHandle
  214. CP.FilenamePtrOff = VARPTR(BUname)
  215. CP.FilenamePtrSeg = VARSEG(BUname)
  216. stat = BULLET(CP)
  217.  
  218. IF stat = 0 THEN
  219.    BUname = ".\XSRC01.D!X" + CHR$(0)
  220.    CP.Func = BackupFileXB
  221.    CP.Handle = kfHandle
  222.    CP.FilenamePtrOff = VARPTR(BUname)
  223.    CP.FilenamePtrSeg = VARSEG(BUname)
  224.    stat = BULLET(CP)
  225. END IF
  226. DoBackup = stat
  227.  
  228. END FUNCTION
  229.  
  230. FUNCTION DoClose (dfHandle, kfHandle)
  231.  
  232. 'close key file first, then data file
  233.  
  234. DIM HP AS HandlePack
  235.  
  236. HP.Func = CloseKXB
  237. HP.Handle = kfHandle
  238. stat = BULLET(HP)
  239.  
  240. HP.Func = CloseDXB
  241. HP.Handle = dfHandle
  242. stat2 = BULLET(HP)
  243. IF stat = 0 THEN stat = stat2
  244. DoClose = stat
  245.  
  246. END FUNCTION
  247.  
  248. FUNCTION DoCreateOpenDataFile (dfHandle)
  249.  
  250. 'Create (if needed) and open data file
  251.  
  252. 'Rtn: dfHandle DOS file handle
  253.  
  254. '--Demonstrates ability to specify data file format at run-time without
  255. 'hard-coding it at compile-time. This info could easily be specified
  256. 'interactively from the user, an external file, etc.
  257.  
  258. 'FieldName MUST BE ZERO-FILLED TO CHARACTER POSITION 11
  259. 'technically, only A-Z and _ are allowed in DBF fieldnames
  260. 'also, all info should be in UPPER-CASE
  261.  
  262. DIM CDP AS CreateDataPack
  263. DIM OP AS OpenPack
  264.  
  265. DIM XBdf AS STRING * 64         'used only for create (must be FIXED-LENGTH)
  266. DIM NoFields AS INTEGER         'used only for create
  267.  
  268. RESTORE DataFileInfo
  269. READ d$                         'filename
  270. XBdf = d$ + CHR$(0)             'MUST ZERO-TERMINATE filename (0T)
  271. READ NoFields                   'number of fields to process
  272.  
  273. 'FieldList() is a temporary TYPEd array, needed only to create the data file
  274. '--can be discarded after use. FieldDescTYPE defined in BULLET.BI.
  275.  
  276. REDIM FieldList(1 TO NoFields) AS FieldDescTYPE
  277.  
  278. FOR i = 1 TO NoFields
  279.    READ FldName$, FldType$, FldLen, FldDC
  280.    FieldList(i).FieldName = FldName$ + STRING$(10, 0)  'must zero-fill name
  281.    FieldList(i).FieldType = FldType$
  282.    FieldList(i).FieldLength = CHR$(FldLen)
  283.    FieldList(i).FieldDC = CHR$(FldDC)
  284. NEXT
  285. CDP.Func = CreateDXB
  286. CDP.FilenamePtrOff = VARPTR(XBdf)           'point to data filename
  287. CDP.FilenamePtrSeg = VARSEG(XBdf)
  288. CDP.NoFields = NoFields
  289. CDP.FieldListPtrOff = VARPTR(FieldList(1))  'point to first field descriptor
  290. CDP.FieldListPtrSeg = VARSEG(FieldList(1))
  291. CDP.FileID = 3                              'standard DBF file ID
  292.  
  293. PRINT "Creating "; RTRIM$(XBdf); " stat:";
  294. stat = BULLET(CDP)
  295. PRINT stat
  296.  
  297. IF stat = 0 OR stat = &H50 THEN             'if created okay OR already exists
  298.    OP.Func = OpenDXB                        'open it
  299.    OP.FilenamePtrOff = VARPTR(XBdf)
  300.    OP.FilenamePtrSeg = VARSEG(XBdf)
  301.    OP.ASmode = &H42                         'DENY NONE (SHARE R/W ACCESS)
  302.    PRINT " Opening "; RTRIM$(XBdf); " stat:";
  303.    stat = BULLET(OP)
  304.    PRINT stat
  305.    dfHandle = OP.Handle                     'DOS file handle for data file
  306. END IF
  307. DoCreateOpenDataFile = stat
  308.  
  309. END FUNCTION
  310.  
  311. FUNCTION DoCreateOpenKeyFile (dfHandle, kfHandle)
  312.  
  313. 'dfHandle is the DOS file handle for the open data file
  314. 'that this key file (to now be created) indexes
  315.  
  316. DIM CKP AS CreateKeyPack
  317. DIM OP AS OpenPack
  318.  
  319. DIM XBkf AS STRING * 64         'key filename (must be FIXED-LENGTH)
  320. DIM XBkx AS STRING * 104        'key expression (must be FIXED-LENGTH)
  321. DIM XBkFlags AS INTEGER         'key type flags (see CreateKXB in CZHELP)
  322.  
  323. RESTORE KeyFileInfo
  324. READ d$                              'filename
  325. XBkf = d$ + CHR$(0)                  'MUST ZERO-TERMINATE filename
  326. READ d$                              'key expression
  327. XBkx = d$ + CHR$(0)                  'MUST ZERO-TERMINATE key expression (0T)
  328. READ XBkFlags
  329. CKP.Func = CreateKXB
  330. CKP.FilenamePtrOff = VARPTR(XBkf)    'filename
  331. CKP.FilenamePtrSeg = VARSEG(XBkf)
  332. CKP.KeyExpPtrOff = VARPTR(XBkx)      'key expression
  333. CKP.KeyExpPtrSeg = VARSEG(XBkx)
  334. CKP.XBlink = dfHandle                'key file indexes this data file
  335. CKP.KeyFlags = XBkFlags
  336. CKP.CountryCode = -1
  337. CKP.CodePageID = -1                  'uses default OS's NLS
  338. CKP.CollatePtrOff = 0                'uses default OS's collate table
  339. CKP.CollatePtrSeg = 0
  340.  
  341. PRINT "Creating "; RTRIM$(XBkf); " stat:";
  342. stat = BULLET(CKP)
  343. PRINT stat
  344.  
  345. IF stat = &H50 THEN stat = 0         'key file already exists, no problem
  346.  
  347. IF stat = 0 THEN                     'open the key file
  348.    OP.Func = OpenKXB
  349.    OP.ASmode = &H42                  'DENY NONE (SHARE R/W ACCESS)
  350.    OP.xbHandle = dfHandle            'key file's link to the data file--
  351.    OP.FilenamePtrOff = VARPTR(XBkf)  '--MUST be handle to open data file
  352.    OP.FilenamePtrSeg = VARSEG(XBkf)
  353.    PRINT " Opening "; RTRIM$(XBkf); " stat:";
  354.    stat = BULLET(OP)
  355.    PRINT stat
  356.    kfHandle = OP.Handle              'DOS handle for this key file
  357. END IF
  358.  
  359. DoCreateOpenKeyFile = stat
  360.  
  361. END FUNCTION
  362.  
  363. FUNCTION DoExit
  364.  
  365. 'shutdown
  366.  
  367. DIM EP AS ExitPack
  368.  
  369. EP.Func = ExitXB
  370. stat = BULLET(EP)
  371. DoExit = stat
  372.  
  373. END FUNCTION
  374.  
  375. FUNCTION DoExpandFile (kfHandle)
  376.  
  377. DIM DFP AS DOSFilePack
  378.  
  379. DFP.Func = ExpandFileDOS
  380. DFP.Handle = kfHandle
  381. DFP.SeekOffset = 512&
  382. stat = BULLET(DFP)
  383. DoExpandFile = stat
  384.  
  385. END FUNCTION
  386.  
  387. FUNCTION DoFirstThings (dfHandle, kfHandle)
  388.  
  389. 'init BULLET, check (and get if needed) memory,
  390. 'check if SHARE.EXE is installed (for record-locking),
  391. 'create the data and key files (if they don't exist), open them
  392.  
  393. DIM IP AS InitPack
  394. DIM EP AS ExitPack
  395.  
  396. stat = DoMemCheck                            'check available OS memory
  397. IF stat = 0 THEN
  398.    IP.Func = InitXB
  399.    IP.JFTmode = 1                            'expand for max 250 open files
  400.    stat = BULLET(IP)
  401.    PRINT "xb_ExitXB @ "; HEX$(IP.ExitPtrSeg); ":"; HEX$(IP.ExitPtrOff)
  402.    EP.Func = AtExitXB
  403.    stat2 = BULLET(EP)
  404.    IF stat = 0 THEN
  405.       stat = DoCreateOpenDataFile(dfHandle)     'create/open the DBF datafile
  406.       IF stat = 0 THEN                          'create/open the key file
  407.          stat = DoCreateOpenKeyFile(dfHandle, kfHandle)
  408.       END IF
  409.    END IF
  410. END IF
  411. DoFirstThings = stat
  412.  
  413. END FUNCTION
  414.  
  415. FUNCTION DoGetEqual (kfHandle, match$)
  416.  
  417. 'get an exact match or position 'key pointer' to where it would have been
  418. 'for GetNext() or GetPrev() to start at a certain point
  419.  
  420. DIM AP AS AccessPack
  421. DIM AnyKeyBuffer AS STRING * 64
  422.  
  423. AP.Func = GetEqualXB
  424. AP.stat = 0
  425. AP.Handle = kfHandle
  426. AnyKeyBuffer = match$
  427. AP.RecPtrOff = VARPTR(gScoreRec)        'gScoreRec is GLOBAL!
  428. AP.RecPtrSeg = VARSEG(gScoreRec)        'because QB doesn't pass generic
  429. AP.KeyPtrOff = VARPTR(AnyKeyBuffer)     'TYPEd variables unless you put the
  430. AP.KeyPtrSeg = VARSEG(AnyKeyBuffer)     'TYPE in the parameter list (which
  431. stat = BULLET(AP)   'makes it hard-coded, not generic)
  432. DoGetEqual = stat
  433.  
  434. END FUNCTION
  435.  
  436. FUNCTION DoMemCheck
  437.  
  438. 'make sure OS has enough memory available to it to satisify BULLET
  439. 'this only ensures that at this point there's enough OS memory available--
  440. '--if you're using another library that makes calls to the OS for memory
  441. 'then that memory may be taken away (not likely to happen but be aware)
  442. '--if debugging in environment make sure you don't restart the program
  443. 'without first completing through to the DoClose, else too many files will
  444. 'eventually occur, possibly with the side effect of an Error 8
  445.  
  446. 'This is done because at startup BASIC by default uses all memory below
  447. 'the 640K mark (but not any UMB memory which BULLET can use). We can tell
  448. 'BASIC to release memory it owns by using SETMEM().
  449.  
  450. 'BULLET allocates memory on an as-needed basis, specifically when a file
  451. 'is actually opened. When a file is closed that memory used by it is released
  452. 'back to the OS (operating system).
  453.  
  454. CONST NEM = 8           'error number returned if not enough memory avail
  455.  
  456.                         'the CONST used below pertain to this example program
  457.                         'only--in yours make any necessay adjustments, or
  458.                         'better still, develop your own memory required
  459.                         'formula based on the one below--
  460.  
  461. CONST RAM4PACK = 40000  'bytes to reserve for PackDXB/ReindexKXB (minimum)
  462. CONST RAM4MORE = 33000  '32K more will be tried/used if available
  463.  
  464. DIM MP AS MemoryPack
  465.  
  466. stat = 0                'this is a simple formula for memory required (MIN)
  467. memreq& = 1& * (1264& * MAXKF) + (144& * MAXDF) + (32& * MAXFD) + RAM4PACK
  468.  
  469. needed& = memreq& + RAM4MORE         'reduce by what's needed+try 32K more
  470. MP.Func = MemoryXB
  471. stat = BULLET(MP)
  472. IF MP.Memory < needed& THEN
  473.     QBheap& = SETMEM(-needed&)       'ask for what we need
  474.     stat = BULLET(MP)
  475.     IF MP.Memory < memreq& THEN stat = NEM   'settle for min request
  476. END IF
  477.  
  478. PRINT "Total QB heap memory available:"; SETMEM(0)
  479. PRINT "OS memory available ( < 640K) :"; MP.Memory; " (not including UMBs)"
  480. DoMemCheck = stat
  481.  
  482. END FUNCTION
  483.  
  484. SUB DoPrint (kfHandle, k$)
  485.  
  486. 'print the key (k$) and the data record (gScoreRec)
  487.  
  488. 'key is passed as a FIXED-LENGTH but is a VAR-LEN string in the parm list
  489. 'this because that what QB 4.x needs
  490.  
  491. stat = GetKeyInfo(kfHandle, kfKeyFlags, kfKeyLen)
  492. IF stat = 0 THEN
  493.    IF (kfKeyFlags AND 2) THEN           'character key
  494.       IF (kfKeyFlags AND 1) = 0 THEN
  495.          kfKeyLen = kfKeyLen - 2        'remove enumerator if non-unique
  496.          IF kfKeyLen < 1 THEN STOP
  497.       END IF
  498.       PRINT "key: "; LEFT$(k$, kfKeyLen); "  rec: "; gScoreRec.codename; gScoreRec.score
  499.  
  500.    ELSEIF (kfKeyFlags AND 16) THEN      'integer key
  501.  
  502.       PRINT "key: "; CVI(k$), "  rec: "; gScoreRec.codename; gScoreRec.score
  503.  
  504.    END IF
  505. END IF
  506. END SUB
  507.  
  508. FUNCTION DoReindex (kfHandle)
  509.  
  510. 'backup and reindex the key file
  511.  
  512. DIM AP AS AccessPack
  513.  
  514. AP.Func = ReindexXB
  515. AP.Handle = kfHandle
  516. stat = BULLET(AP)
  517. IF stat THEN stat = AP.stat
  518. DoReindex = stat
  519.  
  520. END FUNCTION
  521.  
  522. FUNCTION DoShowFirst (kfHandle)
  523.  
  524. 'get the first key and load its data record into ScoreRec
  525. 'print it to the screen
  526.  
  527. DIM AP AS AccessPack
  528. DIM AnyKeyBuffer AS STRING * 64
  529.  
  530. AP.Func = GetFirstXB                    'yes,this code is exactly the same
  531. AP.stat = 0                             'as DoShowNext() except for AP.Func
  532. AP.Handle = kfHandle
  533. AnyKeyBuffer = ""
  534. AP.RecPtrOff = VARPTR(gScoreRec)        'see DoGetEqual()
  535. AP.RecPtrSeg = VARSEG(gScoreRec)
  536. AP.KeyPtrOff = VARPTR(AnyKeyBuffer)
  537. AP.KeyPtrSeg = VARSEG(AnyKeyBuffer)
  538. stat = BULLET(AP)
  539. k$ = AnyKeyBuffer
  540. IF stat = 0 THEN DoPrint kfHandle, k$
  541. DoShowFirst = stat
  542.                                         
  543. END FUNCTION
  544.  
  545. FUNCTION DoShowNext (kfHandle)
  546.  
  547. 'get the next key and load its data record into ScoreRec
  548. 'print it to the screen
  549.  
  550. DIM AP AS AccessPack
  551. DIM AnyKeyBuffer AS STRING * 64
  552.  
  553. AP.Func = GetNextXB
  554. AP.stat = 0
  555. AP.Handle = kfHandle
  556. AnyKeyBuffer = ""
  557. AP.RecPtrOff = VARPTR(gScoreRec)        'see DoGetEqual()
  558. AP.RecPtrSeg = VARSEG(gScoreRec)
  559. AP.KeyPtrOff = VARPTR(AnyKeyBuffer)
  560. AP.KeyPtrSeg = VARSEG(AnyKeyBuffer)
  561. stat = BULLET(AP)
  562. k$ = AnyKeyBuffer
  563. IF stat = 0 THEN DoPrint kfHandle, k$
  564. DoShowNext = stat
  565.  
  566. END FUNCTION
  567.  
  568. FUNCTION GetKeyInfo (kfHandle, kfKeyFlags, kfKeyLen)
  569.  
  570. 'a little routine to get some formatting info used for printing, etc.
  571.  
  572. DIM SKP AS StatKeyPack
  573.  
  574. SKP.Func = StatKXB
  575. SKP.Handle = kfHandle
  576. stat = BULLET(SKP)
  577. IF stat = 0 THEN
  578.    kfKeyLen = SKP.KeyLen
  579.    kfKeyFlags = SKP.KeyFlags
  580. END IF
  581. GetKeyInfo = stat
  582.  
  583. END FUNCTION
  584.  
  585. FUNCTION IsShareLoaded
  586.  
  587. DIM RP AS RemotePack
  588.  
  589. RP.Func = DriveRemoteXB
  590. RP.Handle = 0                           'actually drive (0=default drive)
  591. stat = BULLET(RP)
  592. IsShareLoaded = RP.IsShare              '-1 if loaded, else 0
  593.  
  594. END FUNCTION
  595.  
  596.