home *** CD-ROM | disk | FTP | other *** search
/ Programming Tool Box / SIMS_2.iso / vb_tools / v_xbase / readme.txt next >
Text File  |  1993-08-11  |  71KB  |  1,885 lines

  1. vxBase 3.07  August 11, 1993
  2. ----------------------------
  3. This is a new major release of vxBase numbered 3.0X. It contains a new set of
  4. functions designed to store, manage, and retrieve bitmaps. It also contains
  5. a set of functions that will create and maintain permanent subindexes - plus
  6. MORE. In all, 20 new functions have been added.
  7.  
  8. Changes to version vxBase 2.xx are documented after the new function
  9. writeups.
  10.  
  11. NOTE: Release 3.02 adds function vxLockRetry which allows much greater
  12.       flexibility in locking protocol and error reporting. See below.
  13.  
  14.       Release 3.03 increases max filter string length to 1024 from 512
  15.       and also now respects filters in child files in vxSetRelation
  16.       chains.
  17.  
  18.       Release 3.04 corrects vxPack problem (640/1602 error) when every
  19.       record in the 64k read buffer was deleted.
  20.  
  21.       Release 3.05 adds function vxPicturePrint and the following
  22.       elements to the xBase expression parsing engine:
  23.         function ALLTRIM()  trims right and left
  24.         functiom EMPTY()    true if string is all spaces, blank date, 
  25.                             or 0 numeric value or .F. logical
  26.         operator !          equivalent to .NOT.
  27.         operator ==         exactly equal
  28.         #                   not equal (equivalent to <>)
  29.         !=                  not equal (equivalent to <>) 
  30.  
  31.       Release 3.06 adds:
  32.         (1) sub function vxSetGauge allows the programmer
  33.             to use his own gauge controls in vxReindex, vxPack, etc.
  34.         (2) new vxCtlBrowseMsg messages VXB_GO, VXB_SKIP (see below).
  35.         (3) quasi-xBase function TIMEODAY(). TIMEODAY(val) converts a number
  36.             (either literal or contained in a numeric field) representing
  37.             minutes into a string representing the time of day
  38.             (e.g., TIMEODAY(510) = "08:30 am".
  39.         (4) "Exit" item aded to vxMemoEdit window.
  40.         (5) minor positioning and scroll problems corrected in vxCtlBrowse.
  41.         (6) xBase expressions that do not have their elements separated by
  42.             spaces now parse properly (e.g., (Y_N1.and.Y_N2) formerly 
  43.             returned an error unless ".and." was separated from the field
  44.             names by spaces).
  45.  
  46.       Release 3.07 Bug Fixes:
  47.          (1) memo overwrite caused by 3.02 corrected.
  48.          (2) vxNumRecsSub corrected
  49.          (3) vxNtxRecNo positioning after call corrected     
  50.          (4) index corruption when appending key to subindex corrected
  51.  
  52.  
  53. BITMAPS
  54. -------
  55. The bitmaps are stored in standard xBase memo files. Fields in the dbf which
  56. contain block references to the bitmaps are standard type "M" fields. An
  57. attempt to display the bitmap using third party xBase software (e.g., Clipper
  58. or even the current release of DataWorks) will show "BIT*MAP". If these
  59. memos are replaced with text, the bitmaps will be lost.
  60.  
  61. An updated vxbtest project is included in the zip. To show off the bitmap
  62. functions, run it and select "Link" and then "Show Pictures" from the
  63. main menu. The code that shows the bitmaps is in VYFORM2. If you are running
  64. the sample on a low resolution monitor (i.e., 640x480), maximize 
  65. the form. You should also make the vxCtlBrowse box a little wider and
  66. deeper. 
  67.  
  68. Collecting Bitmaps
  69. ------------------
  70. Images stored in a vxBase memo file are most easily transferred via
  71. a bitmap file (files with .BMP extensions).
  72.  
  73. vxBase takes advantage of the rich body of functions included in Visual
  74. Basic to handle bitmap files. Bitmaps are the Windows norm; all paint
  75. programs, viewers, etc. can handle bitmaps - and most programs that
  76. deal with pictures can convert foreign formats (e.g., GIF) to BMPs.
  77. As a last resort, cut a picture into the clipboard and paste it into a 
  78. Windows PAINT window. It can then be stored as a .BMP file. 
  79.  
  80. Once an image is stored in a BMP file it can be transferred to the 
  81. memo file with the vxPictureImport function. To retrieve the bitmap,
  82. vxBase uses the standard Windows Clipboard. It puts the bitmap out to
  83. the clipboard as a DIB (device independent bitmap). The Visual Basic
  84. Clipboard.GetData(8) function then is used to retrieve the image
  85. from the clipboard and display it in a VB Picture Box. The box
  86. can have the AUTORESIZE property set to TRUE as in the sample
  87. application if the images are all different sizes
  88.  
  89. C programmers can store ANY KIND of BLOB (binary large object) in a memo 
  90. file with vxBlobWrite and retrieve the BLOBs with vxBlobRead. Contact the
  91. author for more information on these functions.
  92.  
  93.  
  94. SUBINDEXES
  95. ----------
  96. A subindex is an index that represents a defined subset of records in the
  97. main dbf file. The indexing expression is in no way related to the
  98. conditional expression that determines whether or not the record will be 
  99. represented in the index. In other words, the condition that determines
  100. the presence or absence of a key does not depend upon the value of the
  101. key. For example, a subindex may be created using the expression
  102. "upper(custname)" as the key. The conditional expression could be
  103. "(left(vxcountry,6)="CANADA") .or. (left(vxcountry,6)="U.S.A.". This
  104. would produce an index that represented customers in North America only.
  105. An open subindex in an index list attached to a database is maintained
  106. just as like other index. When a record is added, an index key for the
  107. record is only added if the conditional expression evaluates as TRUE.
  108. If a record is updated, and the update data invalidates the record
  109. for inclusion in the subindex, the key is deleted.
  110.  
  111. If you regularly filter data based upon a condition such as the one
  112. above, a permanent subindex makes data retrieval MUCH faster. If the
  113. file is large, and you need to set a temporary filter that may result
  114. in very long record retrieval times, it is probably faster to create
  115. a temporary subindex instead. A subindex makes it APPEAR that the database
  116. contains only records that satisfy the conditional logical expression.
  117.  
  118.  
  119. COMPATIBILITY ISSUES
  120. --------------------
  121. With release 3.0X, vxBase breaks away from strict xBase standards. Bitmaps
  122. of course may only be retrieved and displayed using vxBase functions.
  123. The header block of a subindex also differs from a standard Clipper NTX
  124. index header block. New elements have been added that define whether or
  125. not the index is a subindex and an area is used to hold the conditional
  126. expression as well. 
  127.  
  128. Release 5.2 of CA-Clipper changes the index header as well and also changes
  129. the index locking scheme. vxBase NTX indexes ARE NOT COMPATIBLE with Clipper
  130. 5.2 indexes. Indexes created and/or maintained with any version of Clipper
  131. will NOT properly maintain a vxBase subindex.
  132.  
  133. Bitmaps and subindexes are specialty items requested by a great many vxBase
  134. users. If compatibility is an issue with your application, it would be best
  135. not to use these functions (although bitmaps may be safely ignored; if the
  136. memo text returns "BIT*MAP" then it may be ignored in a Clipper application).
  137.  
  138.  
  139. vxCtlBrowseMsg
  140. --------------
  141. A new message type has been created to extract the current contents of the
  142. user entered quick key value. Define the message in your global module as
  143.  
  144. Global Const VXB_QUICKDISPLAY = 12
  145.  
  146. A quick key entry will normally result in a the record pointer being
  147. moved so the KeyCode middle button down event generated by vxCtlBrowse
  148. whenever a new record is highlighted may be used to conveniently ask 
  149. for the current quick value. The new message may be used to display
  150. the current quick value in a text box as follows:
  151.  
  152. Sub BrowseBox_KeyDown (KeyCode As Integer, Shift As Integer)
  153. '   Debug.Print KeyCode
  154.    If KeyCode = 4 Then
  155.       QWinLong& = vxCtlHwnd(QuickBox) 
  156.       ' Note: vxCtlHwnd normally returns an integer but you
  157.       ' must explicitly cast its value as a long integer
  158.       ' in order to fulfill the vxCtlBrowseMsg parameter
  159.       ' requirements 
  160.       k& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_QUICKDISPLAY, ByVal QWinLong&)
  161.    End If
  162. End Sub
  163.  
  164. Note: A VB label MAY NOT BE USED to display the quick value because a
  165. label is a "graphical object" and therefore does not have a window 
  166. handle.
  167.  
  168. New array positioning messages:
  169.  
  170. Global Const VXB_GO = 13
  171.  
  172. Positions the highlight to a specific record contained in the current browse
  173. display. This is especially useful if you are updating a record on a detail
  174. form and, after you are done, you wish to refresh the browse table with the
  175. new information and then position the highlight to the record that was just 
  176. updated (VXB_REFRESH always positions the highlight to the top record in the
  177. browse). Param is passed BYVAL as a dbf record number to the browse. You must
  178. ensure that the record number passed is indeed pointing to a record on the
  179. current browse display. The return value may be ignored. 
  180.  
  181. Example:
  182. Sub ButtonSave_Click ()
  183.    SaveRecNo& = CurrentRec
  184.    TopRec& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_GETTOPREC, 0)
  185.    j% = vxSelectDbf(vxClientDbf)
  186.    j% = vxGo(CurrentRec)
  187.    j% = vxLockRecord()
  188.    Call vxReplString("vxnamekey", (BoxNAMEKEY.Text))
  189.    Call vxReplString("vxcompany", (BoxCOMPANY.Text))
  190.    j% = vxWrite()
  191.    j% = vxWriteHdr()
  192.    j% = vxUnlock()
  193.    k& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_REFRESH, ByVal TopRec&)
  194.    k& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_GO, ByVal SaveRecNo&)
  195. End Sub
  196.  
  197. Global Const VXB_SKIP = 14
  198. Moves the highlight up or down in the browse table (if param is passed as a negative
  199. number the movement is UP; 0 or a positive number moves DOWN). If the highlight is
  200. positioned at the top or bottom record in the display, the browse will scroll. This
  201. is useful where you have a browse table on one side of the screen and detail info
  202. about the highlighted record on the other side of the screen or even on a different
  203. form.  If the detail side has a Previous or Next button on it, you can synchronize the
  204. highlight on the browse table to the detail record data. The return value may be ignored.
  205.  
  206. Example:
  207. Sub ButtonNext_Click ()
  208.    If RecChange Then
  209.       j% = MsgBox("Record changed. Save?", 52)
  210.       If j% = 6 Then
  211.          ButtonSave_Click
  212.       End If
  213.    End If
  214.  
  215.    CurrentRec = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_GETCURRENTREC, 0)
  216.    j% = vxGo(CurrentRec)
  217.  
  218.    ' skip forward one record
  219.    ' -----------------------
  220.    j% = vxSelectDbf(vxClientDbf)
  221.    j% = vxSkip(1)
  222.    
  223.    ' test for end of file
  224.    ' --------------------
  225.    If vxEof() Then
  226.       Beep
  227.       VXFORM1.StatBar.Text = "End of File!"
  228.       j% = vxGo(CurrentRec)
  229.    Else
  230.       VXFORM1.StatBar.Text = "Skipped to record " + LTrim$(Str$(vxRecNo()))
  231.       CurrentRec = vxRecNo()
  232.       CurrentRec = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_SKIP, ByVal 1&)
  233.       ButtonEdit_Click
  234.    End If
  235. End Sub
  236.  
  237.  
  238. NEW FUNCTIONS
  239. -------------
  240.  
  241. vxBlobRead
  242. ----------
  243. Declaration:
  244. HANDLE FAR PASCAL  vxBlobRead (memofieldname)
  245. char*  memofieldname;          /* name of memo field holding blob */ 
  246.  
  247. Purpose:
  248.    Read a binary large object (blob) from a memo file that was stored with
  249. vxBlobWrite.
  250.  
  251. Parameters:
  252.    memofieldname is either a string variable or a literal string that
  253. contains a valid memo field name from the currently selected database.
  254. MemoFieldName may be qualified with a valid alias name that points to
  255. any open database.
  256.  
  257. Returns:
  258.    A HANDLE to global memory allocated by vxBase. The memory contains
  259. the blob. It is the programmer's responsibility to release the memory
  260. with GlobalFree when he is done with it.
  261.  
  262. Usage:
  263.    Any binary object may be stored in a memo field with vxBlobWrite and
  264. a HANDLE to that object may be extracted with vxBlobRead. The vxPicture
  265. functions are limited to standard BMPs and variants thereof. 
  266.  
  267. Example:
  268.  
  269. /* ********************************************* */
  270. /* DrawBlob uses a GIF library to place an       */
  271. /* image into the window passed to the function  */
  272. /* The blob is retrieved from the memo fieldname */
  273. /* stored in the current record                  */
  274. /* ********************************************* */
  275. BOOL DrawBlob(HWND hwnd, char *fieldname)
  276. {
  277.    HANDLE     hPicBuffer;      // mem handle to blob
  278.    LPSTR      lpPicBuffer;     // string addr of blob
  279.  
  280.    // get the handle to the blob
  281.    // if NULL, return FALSE
  282.    // ---------------------------
  283.    hPicBuffer = vxBlobRead(fieldname);
  284.    if (!hPicBuffer)
  285.       return(FALSE);
  286.    
  287.    // convert the handle to a string address
  288.    // --------------------------------------
  289.    lpPicBuffer = GlobalLock(hPicBuffer);
  290.  
  291.    // Draw the image
  292.    // --------------
  293.    if (!GifConverter(hwnd, lpPicBuffer))
  294.       {
  295.       GlobalUnlock(hPicBuffer);
  296.       GlobalFree(hPicBuffer);
  297.       return(FALSE);
  298.       }
  299.  
  300.    // release the memory
  301.    // ------------------
  302.    GlobalUnlock(hPicBuffer);
  303.    GlobalFree(hPicBuffer);
  304.    return(TRUE);
  305. }
  306.  
  307. See Also:
  308.    vxBlobWrite, vxIsPicture, vxPictureImport, vxPictureRead, vxMemoClear
  309.  
  310.  
  311. vxBlobWrite
  312. -----------
  313. Declaration:
  314. int FAR PASCAL  vxBlobWrite (hGlobal, memofieldname)
  315. HANDLE hGlobal;           // global handle to mem storing blob        
  316. char*  memofieldname;     // name of memo field to put it in
  317.  
  318. Purpose:
  319.    Write a binary large object (blob) into a memo file.
  320.  
  321. Parameters:
  322.    hGlobal is a handle to a global memory object that stores a
  323. binary large object.
  324.  
  325.    MemoFieldName is either a string variable or a literal string that
  326. contains a valid memo field name from the currently selected database.
  327. MemoFieldName may be qualified with a valid alias name that points to
  328. any open database.
  329.  
  330. Returns:
  331.    TRUE if the operation was successful and FALSE if not.
  332.  
  333. Usage:
  334.    Any binary object may be stored in a memo field with vxBlobWrite and
  335. a HANDLE to that object may be extracted with vxBlobRead. The vxPicture
  336. functions are limited to standard BMPs and variants thereof. 
  337.    vxBase does not free the global memory after writing the blob. That
  338. is the programmer's responsibility.
  339.  
  340. Example:
  341.  
  342. /* ********************************************** */
  343. /* GetBlob stores a GIF image into a memo field   */
  344. /* The blob is retrieved from the filename passed */
  345. /* to this function                               */
  346. /* ********************************************** */
  347. BOOL GetBlob(char *filename, char *fieldname)
  348. {
  349.  
  350.    int        hFile;           // dos file handle
  351.    DWORD      dwLength;        // import file length
  352.    HANDLE     hPicBuffer;      // mem handle to blob
  353.    LPSTR      lpPicBuffer;     // string addr of blob
  354.  
  355.    //  verify existence of import file
  356.    // --------------------------------
  357.    hFile = myFileOpen(filename, 0);
  358.    if (hFile < 0)      // if error, return FALSE
  359.       return(FALSE);
  360.       
  361.  
  362.    // if zero length, set error
  363.    // -------------------------
  364.    dwLength = myFileLength(hFile);
  365.    if (!dwLength)
  366.       return(FALSE);
  367.  
  368.    // if unable to allocate memory, set error
  369.    // ---------------------------------------
  370.    if (NULL == (hPicBuffer = GlobalAlloc(GHND, (DWORD)dwLength)))
  371.       {
  372.       _lclose(hFile);
  373.       return(FALSE);
  374.       }
  375.  
  376.    // read image
  377.    // ----------
  378.    lpPicBuffer = GlobalLock(hPicBuffer);
  379.    _hread(hFile, lpPicBuffer, (DWORD) dwLength); // huge read
  380.    _lclose(hFile);
  381.  
  382.    // write image to memo file
  383.    // ------------------------
  384.    GlobalUnlock(hPicBuffer);
  385.    if (!vxBlobWrite(hPicBuffer, fieldname))
  386.       {
  387.       GlobalFree(hPicBuffer);
  388.       return(FALSE);
  389.       }
  390.  
  391.    GlobalFree(hPicBuffer);
  392.    return(TRUE);
  393. }
  394.  
  395. See Also:
  396.    vxBlobRead, vxIsPicture, vxPictureImport, vxPictureRead, vxMemoClear
  397.  
  398.  
  399. vxCreateSubNtx
  400. --------------
  401. Declaration:
  402.    Declare Function vxCreateSubNtx Lib "vxbase.dll" (ByVal NewNtxName
  403. As String, ByVal NtxExpr As String, ByVal ForCond As String) As Integer
  404.  
  405. Purpose:
  406.    Create a permanent subindex that represents a defined subset of
  407. records in the main dbf file. Only records that pass the test of
  408. the defined conditional logical expression are included in the index.
  409.  
  410. Parameters:
  411.    NewNtxName is the name of the new index file that is created. The
  412. parameter may be a literal string or a string variable. It may include
  413. a complete path name. If an extension is not specified, vxBase defaults
  414. it to ".ntx". An existing file with the same name is overwritten. File
  415. names must begin with a letter. The file name length is limited by DOS
  416. to 8 characters.
  417.  
  418.    NtxExpr is a valid xBase expression (which may be as simple as a 
  419. field name) that is passed as either a literal string or as a string
  420. variable. Maximum length of the expression is 255 characters.
  421.  
  422.    ForCond is a valid xBase expression that evaluates as a logical
  423. TRUE or FALSE. The index built by vxCreateSubNtx is composed of
  424. keys built from records that satisfy the ForCond expression. The ForCond
  425. expression may be passed as either a literal string or as a string
  426. variable. Maximum length of the expression is 255 characters.
  427.  
  428. Usage:
  429.    A subindex is an index that represents a defined subset of records in the
  430. main dbf file. The indexing expression is in no way related to the
  431. conditional expression that determines whether or not the record will be 
  432. represented in the index. In other words, the condition that determines
  433. the presence or absence of a key does not depend upon the value of the
  434. key. For example, a subindex may be created using the expression
  435. "upper(custname)" as the key. The conditional expression could be
  436. "(left(vxcountry,6)="CANADA") .or. (left(vxcountry,6)="U.S.A.". This
  437. would produce an index that represented customers in North America only.
  438. An open subindex in an index list attached to a database is maintained
  439. just as like other index. When a record is added, an index key for the
  440. record is only added if the conditional expression evaluates as TRUE.
  441. If a record is updated, and the update data invalidates the record
  442. for inclusion in the subindex, the key is deleted.
  443.  
  444.    If you regularly filter data based upon a condition such as the one
  445. above, a permanent subindex makes data retrieval MUCH faster. If the
  446. file is large, and you need to set a temporary filter that may result
  447. in very long record retrieval times, it is probably faster to create
  448. a temporary subindex instead. A subindex makes it APPEAR that the database
  449. contains only records that satisfy the conditional logical expression.
  450.  
  451.  
  452. Warning:
  453.    If you are editing a file that is being controlled by a subindex (i.e.,
  454. the index currently selected), field changes or additions that result in
  455. the for condition returning FALSE will leave the record pointer in an
  456. undefined state after the record is saved. If the record is an update,
  457. the key will be removed from the index. If the record is an addition,
  458. the key will not be added to the index. IT IS YOUR RESPONSIBILTY to
  459. position the record pointer to a valid record if this should occur.
  460.    There are a number of ways this can be accomplished. If you know
  461. the condition, you can test if the new data will qualify the record
  462. for inclusion in the index. Or you may simply seek for the record again
  463. after writing. If it does not exist, you can position the record
  464. pointer to someplace you have prepared to go to before you began the
  465. update routine. This is the strategy used below:
  466.  
  467. Example (Updating a subindexed file safely):
  468. --------------------------------------------
  469.  
  470. ' Validate data when save button is pressed
  471. ' -----------------------------------------
  472. Sub CustSave_Click ()
  473.    ' verify something in the field
  474.    ' -----------------------------
  475.    j% = vxSelectDbf(vxClientDbf)
  476.    SeekKey$ = CustCode.Text
  477.    If EmptyString(SeekKey$) Then
  478.       MsgBox "vxSer Field cannot be empty"
  479.       Exit Sub
  480.    End If
  481.  
  482.    ' reread the record
  483.    ' -----------------
  484.    j% = vxSeek(SeekKey$)
  485.    ThisRec& = vxRecNo()
  486.  
  487.    ' now get previous record in case
  488.    ' in a subindex situation the changes
  489.    ' the user makes removes this record
  490.    ' from the index. 
  491.    ' The subindex condition here is
  492.    ' vxCountry = 'CANADA' .or. vxCountry = 'U.S.A.'
  493.    ' If the user has changed the country to 
  494.    ' something else, this record will disappear
  495.    ' from the index when it is written so we
  496.    ' must plan on what to do of this happens.
  497.    ' ----------------------------------------------
  498.    j% = vxSkip(-1)
  499.    If vxBof() Then
  500.       j% = vxTop()
  501.    End If
  502.    PrevRec& = vxRecNo()
  503.  
  504.    ' put record pointer back to update
  505.    ' ---------------------------------
  506.    j% = vxGo(ThisRec&)
  507.  
  508.    ' Data passed. Put it away
  509.    ' ------------------------
  510.    j% = vxLockRecord()
  511.    Call vxReplString("vxcompany", (CustCompany.Text))
  512.    Call vxReplString("vxname", (CustName.Text))
  513.    Call vxReplString("vxaddress1", (CustAddress.Text))
  514.    Call vxReplString("vxaddress2", (CustAddress2.Text))
  515.    Call vxReplString("vxcity", (CustCity.Text))
  516.    Call vxReplString("vxstate", (CustState.Text))
  517.    Call vxReplString("vxcountry", (CustCountry.Text))
  518.    Call vxReplString("vxzip", (CustZip.Text))
  519.    Call vxReplString("vxphone", (CustPhBus.Text))
  520.    Call vxReplString("vxfax", (CustFax.Text))
  521.    j% = vxWrite()
  522.    j% = vxWriteHdr()
  523.    j% = vxUnlock()
  524.  
  525.    ' Update status box
  526.    ' -----------------
  527.    VXFORM1.StatBar.Text = "Record " + LTrim$(Str$(ThisRec&)) + " saved"
  528.  
  529.    ' Now see if the record still exists in this index.
  530.    ' If it doesnt exist, the country has been changed
  531.    ' so we will go to the Previous record we saved 
  532.    ' above and load the form data with that. Otherwise,
  533.    ' this record data will remain on the form.
  534.    ' -------------------------------------------------
  535.    If Not vxSeek(SeekKey$) Then
  536.       j% = vxGo(PrevRec&)
  537.       CustDataLoad
  538.    End If
  539.    
  540.    CustReturn = BROWSE_EDIT
  541.    RecChange = False
  542. End Sub
  543.  
  544. Example (Creating a subindex):
  545.   ' we open a subindex just as we do a normal index
  546.   ' UserFname$ contains the path and name of the subindex
  547.   If Not vxFile(UserFname$) Then
  548.      vxCl1Ntx = vxCreateSubNtx(UserFname$, "vxser", "left(vxcountry,6)='CANADA'
  549.  .or. left(vxcountry,6)='U.S.A.'")
  550.   Else
  551.      vxCl1Ntx = vxUseNtx(UserFname$)
  552.   End If
  553.  
  554. See Also:
  555.    vxCreateNtx, vxIsSubNtx, vxNtxSubExpr, vxNumRecsSub, vxUseNtx
  556.  
  557.  
  558. vxIsPicture
  559. -----------
  560. Declaration:
  561.    Declare Function vxIsPicture Lib "vxbase.dll" (ByVal MemoFieldName
  562. As String) As Integer
  563.  
  564. Purpose:
  565.    Determine whether a bitmap is attached to the defined memo field.
  566.  
  567. Parameters:
  568.    MemoFieldName is either a string variable or a literal string that
  569. contains a valid memo field name from the currently selected database.
  570. MemoFieldName may be qualified with a valid alias name that points to
  571. any open database.
  572.  
  573. Returns:
  574.   TRUE if a bitmap is present and FALSE if not. Note that text attached
  575. to the field instead of a bitmap will return FALSE.
  576.  
  577. Usage:
  578.    Could be used to determine whether or not to load a new bitmap.
  579.  
  580. Example:
  581.  
  582.    ' the name of the bmp picture file is the
  583.    ' same as the string in field "title" so
  584.    ' we can import the bmps into the memo file
  585.    ' by cocatenating ".bmp" to the trimmed field
  586.    ' contents
  587.    ' -------------------------------------------
  588.    j% = vxTop()
  589.    If Not vxIsPicture("pic") Then
  590.       For i& = 1 To 13 ' there are 13 recs in the file
  591.          j% = vxGo(i&)
  592.          ftitle$ = vxFieldTrim("type")
  593.          fname$ = "c:\magic\bmp\" + ftitle$ + ".bmp"
  594.          If Not vxPictureImport(fname$, "pic") Then
  595.             MsgBox "Import Failed"
  596.          End If
  597.       Next i&
  598.       j% = vxClose() ' close ensures buffers flushed
  599.       AirPicsDbf = vxUseDbf("\vb\vxbtest\airpics.dbf")
  600.       j% = vxSelectDbf(AirPicsDbf)
  601.    End If  
  602.  
  603. See Also:
  604.    vxIsMemo, vxMemoClear, vxPictureImport, vxPicturePrint, 
  605. vxPictureRead, vxSetAlias
  606.  
  607.  
  608. vxIsSubNtx
  609. ----------
  610. Declaration:
  611.    Declare Function vxIsSubIndex Lib "vxbase.dll" (ByVal NtxArea As Integer)
  612. As Integer
  613.  
  614. Purpose:
  615.    Determine whether or not the defined index is a subindex or a normal
  616. index.
  617.  
  618. Parameters:
  619.    NtxArea is the select area of an index file returned by vxUseNtx or
  620. vxAreaNtx.
  621.  
  622. Returns:
  623.    TRUE if the index is a subindex or FALSE if it is not.
  624.  
  625. Usage:
  626.    It may be necessary to determine an update strategy or perhaps
  627. do something based upon the record count depending on whether or not the
  628. entire file is represented in the index. 
  629.  
  630. Example:
  631.    If vxIsSubNtx(vxNtxCurrent()) Then
  632.       NumRecs& = vxNumRecsSub()
  633.    Else
  634.       NumRecs& = vxNumRecs()
  635.    End If
  636.    
  637. See Also:
  638.    vxCreateSubNtx, vxNtxCurrent, vxNtxSubExpr, vxNumRecsSub, vxUseNtx
  639.  
  640.  
  641. vxLockRetry
  642. -----------
  643. Declaration:
  644.    Declare Sub vxLockRetry Lib "vxbase.dll" (ByVal ErrorMode As Integer,
  645. ByVal WaitSeconds As Integer)
  646.  
  647. Purpose:
  648.    Set the method of reporting a locked file or record to the user and
  649. also specify a lock try timeout value.
  650.  
  651. Parameters:
  652.    ErrorMode is passed as either TRUE or FALSE.
  653.  
  654.    If TRUE (the default), and an operation is performed that requires
  655. a lock (either record or file) which is unable to be set because another
  656. user has control of the record or file, the user is presented with a message
  657. from vxBase that asks if he wishes to retry the operation or abort.  If 
  658. "Retry" is chosen, vxBase attempts to set the lock again.  
  659.  
  660.    If ErrorMode is passed as FALSE, vxBase issues error code 610 "File lock
  661. error" instead of the retry message IF vxSetErrorMethod is set to TRUE. If the
  662. alternate error method is TRUE, the programmer can then set up his own
  663. method of dealing with locks through the VB ON ERROR routine.  
  664.  
  665.    If vxSetErrorMethod is FALSE and ErrorMode is FALSE, the default user retry
  666. message is sent instead.
  667.  
  668.    WaitSeconds is the number of seconds to continue to attempt setting a lock.
  669. If zero (0), and a lock fails, the lock function returns with the error
  670. immediately and either presents the "Retry" message to the user or triggers
  671. the vxBase 600 error depending on the value of ErrorMode and vxSetErrorMethod.
  672.  
  673.    If WaitSeconds is greater than zero, vxBase will continue to attempt to set
  674. the lock until WaitSeconds has expired. The maximum number of WaitSeconds that
  675. can be specified is 32,767 (which equates to over 9 hours) and is essentially
  676. a "wait forever" state.
  677.  
  678. Returns:
  679.    Nothing.
  680.  
  681. Usage:
  682.    In a multiuser environment the programmer often wishes to handle the failed
  683. lock scenario himself rather than rely on the user to retry the lock or not. This
  684. is the function of the errormode parameter.
  685.   
  686.    Setting WaitSeconds to about 20 is a good value for normal database operations.
  687. For example, if a record is to be written, vxBase will try over and over again
  688. for 20 seconds to set the lock. After the time has expired, the selected error
  689. method is executed.
  690.  
  691.    If using vxBase in an unattended program, it makes good sense to set the timeout
  692. value very high. Other processes that take control of a file for 15 or 20 minutes
  693. then do not necessarily disrupt the unattended program from performing its tasks
  694. after the file has been released.
  695.  
  696.    NOTE:  If a file is opened for exclusive use with vxUseDbfEX then ALL other
  697. processes requiring that file across the entire network will be denied access to
  698. the file.  The vxUseDbfEX function sets a network SHARE flag rather than a
  699. Clipper style lock on the file and no one is granted access to the file no matter
  700. what the value of vxSetLocks.
  701.  
  702.    NOTE:  vxLockRetry settings are GLOBAL to all vxBase tasks on a workstation.
  703. Once you select a set of values, you should use the same values in all of your vxBase
  704. programs.
  705.  
  706.  
  707. Example:
  708.    ' this function attempts to write a record and, if the required
  709.    ' lock fails, it send the user its own message asking for a
  710.    ' another attempt instead of using the vxBase default Retry? message
  711.    ' ------------------------------------------------------------------
  712.    Sub RecWrite
  713.       Dim vxError As vxErrorStruc
  714.       Dim RetryVal As Integer
  715.  
  716.       vxSetLocks FALSE
  717.       vxSetErrorMethod TRUE
  718.       vxLockRetry 0, 20
  719.       ' will use alternate error method after
  720.       ' retrying a lock for 20 seconds
  721.  
  722.       On Error GoTo LockError
  723.  
  724.       ' we will attempt to lock the record
  725.       ' as long as RetryVal is zero. If the
  726.       ' lock required by vxWrite fails, we
  727.       ' exit to the On Error routine - which
  728.       ' will set RetryVal to 2 if the user
  729.       ' does not wish to retry.
  730.       ' -------------------------------------
  731.       RetryVal = 0
  732.  
  733.       Do
  734.          If vxLockRecord() Then RetryVal = 1
  735.       Loop While RetryVal = 0
  736.  
  737.       If RetryVal = 1 Then 
  738.          If Not vxWrite() Then
  739.             MsgBox "Record Write Error"
  740.          End If      
  741.       End If
  742.       
  743.       vxSetErrorMethod FALSE
  744.       Exit Sub
  745.  
  746.    LockError:
  747.       If vxErrorTest(vxError) Then
  748.          If vxError.ErrorNum = 600 Then
  749.             j% = MsgBox("Lock failed. Retry?", 52)
  750.             If j% = 6 Then
  751.                Resume Next
  752.             Else
  753.                RetryVal = 2
  754.                Resume Next
  755.             End If
  756.          End If
  757.       End If
  758.  
  759.    End Sub
  760.  
  761. See Also:
  762.    vxIsRecLocked, vxLockDbf, vxLocked, vxLockRecord, vxSetLocks,
  763.    vxUnlock, vxUseDbfEX
  764.  
  765. vxMemCompact
  766. ------------
  767. Declaration:
  768.    Declare Function vxMemCompact Lib "vxbase.dll" () As Long
  769.  
  770. Purpose
  771.    Windows memory can become extremely fragmented when running a vxBase
  772. application. The vxBase program architecture is built of many small
  773. chunks which are all discardable and may be loaded on call. Other tasks
  774. running concurrently with vxBase can also contribute to memory
  775. fragmentation and consequent loss of perfromance or even out of memory
  776. conditions when a large request is made for some fixed memory (e.g.,
  777. reading a memo). vxMemCompact uses Windows API routines to compact
  778. memory and leave the largest contiguous free areas possible.
  779.  
  780. Parameters
  781.    None.
  782.  
  783. Returns
  784.    A long integer that contains the number of bytes in the largest free
  785. global memory object in the global heap.
  786.  
  787. Example
  788.    ' compact memory on each return to the controlling form
  789.    ' -----------------------------------------------------
  790.    Sub Form_Unload (Cancel As Integer)
  791.       vxWindowDereg(VXFORM5.hWnd)
  792.       vxMemCompact
  793.    End Sub
  794.  
  795.  
  796. vxMemoClear
  797. -----------
  798. Declaration:
  799.    Declare Function vxMemoClear Lib "vxbase.dll" (ByVal MemoFieldName
  800. As String) As Integer
  801.  
  802. Purpose:
  803.    Remove a memo block reference from a memo field. The bitmap OR memo
  804. attached to the field is effectively deleted.
  805.  
  806. Parameters:
  807.    MemoFieldName is either a string variable or a literal string that
  808. contains a valid memo field name from the currently selected database.
  809. MemoFieldName may be qualified with a valid alias name that points to
  810. any open database.
  811.  
  812. Returns:
  813.    TRUE if the operation was successful and FALSE if not. Always
  814. returns FALSE is always returned if the associated dbf has been opened
  815. as Read Only with vxUseDbfRO.
  816.  
  817. Usage:
  818.    Delete a memo or bitmap.
  819.  
  820. Example:
  821.  
  822.    Sub ButtonDelete_Click ()
  823.       If vxMemoClear("pic") Then
  824.          PicBox.Picture = LoadPicture()
  825.       Else
  826.          MsgBox "Delete failed"
  827.       End If
  828.  
  829. See Also:
  830.       vxIsMemo, vxIsPicture, vxReplMemo, vxPictureImport, vxSetAlias
  831.  
  832.  
  833. vxMemoPos
  834. ---------
  835. Declaration:
  836.    Declare Sub vxMemoPos Lib "vxbase.dll" (ByVal StartX As Integer,
  837. ByVal StartY As Integer, ByVal xWidth As Integer, ByVal yHeight As Integer,
  838. ByVal MemoTitle As String)
  839.  
  840. Purpose:
  841.    Set the start position and size of an upcoming memo edit window that
  842. will edit a memo attached to the current database with vxMemoEdit. Also
  843. used to set up the memo edit window title.
  844.  
  845. Parameters:
  846.    Window coordinates passed to this function use familiar character units
  847. in the x dimension and line height units in the y dimension. The units are
  848. converted to the average character width and height of the standard
  849. Windows system font and are therefore device independent.
  850.  
  851.    StartX is the start position of the memo window in characters from the
  852. left edge of the screen.
  853.  
  854.    StartY is the start position of the memo window in lines from the top
  855. of the screen.
  856.  
  857.    xWidth is the start width of the memo window in characters.
  858.  
  859.    yHeight is the height of the memo window (including caption and menu
  860. bars) in lines.
  861.  
  862. Returns:
  863.    Nothing.
  864.  
  865. Usage:
  866.    Memo window position and size are defaulted according to the size of
  867. the parent window passed to the vxMemoEdit function if this command is
  868. not issued. If this Sub is called, the position and size are relative to the
  869. entire screen.
  870.  
  871.    The default memo window caption is "Memo Edit: DBF name". If this is good
  872. enough, pass the MemoTitle as a null value (ByVal 0&).
  873.  
  874.    If you wish to set the memo title only and leave the size and position as
  875. the default values, pass all x and y coordinates as 0. For example,
  876. Call vxMemoPos(0,0,0,0,"My Memo Title")
  877.  
  878.    If the user sizes the memo window according to his own tastes, its position
  879. and size will be retained on subsequent edits.
  880.  
  881. Example:
  882.    Call vxMemoPos(10, 5, 60, 15, "Customer Complaints")
  883.    RecNum& = vxRecNo()
  884.    Call vxMemoEdit(VXFORM3.hWnd, "a_memo")
  885.    j% = vxGo(RecNum&)
  886.    j% = vxUnLock()
  887.  
  888. See Also:
  889.    vxMemoEdit
  890.  
  891.  
  892. vxMemRealloc
  893. ------------
  894. Declaration
  895.    Declare Function vxMemRealloc Lib "vxbase.dll" (ByVal NumDbf As Integer,
  896. ByVal NumNtx As Integer, ByVal ReindexBuff As Integer) As Integer
  897.  
  898. Purpose
  899.    Decrease the initial vxBase memory requirements.
  900.  
  901. Parameters
  902.    NumDbf is the number of dbf files that will be opened simultaneously. The
  903. minimum number is 2.
  904.  
  905.    NumNtx is the number of ntx files that will be opened simultaneously. The
  906. minimum number is 2.
  907.  
  908.    ReindexBuff is passed as either TRUE or FALSE. If TRUE, a 64k buffer used
  909. to speed up creation of indexes and the reindex/pack routines is set up. If
  910. this parameter is passed as FALSE, the buffer is either removed (if is has 
  911. already been created) or not set up at all.
  912.  
  913. Returns
  914.    TRUE if the memory reallocation was successful and FALSE if not. 
  915.  
  916. Usage
  917.    The first call to vxBase allocates about 160,000 bytes to track open dbf
  918. files and open index files and also creates a 64k buffer used by vxReindex,
  919. vxPack, and vxCreateNtx. By calling vxMemRealloc(2, 2, FALSE) this huge block
  920. of memory may be reduced to about 35,000 bytes. If you are not going to 
  921. be creating indexes, reindexing, or packing, the ReindexBuff may be passed
  922. as FALSE to remove an immediate 64k.
  923.  
  924.    You should not use this function to INCREASE memory requirements. Let
  925. vxBase handle that automatically. DBF descriptor blocks and NTX buffers
  926. are each limited to 64k (FAR pointer arithmetic is used by vxBase) so the
  927. maximum number of open dbf and ntx files for ALL concurrent vxBase tasks is
  928. about 75. If more memory is required by vxBase, it will increase the size of
  929. each dbf or ntx object by the immediate amount required (to a maximum of
  930. 64k each).
  931.  
  932.    This function should be called in your initialization routine. It should
  933. only be called ONCE. It is not designed as an all purpose vxBase memory
  934. manager; rather it is designed to let users with low memory situations
  935. customize specific vxBase applications.
  936.  
  937.    WARNING: Use this function with care. This function CLOSES all open dbf
  938. and ntx files that belong to the current task before the memory is
  939. reallocated. If any files are open that belong to OTHER vxBase tasks,
  940. the function fails. ALWAYS test the result for a TRUE value to ensure
  941. the reallocation takes place.
  942.  
  943.  
  944.  
  945. Example
  946.  
  947.    ' The FIRST form load is used to initalize vxbase  
  948.    ' -----------------------------------------------
  949.    Sub Form_Load ()
  950.       vxInit
  951.       vxCtlGraySet
  952.       vxSetLocks FALSE
  953.       j% = vxCloseAll()
  954.       If Not vxMemRealloc(2, 2, FALSE) Then
  955.          MsgBox "Reallocation failed"
  956.          End
  957.       End If
  958.    End Sub
  959.  
  960. See Also
  961.    vxInit, vxMemCompact
  962.  
  963.  
  964.  
  965. vxNtxSubExpr
  966. ------------
  967. Declaration:
  968.    Declare Function vxNtxSubExpr Lib "vxbase.dll" (ByVal NtxArea As Integer)
  969. As String
  970.  
  971. Purpose:
  972.    Extract the conditional expression that controls the insertion/deletion
  973. of keys in a subindex.
  974.  
  975. Parameters:
  976.    NtxArea is the select area of an index file returned by vxUseNtx or
  977. vxAreaNtx.
  978.  
  979. Returns:
  980.    A string that contains the conditional expression used to create the
  981. subindex. The string is either in Visual Basic format or C format depending
  982. upon the value of vxSetString.
  983.  
  984. Usage:
  985.    Especially useful in creating files at run time that are copies of
  986. existing files and that are to be indexed in the same way. Or in reporting
  987. the conditions of index insertion to the user.
  988.  
  989. Example:
  990.    If vxIsSubNtx(vxNtxCurrent()) Then
  991.       NumRecs& = vxNumRecsSub()
  992.       Form1.Caption = "Subindex on " + vxNtxExpr(vxNtxCurrent()) +
  993. " For Condition " + vxNtxSubExpr(vxNtxCurrent())
  994.    Else
  995.       NumRecs& = vxNumRecs()
  996.       Form1.Caption = "Master Index on " + vxNtxExpr(vxNtxCurrent())
  997.    End If
  998.    
  999. See Also:
  1000.    vxCreateSubNtx, vxIsSubNtx, vxNtxCurrent, vxNtxExpr, vxNtxSubExpr,
  1001.  vxNumRecsSub
  1002.  
  1003.  
  1004. vxNumRecsFilter
  1005. ---------------
  1006. Declaration:
  1007.    Declare Function vxNumRecsFilter Lib "vxbase.dll" () As Long
  1008.  
  1009. Purpose:
  1010.    Return the number of records in the database that pass the defined
  1011. filter.
  1012.  
  1013. Parameters:
  1014.    None. The number of records returned is for the currently 
  1015. selected database.
  1016.  
  1017. Usage:
  1018.    Useful for generating accurate scroll bar extents and as a FOR LOOP
  1019. counter. Note that this function does exactly what you would do to
  1020. determine the number of records in a database that satisfy some
  1021. condition. It must read every record in the database, evaluate the
  1022. filter, and increment a counter. It is done at a lower level but
  1023. still can take a lot of time in a large database.
  1024.  
  1025. Example:
  1026.    j% = vxSelectDbf(TestDbf")
  1027.    Debug.Print vxNumRecs()
  1028.    Call vxFilter("trim(vxcountry)='CANADA')
  1029.    Debug.Print vxNumrecsFilter()
  1030.  
  1031. See Also:
  1032.    vxFilter, vxFilterReset, vxNumRecs, vxNumrecsSub
  1033.  
  1034. vxNumRecsSub
  1035. ------------
  1036. Declaration:
  1037.    Declare Function vxNumRecsSub Lib "vxbase.dll" () As Long
  1038.  
  1039. Purpose:
  1040.    Return the number of records in a subindex.
  1041.  
  1042. Parameters:
  1043.    None. The subindex MUST be the currently selected index.
  1044.  
  1045. Usage:
  1046.    Generally used as a FOR LOOP counter or as a statistic. It may also
  1047. be used to set an accurate vertical scroll bar extent.
  1048.  
  1049. Example:
  1050.    If vxIsSubNtx(vxNtxCurrent()) Then
  1051.       NumRecs& = vxNumRecsSub()
  1052.       Form1.Caption = "Subindex on " + vxNtxExpr(vxNtxCurrent()) +
  1053. " For Condition " + vxNtxSubExpr(vxNtxCurrent())
  1054.    Else
  1055.       NumRecs& = vxNumRecs()
  1056.       Form1.Caption = "Master Index on " + vxNtxExpr(vxNtxCurrent())
  1057.    End If
  1058.    
  1059. See Also:
  1060.    vxCreateSubNtx, vxIsSubNtx, vxNtxCurrent, vxNtxExpr, vxNtxSubExpr
  1061.  
  1062.  
  1063. vxPictureImport
  1064. ---------------
  1065. Declaration:
  1066.    Declare Function vxPictureImport Lib "vxbase.dll" (ByVal BmpFileName As
  1067. String, ByVal MemoFieldName As String) As Integer
  1068.  
  1069. Purpose:
  1070.    Import a bitmap from a system .BMP file into a memo field. The image
  1071. may be displayed with vxPictureRead. The maximum size of the bitmap is
  1072. 16 megabytes.
  1073.  
  1074. Parameters:
  1075.    BmpFileName is the complete name of the bitmap file including path
  1076. and extension. Files other than bitmaps may be stored into the memo
  1077. file but they may not be read with vxPictureRead (unless they are run
  1078. length encoded compressed variants of BMPS - i.e., RLE files in either
  1079. 4 or 8 bit per pixel format). The file name may be represented by a
  1080. literal string or a string variable.
  1081.  
  1082.    MemoFieldName is either a string variable or a literal string that
  1083. contains a valid memo field name from the currently selected database.
  1084. MemoFieldName may be qualified with a valid alias name that points to
  1085. any open database.
  1086.  
  1087. Returns:
  1088.    FALSE if the function fails and TRUE if successful. FALSE is always
  1089. returned if the associated dbf has been opened as Read Only with
  1090. vxUseDbfRO.
  1091.  
  1092. Usage:
  1093.    It is much more efficient both from a retrieval standpoint and from
  1094. a disk management standpoint to store bitmaps you wish to have 
  1095. associated with database records in a single source file.
  1096.    Store pictures of people in personnel files, parts images in
  1097. inventory files, homes in real estate files, etc. 
  1098.  
  1099.    Files other than BMPs may also be stored in a memo file. Note, however,
  1100. that only BMP or RLE format files are converted by vxPictureRead for display
  1101. in a Visual basic picture box. The memo link parameters included in the
  1102. vxCtlBrowse function will also result in bitmap display WITHOUT any
  1103. effort required by the programmer other that defining the memo window
  1104. and memo field name to the vxCtlBrowse function.
  1105.  
  1106. Collecting Bitmaps
  1107.    vxBase takes advantage of the rich body of functions included in Visual
  1108. Basic to handle bitmap files. Bitmaps are the Windows norm; all paint
  1109. programs, viewers, etc. can handle bitmaps - and most programs that
  1110. deal with pictures can convert foreign formats (e.g., GIF) to BMPs.
  1111. As a last resort, cut a picture into the clipboard and paste it into a 
  1112. Windows PAINT window. It can then be stored as a .BMP file. 
  1113.  
  1114.    Once an image is stored in a BMP file it can be transferred to the 
  1115. memo file with the vxPictureImport function. To retrieve the bitmap,
  1116. vxBase uses the standard Windows Clipboard. It puts the bitmap out to
  1117. the clipboard as a DIB (device independent bitmap). The Visual Basic
  1118. Clipboard.GetData(8) function then is used to retrieve the image
  1119. from the clipboard and display it in a VB Picture Box. The box
  1120. can have the AUTORESIZE property set to TRUE as in the sample
  1121. application if the images are all different sizes
  1122.  
  1123.    Bitmap files can be created from existing images you may be using in
  1124. a Visual Basic program by calling the SavePicture function. You can then
  1125. call vxPictureImport to store the image in a memo file by using the name
  1126. of the bitmap file you created with SavePicture. You can also SavePicture
  1127. to export pictures from a memo file by first reading them into a picture
  1128. box with vxPictureRead.
  1129.  
  1130. Example:
  1131.    ' the name of the bmp picture file is the
  1132.    ' same as the string in field "title" so
  1133.    ' we can import the bmps into the memo file
  1134.    ' by cocatenating ".bmp" to the trimmed field
  1135.    ' contents
  1136.    ' -------------------------------------------
  1137.    j% = vxTop()
  1138.    If Not vxIsPicture("pic") Then
  1139.       For i& = 1 To 13 ' there are 13 recs in the file
  1140.          j% = vxGo(i&)
  1141.          ftitle$ = vxFieldTrim("type")
  1142.          fname$ = "c:\magic\bmp\" + ftitle$ + ".bmp"
  1143.          If Not vxPictureImport(fname$, "pic") Then
  1144.             MsgBox "Import Failed"
  1145.          End If
  1146.       Next i&
  1147.       j% = vxClose() ' close ensures buffers flushed
  1148.       AirPicsDbf = vxUseDbf("\vb\vxbtest\airpics.dbf")
  1149.       j% = vxSelectDbf(AirPicsDbf)
  1150.    End If  
  1151.  
  1152. See Also:
  1153.    vxIsPicture, vxMemoClear, vxPicturePrint, vxPictureRead
  1154.  
  1155.  
  1156. vxPicturePrint
  1157. --------------
  1158. Declaration:
  1159.    Declare Function vxPicturePrint Lib "vxbase.dll" (ByVal MemoFieldName As
  1160. String) As Integer
  1161.  
  1162. Purpose:
  1163.    Print a MONOCHROME bitmap that has been stored in a vxbase memo file.
  1164.  
  1165. Parameters:
  1166.    MemoFieldName is either a string variable or a literal string that
  1167. contains a valid memo field name from the currently selected database.
  1168. MemoFieldName may be qualified with a valid alias name that points to
  1169. any open database.
  1170.  
  1171. Returns:
  1172.    FALSE if the function fails and TRUE if successful.
  1173.  
  1174. Usage:
  1175.    The bitmap image is expanded or compressed to best fit the current
  1176. page size set for the selected printer.  Color bitmaps print very
  1177. poorly because the Windows StretchBlt function used by vxPicturePrint does not
  1178. convert the color images to black and white very well.  If you are going
  1179. to print a lot of bitmaps, use a conversion program to convert color bitmaps
  1180. to black and white before saving to the memo file.
  1181.  
  1182. Example:
  1183.    Sub ButtonPrint_Click ()
  1184.       j% = vxSelectDbf(AirPicsDbf)
  1185.       TopRec& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_GETTOPREC, 0)
  1186.       RecNum& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_GETCURRENTREC, 0)
  1187.       j% = vxGo(RecNum&)
  1188.       If Not vxPicturePrint("pic") Then
  1189.          MsgBox "Print Failed"
  1190.       End If
  1191.       r& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_REFRESH, ByVal TopRec&)
  1192.    End Sub
  1193.  
  1194. See Also:
  1195.    vxIsPicture, vxPictureImport, vxPictureRead
  1196.  
  1197.  
  1198. vxPictureRead
  1199. -------------
  1200. Declaration:
  1201.    Declare Function vxPictureRead Lib "vxbase.dll" (ByVal PicHwnd
  1202. As Integer, ByVal MemoFieldName As String) As Integer
  1203.  
  1204. Purpose:
  1205.    Display a bitmap in a defined window that was stored in a memo 
  1206. file with vxPictureImport.
  1207.  
  1208. Parameters:
  1209.    PicHwnd is the window handle of the window that will receive the
  1210. image. In Visual basic, use vxCtlHwnd to convert a control handle to
  1211. a window handle.
  1212.  
  1213.    MemoFieldName is either a string variable or a literal string that
  1214. contains a valid memo field name from the currently selected database.
  1215. MemoFieldName may be qualified with a valid alias name that points to
  1216. any open database.
  1217.  
  1218. Returns:
  1219.    TRUE if the operation was successful and FALSE is not.
  1220.  
  1221. Usage:
  1222.    Only BITMAPS that have been stored with vxPictureImport may be
  1223. extracted with vxPictureRead. vxPictureRead assumes the binary object
  1224. contained in the memo is a formatted bitmap which contains a Windows
  1225. BITMAPFILEHEADER followed by a BITMAPINFOHEADER followed by an array
  1226. of RGBQUAD structures. All of this information is then followed by the
  1227. bitmap data itself. vxPictureRead creates a DIB (device independent 
  1228. bitmap) out of the Windows data structures and passes the DIB to the
  1229. clipboard, where it can easily be extracted and placed into a Visual
  1230. Basic picture box (or onto a form) with the ClipBoard.GetData(8)
  1231. function.
  1232.    If the structure contained in the memo is not a formal bitmap,
  1233. who knows what result?
  1234.  
  1235.    If you wish to store Binary Large Objects (BLOBs) in the memo file
  1236. other than bitmaps, you must use the vxBlobWrite and vxBlobRead functions
  1237. to access the data. These functions use Windows Global memory handles
  1238. as parameters and are not easily available to the Visual Basic programmer.
  1239.  
  1240.    NOTE: The memo link parameters included in the vxCtlBrowse function
  1241. will also result in bitmap display WITHOUT any effort required by the
  1242. programmer other than defining the memo window and memo field name to
  1243. the vxCtlBrowse function. When vxCtlBrowse displays a bitmap, it auto-
  1244. matically sizes the memo link window to the size of the bitmap. The top left
  1245. corner of your memo window is anchored. If there is not enough room on the 
  1246. form to contain the entire bitmap, it is clipped on the right and/or the
  1247. bottom to the limits of the parent form.
  1248.  
  1249. Example:
  1250.    The following code is a complete reproduction of the code contained
  1251. in VYFORM2 in the vxbtest project sample application:
  1252.  
  1253.  
  1254. ' static switch set to TRUE in form
  1255. ' load procedure so we know when this
  1256. ' form is first loaded
  1257. Dim FirstTime As Integer
  1258.  
  1259. Sub BrowseBox_KeyDown (KeyCode As Integer, Shift As Integer)
  1260.    ' whenever a record is highlighted, this
  1261.    ' proc receives a middle button code
  1262.    ' from the ctlBrowse so we can dynamically
  1263.    ' display the picture in the memo field
  1264.    ' -------------------------------------------
  1265.    If KeyCode = 4 Then  ' middle button?
  1266.       j% = vxSelectDbf(AirPicsDbf)
  1267.       RecNum& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_GETCURRENTREC, 0)
  1268.       j% = vxGo(RecNum&)
  1269.       VYFORM2.Caption = vxFieldTrim("Title")
  1270.       If vxPictureRead(vxCtlHwnd(PicBox), "pic") Then
  1271.          ' the "8" param below is CF_DIB
  1272.          PicBox.Picture = Clipboard.GetData(8)
  1273.          ' If you want to leave the picture in
  1274.          ' the clipboard, comment out line below
  1275.          Clipboard.Clear
  1276.       Else
  1277.          PicBox.Picture = LoadPicture() ' clears the picture area
  1278.       End If
  1279.    End If
  1280.  
  1281.    ' -----------------------------------------------------------------
  1282.    ' NOTE: the code above is an example of using vxPictureRead.
  1283.    '       In this case (displaying records in a vxCtlBrowse table),
  1284.    '       it would be much more efficient to define the memo window
  1285.    '       and the memo field name to the vxCtlBrowse function instead
  1286.    ' -----------------------------------------------------------------
  1287. End Sub
  1288.  
  1289. Sub BrowseBox_KeyPress (KeyAscii As Integer)
  1290.  
  1291.    ' NOTE: YOU MUST ALWAYS TRAP THE ENTER KEY
  1292.    '       AND CHANGE THE KEYASCII CODE TO
  1293.    '       A ZERO WHEN USING VXCTLBROWSE
  1294.    '       EVEN IF YOU DON'T USE IT
  1295.    ' ----------------------------------------
  1296.    If KeyAscii = 13 Then
  1297.       KeyAscii = 0
  1298.       Exit Sub
  1299.    End If
  1300.  
  1301.    ' if ESC key is received, then emulate
  1302.    ' exit button press
  1303.    ' ------------------------------------
  1304.    If KeyAscii = 27 Then
  1305.       KeyAscii = 0
  1306.       ButtonExit_Click
  1307.       Exit Sub
  1308.    End If
  1309.  
  1310. End Sub
  1311.  
  1312. Sub ButtonExit_Click ()
  1313.    Unload VYFORM2
  1314. End Sub
  1315.  
  1316. Sub Form_Load ()
  1317.    ' set FirstTime switch on for Paint
  1318.    ' ---------------------------------
  1319.    FirstTime = True
  1320.  
  1321.    ' register the default database as the master
  1322.    ' -------------------------------------------
  1323.    AirPicsDbf = vxUseDbf("\vb\vxbtest\airpics.dbf")
  1324.    j% = vxSelectDbf(AirPicsDbf)
  1325.    
  1326.    ' first time load pictures
  1327.    j% = vxTop()
  1328.  
  1329.    ' the name of the bmp picture file is the
  1330.    ' same as the string in field "title" so
  1331.    ' we can import the bmps into the memo file
  1332.    ' by cocatenating ".bmp" to the trimmed field
  1333.    ' contents
  1334.    ' -------------------------------------------
  1335.    If Not vxIsPicture("pic") Then
  1336.       For i& = 1 To 13
  1337.          j% = vxGo(i&)
  1338.          ftitle$ = vxFieldTrim("type")
  1339.          fname$ = "c:\magic\bmp\" + ftitle$ + ".bmp"
  1340.          If Not vxPictureImport(fname$, "pic") Then
  1341.             MsgBox "Import Failed"
  1342.          End If
  1343.       Next i&
  1344.       j% = vxClose()
  1345.       AirPicsDbf = vxUseDbf("\vb\vxbtest\airpics.dbf")
  1346.       j% = vxSelectDbf(AirPicsDbf)
  1347.    End If
  1348.    
  1349.    ' set up the browse
  1350.    ' -----------------
  1351.    Call vxTableDeclare(VX_RED, ByVal 0&, ByVal 0&, 0, 1, 1)
  1352.    Call vxTableField(1, "Type", "type", VX_FIELD)
  1353.  
  1354.    Call vxBrowseCase(VX_UPPER)
  1355.    Call vxBrowseSetup(0, 0, 0, 1, "Helv", 15, VX_SEMIBOLD, 0, 0, 0, 0)
  1356.    ' If the typeface is too large on your display,
  1357.    ' CHANGE the parameter following "Helv" above to
  1358.    ' a smaller number
  1359.    ' ----------------------------------------------
  1360.    
  1361.    ' change the mouse pointer in the browse box
  1362.    ' from an I-Beam to an arrow to stop any flicker
  1363.    ' ----------------------------------------------
  1364.    BrowseBox.MousePointer = 1
  1365.  
  1366. End Sub
  1367.  
  1368. Sub Form_Paint ()
  1369.   ' register the database with this window
  1370.    ' --------------------------------------
  1371.    j% = vxSelectDbf(AirPicsDbf)
  1372.  
  1373.    ' make the form 3-d
  1374.    ' -----------------
  1375.    Call vxFormFrame(VYFORM2.hWnd)
  1376.    Call vxCtlStyle(BrowseBox, VX_RECESS)
  1377.  
  1378.    ' initiate the browse the first time only
  1379.    ' ---------------------------------------
  1380.    If FirstTime = True Then
  1381.       j% = vxCtlBrowse(vxCtlHwnd(BrowseBox), AirPicsDbf, 0, 0, 0, 0, " ")
  1382.       FirstTime = False
  1383.    End If
  1384.  
  1385.    ' on initial paint of the browse, middle button
  1386.    ' keydown is not sent to browse box so we want
  1387.    ' to do our dynamic display here as well as
  1388.    ' from a keydown in the browse box code
  1389.    ' ---------------------------------------------
  1390.    Call BrowseBox_KeyDown(4, 0)
  1391.   
  1392. End Sub
  1393.  
  1394. Sub Form_Resize ()
  1395.    VYFORM2.Refresh
  1396. End Sub
  1397.  
  1398. Sub Form_Unload (Cancel As Integer)
  1399.  ' close the browse
  1400.    ' ----------------
  1401.    k& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_CLOSE, 0)
  1402.  
  1403.    ' close all the files
  1404.    ' -------------------
  1405.    j% = vxCloseAll()
  1406.  
  1407.    ' deregister the window and release memory
  1408.    ' ----------------------------------------
  1409.    vxWindowDereg (VYFORM2.hWnd)
  1410.  
  1411. End Sub
  1412.  
  1413. See Also:
  1414.    vxIsPicture, vxPictureImport, vxPicturePrint
  1415.  
  1416.  
  1417. vxSetGauge
  1418. ----------
  1419. Declaration
  1420.    Declare Sub vxSetGauge Lib "vxbase.dll" (ByVal Hwnd As Integer)
  1421.  
  1422. Purpose
  1423.    Sets up an alternative method for generating analog or digital gauge
  1424. information on time consuming indexing and pack procedures. If 
  1425. vxSetMeters is FALSE, and a window handle representing a gauge control
  1426. (or any other valid window) is passed to vxBase via vxSetGauge, a
  1427. KeyDown event is triggered for the defined control or window whenever
  1428. the completion percentage of the active procedure changes. 
  1429.    The KeyCode parameter passed to the KeyDown event procedure contains
  1430. the percentage complete instead of a key value.  This percentage is
  1431. passed as a NEGATIVE number so the programmer can distinguish between
  1432. normal key codes and key codes sent by the vxBase procedure.
  1433.  
  1434. Parameters
  1435.    Hwnd is a window handle to the gauge or textbox control.  If the
  1436. form element KeyDown event being triggered is for a Visual Basic control,
  1437. use vxCtlHwnd to convert the control handle to a window handle.
  1438.  
  1439. Returns
  1440.    Nothing. 
  1441.  
  1442. Usage
  1443.    The sample below shows how to use the vxSetGauge function to control
  1444. the progress of a gauge control (the one included in the Visual Basic
  1445. Professional kit).
  1446.  
  1447.    The following functions will generate KeyDown events for the defined
  1448. control: vxCreateNtx, vxCreateSubNtx, vxPack, and vxReindex (note the
  1449. absence of vxTestNtx from this list).
  1450.    With vxCreateNtx and vxCreateSubNtx we are working with a single
  1451. file at a time so the absolute value of the percentage number generated
  1452. may be used to directly set the gauge control value.
  1453.    With vxPack and vxReindex, you must use a method like the one shown in
  1454. the example below to generate meaningful gauge information.
  1455.    For example, if packing a dbf file with 3 indexes and an attached
  1456. memo (dbt) file, vxBase will generate percentage progress from 0 to 100
  1457. for EACH of the 5 files involved (1 dbf, 3 ntxs, 1 dbt). If you use
  1458. a method to factor the passed percentage and also track the total progress
  1459. then the gauge information will be properly presented to the user.
  1460.  
  1461. Example
  1462.  
  1463. ' This example uses a general form that contains nothing but
  1464. ' a gauge control (in the form of a speedometer) to present
  1465. ' analog progress information to the user. The gauge form is
  1466. ' shown and set up from a PackFiles_Click menu item on the
  1467. ' project's main form
  1468.  
  1469. ' The gauge form is VXFORMG and the gauge control is generated
  1470. ' by GAUGE.VBX included with the Visual Basic Professional
  1471. ' toolkit. The same control is also available from MicroHelp.
  1472.  
  1473. ' The Gauge control uses default properties EXCEPT for the
  1474. ' following:
  1475. '    Name = Gauge
  1476. '    Picture = (Bitmap)  (\vb\bitmqaps\gauge\speedo.bmp)
  1477. ' Style - 2-'Semi' Needle
  1478.  
  1479. ' the following Globals are defined to enable proper multifile
  1480. ' gauging during the pack operation:
  1481.  
  1482. Global GaugeFactor As Integer
  1483. Global GaugeTotal As Integer
  1484.  
  1485. ' The user clicks the PackFiles menu item
  1486. ' ---------------------------------------
  1487. Sub PackFiles_Click ()
  1488.    vxSetMeters False  ' turn off default meters
  1489.    VXFORMG.Show       ' show the form with the meter on it  
  1490.    VXFORMG.Caption = "Pack vxUser"  ' set the caption
  1491.    DoEvents           ' allows the bitmap to be drawn on the gauge   
  1492.    vxSetGauge vxCtlHwnd(VXFORMG.Gauge)   ' tell vxBase about the gauge
  1493.    GaugeTotal = 0     ' global total progess variable       
  1494.  
  1495.    ' pack user file
  1496.    ' --------------
  1497.    j% = vxAreaDbf(DirName + "vxuser.dbf")
  1498.    If j% > 0 Then
  1499.       MsgBox "vxuser in use!"
  1500.    Else
  1501.       vxClientDbf = vxUseDbf(DirName + "vxuser.dbf")
  1502.       vxWhere = vxUseNtx(DirName + "vxwhere.ntx")
  1503.       vxCl1Ntx = vxUseNtx(DirName + "vxuser.ntx")
  1504.       vxNorthNtx = vxUseNtx(DirName + "vxnorth.ntx")
  1505.       vxPhoneNtx = vxUseNtx(DirName + "vxphone.ntx")
  1506.       vxNameNtx = vxUseNtx(DirName + "vxname.ntx")
  1507.       vxCompNtx = vxUseNtx(DirName + "vxcomp.ntx")
  1508.  
  1509.       ' GaugeFactor is 8 (one for each file above PLUS a dbt
  1510.       ' which this file has attached
  1511.       GaugeFactor = 8
  1512.       j% = vxSelectDbf(vxClientDbf)
  1513.       j% = vxPack(VXFORM1.hWnd)
  1514.       j% = vxClose()
  1515.    End If
  1516.  
  1517.    ' pack fax file
  1518.    ' -------------
  1519.    VXFORMG.Caption = "Pack vxFax"  ' new caption
  1520.    VXFORMG.Gauge.Value = 0         ' reset gauge to 0
  1521.    j% = vxAreaDbf(DirName + "vxfax.dbf")
  1522.    If j% > 0 Then
  1523.       MsgBox "vxfax in use!"
  1524.    Else
  1525.       GaugeTotal = 0    ' reset total progress var
  1526.       GaugeFactor = 3   ' this file has 3 elements (dbf, ntx, dbt)
  1527.       vxFaxDbf = vxUseDbf(DirName + "vxfax.dbf")
  1528.       vxFaxNtx = vxUseNtx(DirName + "vxfax.ntx")
  1529.       j% = vxSelectDbf(vxFaxDbf)
  1530.       j% = vxPack(VXFORM1.hWnd)
  1531.       j% = vxClose()
  1532.    End If
  1533.    Unload VXFORMG   ' unload the gauge form
  1534.    vxSetGauge 0     ' turn off the gauge setting
  1535.    vxSetMeters True ' set default meters back on
  1536. End Sub
  1537.  
  1538. ' This is ALL of the code associated with the generic gauge form
  1539. ' --------------------------------------------------------------
  1540. Sub Form_Paint ()
  1541.    Call vxFormFrame(VXFORMG.hWnd)
  1542. End Sub
  1543.  
  1544. Sub Gauge_KeyDown (KeyCode As Integer, Shift As Integer)
  1545.    Dim pValue As Integer
  1546.    
  1547.    ' NOTE: --------------------------------------
  1548.    ' vxBase sends the KeyCode as a negative value
  1549.    ' so the user can distinguish between normal
  1550.    ' keydown events and those triggered by the
  1551.    ' vxSetGauge function. This is especially
  1552.    ' important if the Form KeyPreview property
  1553.    ' is set to TRUE. You can then ignore all
  1554.    ' key values that are less than 0
  1555.    ' --------------------------------------------
  1556.    If KeyCode < 0 Then
  1557.       If GaugeFactor > 0 Then
  1558.          If Abs(KeyCode) = 100 Then
  1559.             GaugeTotal = (100 / GaugeFactor) + GaugeTotal
  1560.             pValue = 0
  1561.          Else
  1562.             pValue = Abs(KeyCode) / GaugeFactor
  1563.          End If
  1564.       Else
  1565.          pValue = Abs(KeyCode)
  1566.       End If
  1567.       Gauge.Value = pValue + GaugeTotal
  1568.  
  1569.       ' ---------------------------------------------- 
  1570.       ' you could also set a digital value into a text
  1571.       ' box or label here
  1572.       ' ----------------------------------------------
  1573.    End If
  1574. End Sub
  1575.  
  1576. See Also
  1577.    vxCreateNtx, vxCreateSubNtx, vxPack, vxReindex, vxSetMeters
  1578.  
  1579.   
  1580.  
  1581. vxSetSelect
  1582. -----------
  1583. Declaration
  1584.    Declare Sub vxSetSelect Lib "vxbase.dll" (ByVal OnOrOff As Integer)
  1585.  
  1586. Purpose
  1587.    Turn off vxBase automatic database selection. Whenever a vxBase
  1588. database function is called, the last database selected for the current
  1589. window is used to perform the database function. If there was no
  1590. database active for the current window, then the last selected database
  1591. for the current task is automatically selected instead.
  1592.  
  1593. Parameters
  1594.    If OnOrOff is TRUE (the default), automatic database selection
  1595. according to the active window takes place whenever a vxBase function
  1596. that accesses a database is called. If FALSE, the last selection is used
  1597. without regard to window or task.
  1598.  
  1599. Returns
  1600.    Nothing.
  1601.  
  1602. Usage
  1603.    Used within Visual Basic sub functions where code attached to a
  1604. particular form does not come into play. Turning the auto select off
  1605. ensures there will be no incorrect selection going on that the
  1606. programmer is not aware of. Care must be taken when using this function
  1607. because, if the programmer allows the user to open a number of windows
  1608. each accessing a different database, the selection process may become
  1609. totally unhinged.
  1610.  
  1611.    vxSetSelect(FALSE) is normally used by C programmers writing DLLs or
  1612. VBXs which use vxBase calls. In a DLL, there is commonly no window that
  1613. can act as controller and even if there were, the programmer knows
  1614. exactly what database he is using and can reselect at every opportunity
  1615. to ensure the correct data comes into play.
  1616.  
  1617. Example
  1618.    ' sub function that does not interfere
  1619.    ' with auto selection of database in
  1620.    ' main line
  1621.    ' ------------------------------------
  1622.    Sub GetMasterNum()
  1623.       Call vxSetSelect(FALSE)
  1624.       PrevDbf% = vxSelectDbf(MasterDbf)
  1625.       MasterNum = vxInteger("masternum")
  1626.       Call vxSetSelect(TRUE)
  1627.       j% = vxSelectDbf(PrevDbf%)
  1628.    End Sub
  1629.  
  1630. See Also
  1631.    vxSelectDbf
  1632.  
  1633.  
  1634. vxUseDbfAgain
  1635. -------------
  1636. Declaration:
  1637.    Declare Function vxUseDbfAgain lib "vxbase.dll" (ByVal DbfName
  1638. As String) As Integer
  1639.  
  1640. Purpose:
  1641.    Opens a database that has already been opened IN ANOTHER AREA.
  1642. Any indexes attached to this database with vxUseNtx are also opened
  1643. in areas separate from any other instances of the same files.
  1644.  
  1645. See Also:
  1646.    vxUseDbf
  1647.  
  1648.      
  1649. vxUseDbfEX
  1650. ----------
  1651.    Declare Function vxUseDbfEX lib "vxbase.dll" (ByVal DbfName
  1652. As String) As Integer
  1653.  
  1654. Purpose:
  1655.    Opens a database for EXCLUSIVE use. If any other user or
  1656. task is currently using the database, this function will
  1657. fail (zero is returned as the select area).
  1658.  
  1659. See Also:
  1660.    vxUseDbf
  1661.  
  1662.  
  1663. IMPORTANT NOTES TO EXISTING VXBASE USERS:
  1664. -----------------------------------------
  1665.    (1) If your application uses DESCENDing indexs and your current vxBase
  1666.        release is less than 2.08, these indexes MUST BE RECREATED after
  1667.        installing this release. The descending key algorithm has been
  1668.        changed to make vxBase descending keys compatible with CLIPPER
  1669.        descending keys.
  1670.  
  1671.        DO NOT USE DATAWORKS to recreate the indexes. It still uses the
  1672.        old algorithm. DataWorks is in the process of update.
  1673.        Use the vxReindex or vxCreateNtx functions to recreate the indexes.
  1674.   
  1675.    (2) See the VXLOAD.EXE discussion below.
  1676.  
  1677. Prerequisites
  1678. -------------
  1679.    vxBase is a dynamic link library of xBase functions that has been
  1680. customized for use with Microsoft Visual Basic. You must have 
  1681. Visual Basic in order to run the VB sample application. 
  1682.    If you are intending to use vxBase with another language (such as 
  1683. C), create the directory \VB before beginning installation of vxBase.
  1684.    The default installation directory is \VB, which is where
  1685. Visual Basic is normally set up. The directory that vxBase is
  1686. installed into MUST exist. If \VB does not exist, or if you wish
  1687. to install vxBase into another directory, ensure that it exists
  1688. prior to installation.
  1689.  
  1690. vxBase Installation
  1691. -------------------
  1692.    If INSTALL.EXE is resident on this diskette, use the
  1693.    program manager RUN command A:INSTALL to install
  1694.    vxBase. If changing the default directory from \VB,
  1695.    the directory being changed to MUST exist.
  1696.  
  1697.    A second sample application (project vxbtut) has been
  1698.    included starting with release 2.05 that shows you how
  1699.    to maintain a single database using vxCtlBrowse as the
  1700.    primary user interface to the database. It is installed
  1701.    in directory \vb\vxbtest along with the vxbtest project.
  1702.  
  1703.  
  1704. ZIP version
  1705. -----------
  1706.     vxBase is distributed on a single diskette or on bulletin boards
  1707. as two compressed .ZIP files. The first ZIP file is vxbdoc.zip, which
  1708. contains the documentation in a Windows Write file. This file is
  1709. essential to understanding and using vxBase. If it is missing, contact
  1710. the author at the address below.  The documentation is separated from
  1711. the rest of vxBase to allow potential users to preview it before
  1712. installing and actually using vxBase. This is especially helpful to
  1713. potential users who extract vxBase from a bulletin board. They can
  1714. evaluate the system from a documentation standpoint before committing to
  1715. downloading the larger system.
  1716.  
  1717.     Unzip vxbdoc.zip and view or print it. The manual is more than
  1718. 250 pages long. It was formatted for an Epson 24-pin printer using
  1719. standard Courier fonts. Printed manuals may be obtained for $20.00.
  1720. See the end of the documentation for ordering information.
  1721.  
  1722.     The second ZIP file (vxbase.zip) contains the sample source code
  1723. and Visual Basic project files, vxbase.txt which includes all of the Visual
  1724. Basic declarations for the routines in the vxBase DLL, the vxBase DLL
  1725. itself, and VXLOAD.EXE - a Visual Basic Design Mode Utility.
  1726.  
  1727.     If you are going to upload vxBase to a bulletin board, it must be
  1728. sent as it was received - in two ZIP files.
  1729.  
  1730.     When the system ZIP file is decompressed, it contains this readme.doc
  1731. file and 3 more ZIP files. These ZIP files are:
  1732.  
  1733.     vxbdll.zip    the vxBase DLL and vxload.exe
  1734.     vxbtest.zip    sample source code and vxbase.txt
  1735.         vxbezy.zip      single database sample app using vxCtlBrowse
  1736.                         (project vxbtut)
  1737.  
  1738.     To install vxBase, first make a subdirectory under your \vb
  1739. directory named \vb\vxbtest and copy the vxbtest.zip and vxbezy.zip files
  1740. there. Unzip them and delete the zip files from your hard disk. To run the
  1741. sample applications it is essential that these files be in directory \vb\vxbtest
  1742. because this path is hard-coded into the sample code. If you MUST put them
  1743. somewhere else, you'll have to modify the file names in the source code to
  1744. reflect your location.
  1745.  
  1746.     Unzip vxbdll.zip and place the resulting files (VXBASE.DLL and VXLOAD.EXE)
  1747. in your \windows directory.
  1748.  
  1749.     To run the sample program, see the Sample Application section in the
  1750. manual. Remember to run vxload.exe before starting Visual Basic. 
  1751.  
  1752.  
  1753. VISUAL BASIC 2.0 And the Sample Applications
  1754. --------------------------------------------
  1755.     Visual Basic 2.0 or better is REQUIRED to run the sample
  1756. applications.        
  1757.  
  1758.  
  1759. Better Memory Management in Design Mode with VXLOAD.EXE
  1760. -------------------------------------------------------
  1761. NOTE: vxload.exe included with vxbase is a utility that simply
  1762.       loads vxbase.dll and runs in an iconized state. It is
  1763.       highly recommended that you run this program immediately 
  1764.       PRIOR to calling up Visual Basic in Design Mode. vxload
  1765.       controls the vxbase memory. Any crashes when testing a vxbase
  1766.       program in design mode will not affect the vxbase memory pool
  1767.       at all if vxload is running. Copy vxload.exe to your \windows
  1768.       directory and set it up as a group item next to your VB icon. 
  1769.  
  1770.       It is also suggested that you add the following two lines of
  1771.       code to your initialization procedure (somewhere after the call
  1772.       to vxInit()):
  1773.  
  1774.       Call vxSetLocks(FALSE)
  1775.       j% = vxCloseAll()
  1776.  
  1777.       vxSetLocks is described in the namual.
  1778.  
  1779.       Adding these two lines to the init procedure will close any
  1780.       files that were left open as a result of a Design Mode VB
  1781.       error. vxSetLocks will ensure that any open files left over
  1782.       from a crashed VB run will not have any leftover locks on
  1783.       your second and subsequent runs of the program while in Design
  1784.       Mode - and vxCloseAll will close any leftover files so you can
  1785.       start off with a clean slate.
  1786.  
  1787.       If you wish to use the default locking scheme in your finished
  1788.       .EXE, remove the vxSetLocks(FALSE) that you set up for design mode
  1789.       testing before compiling (and the vxCloseAll as well although
  1790.       that is not critical).
  1791.  
  1792.       If your vxBase program terminates abnormally (or you use the VB End
  1793.       menu item to terminate), and then you exit Visual Basic, an 
  1794.       attempt to close VXLOAD.EXE from the system menu that appears
  1795.       when you click on its icon will result in a "Task Sequence Closure
  1796.       Error". This is because your vxBase Visual Basic program never
  1797.       called vxDeallocate, which removes Visual Basic from the vxBase 
  1798.       task list being maintained by VXLOAD. If this happens to you,
  1799.       simply double click the VXLOAD icon to bring the VXLOAD window
  1800.       into view and select the EXIT menu item. Closing VXLOAD in this
  1801.       fashion ignores the task list.
  1802.  
  1803. Changes to vxBase version 2.xx
  1804. ------------------------------
  1805.   (1) vxBrowseSetup corrected to display user menus if system menus
  1806.       disabled.
  1807.  
  1808.   (2) vxCtlStyle corrected to handle new Visual Basic 2.0 "graphical
  1809.       objects" (e.g., labels).
  1810.  
  1811.   (3) all SETTINGS cited as System Wide in the current documentation are
  1812.       now local to the vxBase task. These settings include the following:
  1813.           vxCtlPenWidth
  1814.           vxSetAnsi
  1815.           vxSetCollate/vxCollate collating table
  1816.           vxSetDate
  1817.           vxSetErrorCaption
  1818.           vxSetErrorMethod
  1819.           vxSetLanguage
  1820.           vxSetLocks
  1821.           vxSetMeters
  1822.           vxSetString
  1823.  
  1824.        If more than one vxBase task is running at the same time, the
  1825.        items set by the functions above are now local to each concurrent
  1826.        task (e.g., vxBase in French and in English can be run on the same
  1827.        machine at the same time).
  1828.  
  1829.    (4) inconsistent index file lockup in multiuser mode when vxSeek
  1830.        fails corrected.
  1831.  
  1832.    (5) DESCEND and vxDescend index algorithms changed to use 2s complement
  1833.        instead of 1s complement arithmetic to convert defined descending
  1834.        keys into the correct sequence. This makes the vxBase DESCEND
  1835.        index compatible with CLIPPER.
  1836.  
  1837.    (9) memo soft returns from Clipper apps are now properly stripped on
  1838.        European memos when vxSetAnsi is FALSE.
  1839.  
  1840.   (10) vxBrowse and vxCtlBrowse quick key displays and vertical scrolling
  1841.        speeds have been increased by a factor of 2 to 3.
  1842.  
  1843.   (11) memory leaks created by VB 2.0 string creation corrected by using
  1844.        new function to create Visual Basic strings if version is 2.0 or
  1845.        greater.
  1846.  
  1847.   (12) Max memo size now increased to 64k (was 32k).
  1848.  
  1849.   (13) memo reading procedures changed to read 4k blocks instead of 64k file
  1850.        chunks. This should speed memo reads and packs with memo files
  1851.        considerably.
  1852.  
  1853.   (14) vxAppendFrom now appends memos and bitmaps. Restriction removed.
  1854.  
  1855.   (15) vxGo() passed with a zero record number now returns FALSE instead
  1856.        of crashing.
  1857.  
  1858.   (16) vxTop now properly returns FALSE if empty file.
  1859.  
  1860.   (17) dbf files opened as Read Only with vxUseDbfRO no longer have their
  1861.        index files locked when positioning to a specific record.
  1862.  
  1863.   (18) more elegant on screen edit within a vxBrowse or vxCtlBrowse table.
  1864.        The use may accept the edit by pressing the ENTER key or cancel the
  1865.        edit by pressing ESC.
  1866.  
  1867.   (19) initial memory allocation requirements reduced and memory increase
  1868.        requests changed to leave new memory object attached to original
  1869.        calling task.
  1870.  
  1871.   (20) Dutch language support added.
  1872.  
  1873.  
  1874.  
  1875. Terry Orletsky
  1876. vxBase Systems
  1877. #488, 9707 - 110 Street
  1878. Edmonton, Alberta, Canada
  1879. T5K 2L9
  1880. Phone (403) 488-8100
  1881. Fax   (403) 486-8150
  1882. BBS   (403) 488-8365 up to 14400 bps v.32bis 8N1
  1883. Compuserve I.D. 70524,3723
  1884. 
  1885.