home *** CD-ROM | disk | FTP | other *** search
/ Shareware Supreme Volume 6 #1 / swsii.zip / swsii / 201 / BCC101.ZIP / BCC101.NWS < prev    next >
Text File  |  1993-04-20  |  98KB  |  2,343 lines

  1.      Volume  1, Number  1                                    April 20, 1993
  2.  
  3.      
  4.      
  5.      
  6.      
  7.      
  8.      
  9.      
  10.      
  11.      
  12.      
  13.      
  14.      
  15.                    **************************************************
  16.                    *                                                *
  17.                    *             The BASIC Code Cache               *
  18.                    *                                                *
  19.                    *         International BASIC Electronic         *
  20.                    *                  Newsletter                     *
  21.                    *                                                *
  22.                    *       Dedicated to promoting BASIC around      *
  23.                    *                  the world                     *
  24.                    *                                                *
  25.                    **************************************************
  26.      
  27.      
  28.      
  29.      
  30.      
  31.      
  32.      
  33.      
  34.      
  35.      
  36.      
  37.      
  38.      
  39.      
  40.      
  41.      
  42.      The   BASIC  Code  Cache  is  an  electronic  newsletter  published by
  43.      Communication  Techniques.   The  BASIC  Code  Cache  may  be   freely
  44.      distributed  provided NO CHARGE is charged for distribution. The BASIC
  45.      Code Cache  is  copyrighted  in full  by Communication Techniques  and
  46.      republication of any material contained in The BASIC Code Cache is the
  47.      prohibited  without the  consent of  Communication  Techniques or  the
  48.      author of the material. The BASIC Code Cache must be distributed whole
  49.      and unmodified.
  50.      You can write The BASIC Code Cache at:
  51.      
  52.           The BASIC Code Cache
  53.           P.O. Box 507
  54.           Sandy Hook, CT 06482
  55.      
  56.      Copyright (c) 1993 by Communication Techniques.
  57.      
  58.      The BASIC Code Cache                                         Page    i
  59.      Volume  1, Number  1                                    April 20, 1993
  60.  
  61.      
  62.  
  63.      ----------------------------------------------------------------------
  64.  
  65.                         T A B L E   O F   C O N T E N T S
  66.  
  67.      
  68.      1.  From The Editor
  69.           Welcome to The BASIC Code Cache ..............................  1
  70.           Subscribing to The BASIC Code Cache ..........................  3
  71.  
  72.      2.  COMMON SHARED
  73.           A Hexidecimal Primer by Earl Montgomery ......................  4
  74.           Learning Assembler by Brian Mclaughlin .......................  6
  75.  
  76.      3.  Quick BASIC/PDS
  77.           Detecting if Windows is Running by John Riherd ...............  7
  78.           A Fast Windowed Print Library by Brian Mclaughlin ............  9
  79.           Power Menus, Prompts and Messages By Larry Stone ............. 12
  80.           A Quick Method of Changing Colors by Lee Herron .............. 15
  81.  
  82.      4.  PowerBASIC
  83.           PowerBASIC 3.0 Adds Power to BASIC by Bruce Tonkin ........... 17
  84.           Getting Netware Connection Information by Lewis Balentine .... 20
  85.  
  86.      5.  Visual Basic
  87.           SpyWorks-VB from Desaware .................................... 27
  88.           Tom Hanlin Checks in with PBClone for VB ..................... 29
  89.  
  90.      6.  Access Basic
  91.           Creating Custom Wizards with Access Basic .................... 31
  92.  
  93.      7.  The Bug List
  94.           Buglist for Microsoft Visual Basic ........................... 36
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.      The BASIC Code Cache                                         Page   ii
  139.      Volume  1, Number  1                                    April 20, 1993
  140.  
  141.  
  142.  
  143.      ----------------------------------------------------------------------
  144.                           F r o m   T h e   E d i t o r
  145.      ----------------------------------------------------------------------
  146.  
  147.      Welcome to The BASIC Code Cache 
  148.      
  149.      Welcome to the premiere issue of The BASIC Code Cache. For those of
  150.      you familiar with The QBNews, you can think of this as version 2.0 of
  151.      that. When The QBNews first started out, Microsoft QuickBASIC and PDS
  152.      were the king of the hill. However, during the three years that The
  153.      QBNews was published, the state of BASIC programming has changed
  154.      radically.
  155.      
  156.      Microsoft Visual Basic for Windows landed on the scene a short while
  157.      ago and took the Windows development market by storm. Hey, any BASIC
  158.      product that can get C programmers to use it must be pretty special.
  159.      Also more recently, QuickBASIC has gotten some pretty serious
  160.      competition with the release of PowerBASIC 3.0 by Spectra Publishing.
  161.      Because of these radical changes in the marketplace, The QBNews has
  162.      become The BASIC Code Cache. What this means to previous readers of
  163.      The QBNews is that we will now cover all aspects of BASIC programming
  164.      in the PC world instead of strictly QuickBASIC.
  165.      
  166.      I'm sure some of you are saying "Great, YAWR (Yet Another Windows
  167.      Rag)". I can assure you that will not be the case. DOS is still very
  168.      important out there, and with the arrival of PowerBASIC 3.0, there is
  169.      some new excitement out there too. However, just because you program
  170.      in a different environment, I hope you don't quickly dismiss the
  171.      articles and code that don't pertain to you. After all, this is BASIC
  172.      and you can probably learn something new regardless of what
  173.      environment you program for.
  174.      
  175.      For those of you who are new to The BASIC Code Cache, here comes the
  176.      part where I plead for your support to sustain this newsletter. The
  177.      BASIC Code Cache is made up strictly of contributions from its
  178.      readership. Over the course of The QBNews, many programmers have
  179.      contributed a ton of programming knowledge and has made The QBNews an
  180.      encyclopedia of information on programming in QuickBASIC. Many times
  181.      if you have a question on how to do something in QuickBASIC, you can
  182.      find the answer in The QBnews. Now that we have expanded the scope of
  183.      BASIC programming in The BASIC Code Cache, I'm sure there is a wealth
  184.      of programming knowledge out there that can be shared. There are three
  185.      ways to support The BASIC Code Cache.
  186.      
  187.      1. Submit well commented code - Part of the problem I had with
  188.      sustaining The QBNews was not a lack of code, but rather a requirement
  189.      I had about including an article. No more with The BASIC Code Cache.
  190.      If you have some interesting code you would like to contribute, but
  191.      are worried about your writing skills, we will gladly except well
  192.      commented code. For your troubles you will receive the disk based
  193.      version of The BASIC Code Cache your code appears in.
  194.      
  195.      2. Submit an article - One of the biggest requests I got was from
  196.      beginners who wanted more information tailored for beginners. This was
  197.      
  198.      The BASIC Code Cache                                           Page  1
  199.      Volume  1, Number  1                                    April 20, 1993
  200.  
  201.      always hard to come by because advanced users may not know what stuff
  202.      beginners are interested in learning. What may be common knowledge to
  203.      an advanced user may be the answer to a problem for a beginner. So, if
  204.      you are a beginner and you learn something new that you didn't know
  205.      about, write it up and share it with other beginners. After all, if it
  206.      wasn't common knowledge to you, it probably isn't common knowledge to
  207.      everybody else either. You will also receive the disk based version of
  208.      The BASIC Code Cache for your troubles.
  209.      
  210.      3. Subscribe to The BASIC Code Cache - The BASIC Code Cache offers
  211.      disk subscriptions for those who are interested. By subscribing, you
  212.      also get some bonus goodies not available in the electronic version.
  213.      For instance, the disk based edition of this issue includes a working
  214.      demo version of PowerBASIC 3.0, a demo of SpyWorks VB, and a full
  215.      version of Tom Hanlin's entry into the VB shareware market PBCWIN. The
  216.      cost of downloading these from Compuserve or long distance will more
  217.      than cover the cost of the subscription, and you will also be
  218.      supporting the continuation of The BASIC Code Cache to boot. Detailed
  219.      info on subscribing follows this section.
  220.      
  221.      If the rest of the BASIC community supports The BASIC Code Cache like
  222.      QuickBASIC programmers supported The QBNews, we can look forward to
  223.      many years of outstanding contributions of BASIC knowledge being
  224.      spread around, making everybody better BASIC programmers. I look
  225.      forward to your comments, contributions, and criticisms and can be
  226.      reached at the addresses below.
  227.      
  228.      US Mail:    The BASIC Code Cache
  229.                  P.O. Box 507
  230.                  Sandy Hook, CT 06482
  231.      
  232.      Compuserve: 76510,1725
  233.      
  234.      Fidonet:    1:141/777
  235.      
  236.      Prodigy:    HSRW18A
  237.      
  238.      Internet:   dave.cleary@f777.n141.z1.fidonet.org
  239.      
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.      The BASIC Code Cache                                           Page  2
  256.      Volume  1, Number  1                                    April 20, 1993
  257.  
  258.      Subscribing to The BASIC Code Cache
  259.       
  260.      Show you support of The BASIC Code Cache by subscribing. The disk
  261.      based version of The BASIC Code Cache contains extra goodies not
  262.      available in the electronic version. It will come to you on two 360k
  263.      floppy disks or one 720k floppy disk. Extras include demos of
  264.      commercial software reviewed, the latest shareware for BASIC plus much
  265.      more. It costs only $24 for a one year subscription.
  266.      
  267.      Name ____________________________________
  268.      
  269.      Company _________________________________
  270.      
  271.      Address _________________________________
  272.      
  273.      City ____________ State _____ Zip _______
  274.      
  275.      ___ 360k     ___ 720k
  276.      
  277.      Orders outside of the United States please add $10 shipping and
  278.      handling.
  279.      
  280.      
  281.      SPECIAL OFFER FOR THE QBNEWS!!!!
  282.      
  283.      For a limited time, you can receive the entire three disk collection
  284.      of The QBNews for just $10. That is twelve issues in all of the best
  285.      BASIC has to offer. Almost every topic of programming with QuickBASIC
  286.      is touched upon and is an invaluable reference for any programmer.
  287.      
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.      The BASIC Code Cache                                           Page  3
  313.      Volume  1, Number  1                                    April 20, 1993
  314.  
  315.  
  316.  
  317.      ----------------------------------------------------------------------
  318.                             C O M M O N   S H A R E D
  319.      ----------------------------------------------------------------------
  320.  
  321.      A Hexidecimal Primer by Earl Montgomery
  322.      
  323.      While refreshing my memory on Hexadecimal and Binary notations
  324.      (and the use of the logical operators <AND> <OR>, I found that
  325.      it helped to take notes. This is a compilation of those notes.
  326.      Some phrasing is entirely my own. So if you find any mistakes
  327.      (other than grammar, sentence structure, or spelling! <smile>)
  328.      please inform me so I can correct my document file. This
  329.      document should prove useful to the new programmers.
  330.      
  331.                           A little info on Hexadecimal notation.
  332.                           
  333.      Hexadecimal is a numbering system based on 16 elements.
  334.      Digits are numbered 0 through F as follows:
  335.      
  336.      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
  337.      
  338.      Representing the digits 0 through 15.
  339.      
  340.      Hexadecimal system uses powers of 16. For example:
  341.      &H19 (hexadecimal) represents 25 decimal. Let's see why.
  342.      Starting from the right the power is 1. Therefore 9 X 1 = 9
  343.      Moving left the next is power is 16. Therefore 1 X 16 = 16
  344.      And 9 + 16 = 25.
  345.      
  346.      Let's try another. This time &HFF (hexadecimal)
  347.      Again starting from the right (F=15) 15 X 1= 15
  348.      Moving left 15 X 16 = 240.
  349.      And 240 + 15 = 255
  350.      
  351.      So far we have looked at single byte hex values. Let's look at
  352.      a 16 bit hex value. Remember 8 bits to the byte? Now we look at
  353.      two adjoining bytes, or sixteen bits.
  354.      &H1902 (hexadecimal) represents 6402 decimal.
  355.      Again starting from the right 2 X 1= 2
  356.      Moving left 0 X 16 = 0
  357.      Moving left again <16 X 16 =256> 9 X 256 = 2304
  358.      Moving left again <16 X 256 = 4096> 1 X 4096 = 4096
  359.      And 2 + 0 + 2304 + 4096 = 6402
  360.      
  361.      In basic hex values are preceeded by &H. For example &HFF or &H1902.
  362.      In basic the decimal value of a hexadecimal number can be determined
  363.      by the command PRINT &H(hexadecimal number): Example PRINT &HFF.
  364.      The printed result in this case would be 255.
  365.      
  366.      Decimal to hex is accomplished by PRINT HEX$(255)
  367.      The printed result in this case would be &HFF.
  368.      
  369.      Now let's look at the individual bits within a byte.
  370.      Remember there are 8 bits to the byte and reading from Right
  371.      
  372.      The BASIC Code Cache                                           Page  4
  373.      Volume  1, Number  1                                    April 20, 1993
  374.  
  375.      to Left they increase in power by the power of 2.
  376.      Binary notation reflects set bits with a 1. Non set bits with a 0.
  377.      Let's look at one.
  378.      
  379.      1 0 0 0 1 0 0 1 (This byte represents 137)
  380.      
  381.      As with hex we start at the right.
  382.      1 X 1= 1
  383.      Moving left 2 X 0 = 0
  384.      Moving left again 4 X 0 = 0
  385.      Moving left again 8 X 1 = 8
  386.      Moving left again 16 X 0 = 0
  387.      Moving left again 32 X 0 = 0
  388.      Moving left again 64 X 0 = 0
  389.      Moving left again 128 X 1 = 128
  390.      And 1 + 0 + 0 + 8 + 0 + 0 + 0 + 128 = 137
  391.      
  392.                           Logical Operators <AND> <OR>
  393.                           
  394.      When you AND two numbers the results are in a new third number.
  395.      
  396.      For example:
  397.      a = 137
  398.      b = 105
  399.      c = a AND b
  400.      1 0 0 0 1 0 0 1  This represents A <137>
  401.      0 1 1 0 1 0 0 1  This represents B <105>
  402.      0 0 0 0 1 0 0 1  This represents C <9>
  403.      
  404.      What occurs when you AND two numbers is that the computer compares
  405.      the bits within the first number against the bits in the second
  406.      number. If the bits are the same then they will remain the same in
  407.      the third number. If they are not the same then the equivalent
  408.      bits will be 0 in the third number.
  409.      
  410.                                     Logical OR
  411.                                     
  412.      What occurs when you OR two numbers is that the computer compares
  413.      the bits within the first number against the bits in the second number.
  414.      If the bits are the same they will remain the same in the third number.
  415.      If they are not the same then the bits will be 1 in the third number.
  416.      
  417.      For example:
  418.      A=122
  419.      B=15
  420.      C=A OR B
  421.      0 1 1 1 1 0 1 0   This represents A <122>
  422.      0 0 0 0 1 1 1 1   This represents B <15>
  423.      0 1 1 1 1 1 1 1   This represents C <127>
  424.      
  425.      This quick little reference document composed by Earl Montgomery
  426.      I hope it proves to be of some use to you.
  427.      
  428.  
  429.      The BASIC Code Cache                                           Page  5
  430.      Volume  1, Number  1                                    April 20, 1993
  431.  
  432.      Learning Assembler by Brian Mclaughlin
  433.      
  434.      My first suggestion if you want to learn to write ASM routines for
  435.      BASIC is to get some good reference material. The best tutorial
  436.      available can be found in the last 100 pages of "BASIC Techniques and
  437.      Utilities" by Ethan Winer. It's aimed directly at those who know BASIC
  438.      already and want to learn assembly language. The book costs $30, and
  439.      even if you never get the hang of assembler, you'll get your money's
  440.      worth from the rest of the book.
  441.      
  442.      Next, get a good reference on DOS/BIOS interrupts. I have heard
  443.      excellent things about the interrupt list put out by Ralf Brown, and
  444.      available on many BBSes. I use QUE's "DOS Programmer's Reference" and
  445.      can also recommend it.
  446.      
  447.      Don't forget the manual/quick reference guide that comes with your
  448.      assembler. When I get error messages, this is where I turn.
  449.      
  450.      Last, once you have a bit of success and are eager for more I suggest
  451.      you register for one of the shareware libraries that offers source
  452.      code to registered users. Having some code that works(!) which you can
  453.      look at is a great way to learn, IMHO. Until then, you can look at
  454.      XPRINT.ASM. :->
  455.      
  456.      If you get discouraged, take heart; a year ago I couldn't write a
  457.      five-line procedure in ASM without an error message!
  458.      
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.      The BASIC Code Cache                                           Page  6
  487.      Volume  1, Number  1                                    April 20, 1993
  488.  
  489.  
  490.  
  491.      ----------------------------------------------------------------------
  492.                           Q u i c k   B A S I C / P D S
  493.      ----------------------------------------------------------------------
  494.  
  495.      Detecting if Windows is Running by John Riherd
  496.      
  497.      Sometimes you just need to know if your program is running in a DOS
  498.      box under Windows. This code will not only tell you this, but will
  499.      also tell you what version and what mode Windows is operating in.
  500.      CHECKWIN.BAS can be found in the file QBCODE.ZIP.
  501.      
  502.      '*********************************************************************
  503.      '*                         CHEKWIN.BAS                               *
  504.      '*                                                                   *
  505.      '*   This program will determine whether Windows is running and, if  *
  506.      '*   so, its operating mode.                                         *
  507.      '*   QuickBASIC must be loaded, as follows: QB /L QB                 *
  508.      '*   Copyright 1993 by John Riherd                                   *
  509.      '*********************************************************************
  510.      DEFINT A-Z 
  511.      DECLARE FUNCTION ChekWindows% (Ver1 AS INTEGER, Ver2 AS INTEGER)
  512.      
  513.      '$INCLUDE: 'Qb.bi'           'Include file for interrupt calls
  514.      
  515.      CONST MULTIPLEX = &H2F       'multiplex interrupt number
  516.      CONST NOWIN = &H0            'Return for no Windows
  517.      CONST WIN386 = &H1           'Return for Windows-386 V2.?
  518.      CONST REAL = &H81            'Return for Windows in real mode
  519.      CONST STANDARD = &H82        'Return for Windows in standard mode
  520.      CONST ENHANCED = &H83        'Return fo Windows in enhanced mode
  521.      
  522.      DIM WellIsIt AS INTEGER
  523.      DIM Ver1 AS INTEGER           'Primary version number
  524.      DIM Ver2 AS INTEGER           'Secondary version number
  525.        
  526.      WellIsIt = ChekWindows%(Ver1, Ver2)   'Do the test and return values
  527.      SELECT CASE WellIsIt
  528.        CASE NOWIN
  529.          PRINT "Windows is not running"
  530.        CASE WIN386
  531.          PRINT "Windows-386 V 2.? is running"
  532.        CASE REAL
  533.          PRINT "Windows is running in real mode"
  534.        CASE STANDARD
  535.          PRINT "Windows is running in standard mode"
  536.        CASE ENHANCED
  537.          PRINT "Windows Vers. "; LTRIM$(STR$(Ver1)); ".";
  538.          PRINT LTRIM$(STR$(Ver2)); " is running in enhanced mode"
  539.      END SELECT
  540.       
  541.      FUNCTION ChekWindows% (Ver1 AS INTEGER, Ver2 AS INTEGER)
  542.                                                                                      
  543.      
  544.      DIM Regs AS RegTypeX         'Processor registers for interrupt call
  545.      
  546.      The BASIC Code Cache                                           Page  7
  547.      Volume  1, Number  1                                    April 20, 1993
  548.  
  549.      DIM VBuffer AS INTEGER       'To store version number
  550.                                                                                      
  551.      
  552.      Ver1 = 0                     'Initialize version numbers
  553.      Ver2 = 0
  554.                                                                                      
  555.      
  556.      Regs.ax = &H1600             'Function number
  557.      CALL INTERRUPTX(MULTIPLEX, Regs, Regs)
  558.      
  559.      VBuffer = Regs.ax            'Set regs.AX
  560.                                                                                      
  561.      
  562.      SELECT CASE VBuffer MOD 256  'Get the low byte of AX
  563.       
  564.      CASE &H1, &HFF               'Windows-386 running
  565.          Ver1 = 2                 'Primary version
  566.          Ver2 = 0                 'Secondary version is unavailable
  567.          ChekWindows% = WIN386
  568.       
  569.      CASE &H0, &H80
  570.          Regs.ax = &H4680         'Check for real or standard mode
  571.          CALL INTERRUPTX(MULTIPLEX, Regs, Regs)
  572.          
  573.          IF (Regs.ax MOD 256) = &H80 THEN 'Check if Windows is running
  574.               ChekWindows% = NOWIN                'No
  575.          ELSE                     'Check for real or standard mode
  576.               Regs.ax = &H1605    'Set registers and function
  577.               Regs.bx = &H0
  578.               Regs.si = &H0
  579.               Regs.cx = &H0
  580.               Regs.es = &H0
  581.               Regs.ds = &H0
  582.               Regs.dx = &H1
  583.               CALL INTERRUPTX(MULTIPLEX, Regs, Regs)
  584.               
  585.               IF Regs.cx = &H0 THEN  'Check for real mode
  586.                    ChekWindows% = REAL
  587.               ELSE                   'Windows in standard mode
  588.                    ChekWindows% = STANDARD
  589.               END IF
  590.          END IF
  591.       
  592.      CASE ELSE
  593.          Ver1 = VBuffer AND &HF   'Get the low byte for primary version
  594.          Ver2 = VBuffer \ 256     'Get the high byte for second. version
  595.          ChekWindows% = ENHANCED
  596.      END SELECT
  597.                                                                                      
  598.      
  599.      END FUNCTION
  600.      
  601.  
  602.  
  603.      The BASIC Code Cache                                           Page  8
  604.      Volume  1, Number  1                                    April 20, 1993
  605.  
  606.      A Fast Windowed Print Library by Brian Mclaughlin
  607.      
  608.      Here is some assembly language code I've been toying with for a while
  609.      -- a set of fast-printing routines for QuickBASIC 4.x (and P.D.Q.). I
  610.      wrote these because at the time, P.D.Q. did not support VIEW PRINT,
  611.      and by design, outputs all text through DOS instead of printing them
  612.      directly to video memory. 
  613.      
  614.      My answer was to write a group of assembler routines that are (almost)
  615.      as easy to use as regular QB. These routines do direct-to-screen
  616.      writing, update the cursor, scroll automatically, allow you to set or
  617.      change the default colors, and let you set a VIEW PRINT window with
  618.      parameters for width as well as height. They require almost exactly
  619.      the same parameters as their QB counterparts (they almost have the
  620.      same names, even!) and in many programs they will result in a smaller
  621.      EXE than if you used QB's display commands.  Admittedly, they will
  622.      make for a bigger EXE than straight P.D.Q., but the price is fairly
  623.      small and the extra convenience is tremendous.
  624.      
  625.      Here's a list of the routines:
  626.      
  627.      DECLARE SUB XInit (IgnoreSnow%)
  628.      DECLARE SUB XPrint (PrintThis$, NumberOfScrolls%)
  629.      DECLARE SUB XCls ()
  630.      DECLARE SUB XColor (FG%, BG%)
  631.      DECLARE SUB XLocate (Row%, Col%)
  632.      DECLARE SUB XCursorOn (BlockOrLine%)  'non-zero value for block cursor
  633.      DECLARE SUB XCursorOff ()
  634.      DECLARE SUB XViewPort (TopRow%, LeftCol%, BotRow%, RightCol%)
  635.      DECLARE FUNCTION XCsrLin% ()
  636.      DECLARE FUNCTION XPos% ()
  637.      
  638.      These routines do have some limitations and drawbacks. They ONLY work
  639.      with near strings. Far strings will choke'em. Plus, you can't do the
  640.      equivalent of PRINT Num%, instead you must use the equivalent of PRINT
  641.      STR$(Num%). Because STR$() pulls the entire floating-point emulation
  642.      library into your EXE this can be considered a genuine drawback.
  643.      (Fortunately, there are ways to get around this one.)
  644.      
  645.      There is no support for 43/50 line mode. You can only use a 25x80
  646.      screen size. Page zero is the only display page supported. You may
  647.      change the shape of the cursor, but your only choices are a block or
  648.      an underline or turning it off altogether. There are other quirks.  I
  649.      have tried to identify every quirk, feature and point of interest
  650.      about how the routines work in the comment header for the code.
  651.      
  652.      The internal variables used by XPrint use 14 bytes in DGROUP.  The
  653.      routines all assemble into a single OBJ file, so calling even one of
  654.      them will link ALL of them into your EXE file. However, if you can
  655.      assemble the source code, you can easily remove any unneeded routines
  656.      from the source and reassemble only the routines you want or need.
  657.      
  658.      If you need capabilities not included in XPrint, use straight QB, or
  659.      better yet, add them to XPrint!
  660.      
  661.      The BASIC Code Cache                                           Page  9
  662.      Volume  1, Number  1                                    April 20, 1993
  663.  
  664.      
  665.      I have tried to design XPrint to allow the most painless possible
  666.      conversion from normal BASIC syntax. Here are some samples:
  667.      
  668.        In QB:  PRINT X$                   'print, scroll once
  669.        In XP:  XPRINT X$, 1               'same
  670.      
  671.        In QB:  PRINT X$;                  'print, don't scroll
  672.        In XP:  XPRINT X$, 0               'same
  673.      
  674.        In QB:  PRINT: PRINT: PRINT        'scroll 3 times, no printing
  675.        In XP:  XPRINT "", 3               'same
  676.      
  677.        In QB:  LOCATE , B%                'old row, new column
  678.        In XP:  XLOCATE XCSRLIN%, B%       'same
  679.      
  680.        In QB:  LOCATE , , 0               'cursor off
  681.        In XP:  XCURSOROFF                 'same
  682.      
  683.      I know very well that I can't instruct the gurus here, but not
  684.      everyone is a guru. (Look at me!) And I would like to share around a
  685.      bit of what I've learned with other folks like me, who haven't been at
  686.      this so very long.  
  687.      
  688.      I did one thing in XPrint that was new to me. XPrint has multiple
  689.      procedures in one object module, some of which are NEAR for internal
  690.      use and some of which are FAR, to be called from BASIC. In the past
  691.      when I wrote something like this I dropped the BASIC option from the
  692.      .MODEL MEDIUM directive, to avoid making all procedures PUBLIC. That
  693.      stopped the possibility of accidentally CALLing a NEAR procedure from
  694.      BASIC, but it made for more work.  
  695.      
  696.      Writing XPrint I stumbled onto a way to be lazy and use the BASIC
  697.      directive with a clear conscience, even when mixing NEAR and FAR
  698.      procedures. I just used a leading "$" character in the names of all
  699.      the procedures I declared NEAR. Because such names are illegal in
  700.      BASIC, I figure this should pretty much kill the problem of
  701.      accidentally referencing a NEAR procedure.  
  702.      
  703.      I did another thing new to me. On 386s and above the MUL and DIV were
  704.      speeded up considerably, but I work and play on an XT clone with an
  705.      8088, so I always try to shift bits instead. In XPrint I finally got
  706.      around to using multiple shifts and adds to achieve what can't be had
  707.      by shifts alone. In $SetVideoOffset, I needed to multiply by 160.
  708.      First I shift-multiplied by 128, then by 32, and added. Imagine my
  709.      childish delight!  
  710.      
  711.      I almost blush to point this out, but this same technique can be used
  712.      as a fast way to multiply by ten (X*8 + X*2). I hope this tip helps
  713.      someone who hadn't heard it yet.  
  714.      
  715.      The last thing I'll mention today isn't exactly a matter of code, so
  716.      much as a matter of design. In the XInit procedure I added a way to
  717.      specify that snow-suppression be ignored on CGAs. It is my fervent
  718.      
  719.      The BASIC Code Cache                                           Page 10
  720.      Volume  1, Number  1                                    April 20, 1993
  721.  
  722.      wish that this feature will be tied in to a command line option for
  723.      end-users of the programs you write. I strongly believe in giving
  724.      end-users a chance to escape from default behavior! We programmers
  725.      don't always know best!
  726.      
  727.      The assembly language source code for XPrint and XPRINT.OBJ are
  728.      contained in the file XPRINT.ZIP. Please consult the comments section
  729.      at the head of it. When I was writing XPrint I dug out the FastPrint
  730.      routine by Christy Gemmel in the QBNews. and studied its design. I
  731.      would never have learned assembly language for QB without similar
  732.      help.  Perhaps, this will slightly repay those who have helped me.
  733.      
  734.      Lastly, feel free to contact me on the BAS_NET ASM for QB echo about
  735.      any bugs or weird behaviors you find in XPrint. I ain't poifect,
  736.      y'know. In the next issue, we will modify XPrint to work with far
  737.      strings!
  738.      
  739.  
  740.  
  741.  
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.      The BASIC Code Cache                                           Page 11
  777.      Volume  1, Number  1                                    April 20, 1993
  778.  
  779.      Power Menus, Prompts and Messages By Larry Stone
  780.      
  781.      While building a set of routines for the students of my 'C' course
  782.      (forgive me, I enjoy programming in 'C' as much as I enjoy QB), I
  783.      developed a fairly efficient routine for word-wrapping text within a
  784.      boxed frame.  Well, I was so impressed with the speed and versatility
  785.      of my creation that I immediately coded it for QB.
  786.      
  787.      The routine, BoxDialog(), has six arguments in its parameter list:
  788.      
  789.          BoxDialog Top%, BoxWidth, Border$, Msg$, MsgClr%, Shadow%
  790.      
  791.      "Top" is an integer defining the top row for the boxed display.
  792.      "BoxWidth", another integer, defines the width of the displayed box.
  793.      "Msg$" is the string of text to word-wrap inside the display box.
  794.      "MsgClr" is the color attribute for the text and box frame and,
  795.      "Shadow" is true or false for using a shadow around the box frame.
  796.      
  797.      "Border$" is a string of eight characters defining the upper-left
  798.      corner, top-side, upper-right corner, left-side, right-side, lower-
  799.      left corner, bottom-side and lower-right corner of the box,
  800.      respectively.
  801.      
  802.      BoxDialog() automatically frames, word-wraps and centers your text
  803.      using the corner and side characters as defined in Border$.  Further,
  804.      BoxDialog() knows if your monitor is in a 40 column or 80 column
  805.      display mode and centers your message accordingly.
  806.      
  807.      Also, BoxDialog() can be instructed to automatically shadow the boxed
  808.      message.  When Shadow is true, BoxDialog() makes calls to DoShadow().
  809.      
  810.      DoShadow() PEEKs into the appropriate video map at the row, col
  811.      location for the color attribute at that location.  Then DoShadow()
  812.      calculates the attribute needed for a shadow effect at that location.
  813.      Finally, DoShadow() sets that new attribute into the video map.
  814.      
  815.      BoxDialog() does not use BASIC's PRINT statement.  Instead, it makes
  816.      calls to WriteStr().  WriteStr() uses four arguments in its parameter
  817.      list:  A$, the string to write; row and col, integer location for the
  818.      displayed text; and, attr, the color attribute to use.
  819.      
  820.      Note that BoxDialog's MsgClr and WriteStr's attr arguments are color
  821.      attributes as used by DOS.  In BASIC, for an intense white foreground
  822.      and a red background, you would use the command, "COLOR 15, 4".  DOS
  823.      uses the attribute 79.  Because you may prefer to think of color in
  824.      the BASIC scheme of things, DIALOG.BAS includes the small function,
  825.      ClrAttr%.  You can use this function like any other function:
  826.      
  827.              attribute% = ClrAttr%(foreground%, background%)
  828.      
  829.      ClrAttr%() is extremely fast and efficient and does not use any float-
  830.      ing point functions (in fact, none of the DIALOG.BAS routines use the
  831.      floating point library).  ClrAttr() has one line of code:
  832.      
  833.      
  834.      The BASIC Code Cache                                           Page 12
  835.      Volume  1, Number  1                                    April 20, 1993
  836.  
  837.          ClrAttr% = (fg AND 15) OR (16 * bg - (128 * (fg > 15)))
  838.      
  839.      The code above does not perform any multiplication.  The instructions
  840.      16 * bg and 128 * (fg...) use even multiples of 2.  As, consequence,
  841.      the BASIC compiler compiles this statement as a speedy shift left 4
  842.      and shift left 7 instruction.  The instruction (fg > 15) is a Boolean
  843.      test that evaluates as either -1 (true) or 0 (false).
  844.      
  845.      The heart of all of these routines is VidInfo().  VidInfo uses QB's
  846.      INTERRUPT routine.  The AX register is set to &HF00 and the interrupt
  847.      used is &H10.  This is a query to extract the current video mode from
  848.      the ROM BIOS.  Armed with this information, VidInfo() determines your
  849.      systems current video map address via a SELECT CASE Vmode.  Next, this
  850.      routine PEEKs into low memory to find out how many rows and columns
  851.      you system is currently set for.
  852.      
  853.      You might want to add two more pieces of information to the CASEs -
  854.      the memory required to save a screen and whether the particular screen
  855.      is interleaved or not.  In any case, VidInfo() passes four pieces of
  856.      information via a COMMON SHARED block named, /VInfo/.  This means that
  857.      whenever you make a call to VidInfo(), Vmode%, VidSeg%, MonRows% and
  858.      MonCols% are immediately known to all of the routines in DIALOG.BAS,
  859.      as well as, any other modules that '#INCLUDE: 'DIALOG.BI'.
  860.      
  861.      BoxDialog(), DoShadow() and WriteStr() will automatically initialize
  862.      with a call to VidInfo() if you haven't already made this call.  This
  863.      is because these routines need to know, at minimum, the number or
  864.      columns used by your monitor.  WriteStr(), for example, has the code:
  865.      
  866.                offset = MonCols * 2 * (row - 1) + col * 2 - 2
  867.      
  868.      Speaking of WriteStr(), if you are using QBX or compiling with BC7
  869.      using far strings then this routine won't work as written.  You need
  870.      to use SSEG in lieu of VARSEG.  Also, although the routine will not
  871.      be fast within the QB environment, compiled, it's lightning.  In fact,
  872.      compiled and run on an older CGA system will guarantee snow.  This is
  873.      because WriteStr() does not pause for the monitor's retrace.
  874.      
  875.      I could ramble on and on about every nuance of the code but the code
  876.      is rather well commented and speaks for itself.  So, the best thing to
  877.      say is compile it into an exe file and run it - the test driver should
  878.      give you plenty of ideas on how to use it.
  879.      
  880.      To compile ->  BC dialog /o;
  881.                     BC testdlog /o;
  882.      
  883.      To link    -> LINK /e testdlog + dialog, , nul, qb;
  884.      
  885.      Now type, "testdlog" to see the action.
  886.      
  887.      Two things you could do to enhance BoxDialog().  One would be an
  888.      additional argument to force a upper-left column location.  This would
  889.      allow you to use BoxDialog() for pull-down menus (at present, you can
  890.      us it for menus but the menu is always centered on the screen).
  891.      
  892.      The BASIC Code Cache                                           Page 13
  893.      Volume  1, Number  1                                    April 20, 1993
  894.  
  895.      
  896.      The other thing you could do to enhance BoxDialog() is the inclusion
  897.      of another argument to allow the text to have a different color than
  898.      the box frame.
  899.      
  900.      ======================================================================
  901.      Larry Stone is the author of ORCA Pacific Software's file manager  and
  902.      archive handler, "Professional SERVICES 4.0".  He has produced several
  903.      shareware products including the "LS-1.00 Plus Scientific Calculator",
  904.      initially released with The QBNews volume 1, issue 4.    Larry is also
  905.      a consulting programmer and an  adjunct professor  teaching  beginning
  906.      QuickBASIC and 'C'.  He is also a frequent contributor to  The QBNews.
  907.      He can be contacted in care of this newsletter or in care of  The ORCA
  908.      Pacific BBS 1(503)888-6050.
  909.      ======================================================================
  910.      
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931.  
  932.  
  933.  
  934.  
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943.  
  944.  
  945.  
  946.  
  947.  
  948.  
  949.      The BASIC Code Cache                                           Page 14
  950.      Volume  1, Number  1                                    April 20, 1993
  951.  
  952.      A Quick Method of Changing Colors by Lee Herron
  953.      
  954.      I had to color code about 40 pages of text for an app that needed key
  955.      words highlighted, this idea I got from a BBS software.  This code
  956.      uses high order ASCII codes to add color information to the text you
  957.      are printing. ZPRINT.BAS is contained in QBCODE.ZIP. Enjoy.
  958.      
  959.      '*********************************************************************
  960.      '* FileName: ZPrint  by  Lee Herron @ 1:3612/130 fido                *
  961.      '* Copyright 1993 by Lee Herron                                      *
  962.      '* ----------------------------------------------------------------- *
  963.      '* Description: For use in coding color into large text displays,    *
  964.      '* much quicker method of changing colors than using color ?,?       *
  965.      '* everytime. I hope you find it of some help. Hint: Don't use zPrint*
  966.      '* on every line.                                                    *
  967.      '* Origin: NightFlight BBS Pensacola,FL 16.8HST/DS (1:3612/130)      *
  968.      '*********************************************************************
  969.      DEFINT A-Z
  970.      DECLARE SUB zPrint (z$)
  971.      
  972.      ' ASCII TABLE:
  973.      '128 Ç black   '136 ê hblack
  974.      '129 ü blue    '137 ë hblue
  975.      '130 é green   '138 è hgreen
  976.      '131 â cyan    '139 ï hcyan
  977.      '132 ä red     '140 î hred
  978.      '133 à magenta '141  hmagenta
  979.      '134 å brown   '142 Ä hbrown
  980.      '135 ç white   '143 Å hwhite
  981.      
  982.      CLS
  983.      LOCATE 11, 6
  984.      zPrint "éÇThis is a sample string using èÇ<ÄÇZPrintèÇ>éÇ to "
  985.      PRINT "Highlight specific words!"      ' see Hint !
  986.      
  987.      SUB zPrint (z$) STATIC
  988.      
  989.      y = CSRLIN: x = POS(0): cflag = 0
  990.      
  991.      FOR z = 1 TO LEN(z$)
  992.         a = ASC(MID$(z$, z, 1)): m$ = CHR$(a)
  993.         IF a = 145 THEN
  994.            PRINT
  995.         ELSE
  996.            IF a < 128 THEN
  997.               PRINT m$;
  998.               cflag = 0
  999.            ELSE
  1000.               IF cflag THEN
  1001.                  COLOR , a - 128: cflag = 0
  1002.                  'Set background color because previous character was a color.
  1003.               ELSE
  1004.                  COLOR a - 128: cflag = 1
  1005.                  'Set foreground color because prev. char was a letter.
  1006.      
  1007.      The BASIC Code Cache                                           Page 15
  1008.      Volume  1, Number  1                                    April 20, 1993
  1009.  
  1010.               END IF
  1011.            END IF
  1012.         END IF
  1013.      NEXT z
  1014.      END SUB
  1015.      
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.      The BASIC Code Cache                                           Page 16
  1065.      Volume  1, Number  1                                    April 20, 1993
  1066.  
  1067.  
  1068.  
  1069.      ----------------------------------------------------------------------
  1070.                                P o w e r B A S I C
  1071.      ----------------------------------------------------------------------
  1072.  
  1073.      PowerBASIC 3.0 Adds Power to BASIC by Bruce Tonkin
  1074.      
  1075.      Product Name:   PowerBASIC 3.0
  1076.      Available from: Spectra Publishing (408) 730-9291
  1077.                      1030 D East Duane Ave
  1078.                      Sunnyvale CA 94086
  1079.      Price:      $149 ($59 for Basic Code Cache readers until 4/30/93)
  1080.      
  1081.      PowerBASIC represents a clearly-defined and demonstrably better
  1082.      alternative in the BASIC compiler market.  It concedes nothing to
  1083.      other compilers, and extends the range of BASIC in ways that any other
  1084.      compiler vendors might envy.
  1085.      
  1086.      The envy ought to extend to the former leader, Microsoft.  That
  1087.      largest of all software businesses started as a vendor of BASIC, and
  1088.      for years has prided itself on having the best BASIC available.  For
  1089.      all those years, that pride has been justified, but no more; the new
  1090.      king is a product called PowerBASIC.  To see why this is so, we need
  1091.      to ask just two questions: What do BASIC programmers want?  What makes
  1092.      PowerBASIC so good?
  1093.      
  1094.      The answer to both questions is the same: power.  Microsoft BASIC has
  1095.      five numeric data types: integer, long integer, currency, and single
  1096.      and double precision floating-point.  PowerBASIC adds single byte
  1097.      integer, unsigned word and long integer, 8-byte (quad-word) integer,
  1098.      BCD fixed and BCD floating-point (instead of just one currency type),
  1099.      and extended-precision real (80-bit real).  While BASIC isn't made
  1100.      good or bad solely because of the number of numeric data types
  1101.      supported, more types are a definite help -- and these types have been
  1102.      on most BASIC programmers' wish lists for years.
  1103.      
  1104.      Further, the BCD types in PowerBASIC are not limited to a single
  1105.      number of decimal places; the programmer can specify (at run-time) how
  1106.      many places are desired.  Rather than be limited to four decimal
  1107.      places for all calculations (as with the currency data type),
  1108.      PowerBASIC allows you to set BCD to two decimal places for exact (to
  1109.      the penny) calculations with no need for rounding, or to any number of
  1110.      places from zero to eighteen for any particular need.  The result is
  1111.      decreased overhead in each program (no need for rounding), and
  1112.      increased flexibility.
  1113.      
  1114.      PowerBASIC also implements BCD as scaled integers, rather than the
  1115.      two-digits-per-byte "natural" method.  By using scaled integers,
  1116.      PowerBASIC's approach gives increased speed -- ordinary BCD math has a
  1117.      deserved reputation for sluggishness.
  1118.      
  1119.      PowerBASIC also supports flex strings -- strings with a fixed length,
  1120.      except that the length can be changed under program control -- and
  1121.      fundamental changes in the way programs can be created.
  1122.      
  1123.      
  1124.      The BASIC Code Cache                                           Page 17
  1125.      Volume  1, Number  1                                    April 20, 1993
  1126.  
  1127.      Consider the usual way any program is created.  There are several
  1128.      steps; design, code, test, debug, and retest.  In practice, the debug
  1129.      and retest steps are repeated indefinitely.  No one seems to want to
  1130.      mention the reason for the extended debugging and testing phases,
  1131.      perhaps because the reason is so fundamental: the number of
  1132.      expressions and branches in the code.  In other words, code complexity
  1133.      leads directly to coding errors.
  1134.      
  1135.      From that standpoint, it is clear that the fewer expressions and the
  1136.      fewer branches, the more likely a program will work correctly the
  1137.      first time, and the easier it will be to enhance.  This is the big
  1138.      reason for the popularity of toolkits, modular programming, and object
  1139.      orientation.  Sure, there are other reasons for each of those things,
  1140.      but reduced complexity is the biggest and certainly easy to defend.
  1141.      
  1142.      So, how does this apply to PowerBASIC?  Simple: PowerBASIC adds
  1143.      functions that would ordinarily be found in a toolkit or written as
  1144.      needed.  PowerBASIC adds types to make it easier and more natural to
  1145.      express more programming requirements in fewer statements, fewer
  1146.      lines, and fewer branches.  The more power in the language, the better
  1147.      for the programmer -- and the person using the applications.
  1148.      Reliability helps everyone!
  1149.      
  1150.      Some specific examples are in order.  Let's start with some of the
  1151.      array commands and functions.
  1152.      
  1153.      The Array Sort command allows the programmer to sort any type of array
  1154.      in ascending or descending order, in whole or in part.  The sort can
  1155.      simultaneously rearrange the elements in another array (a tag array).
  1156.      It's not so much that the sort command is useful; it's certainly that.
  1157.      It's even more important that it exists; it's such a generally useful
  1158.      command that it's hard to imagine going without it once you've used
  1159.      it.  Even a low-level language like C includes a sort command in its
  1160.      standard library.  No Microsoft BASIC has a sort command, however.
  1161.      
  1162.      Equivalently useful are commands like Array Scan (search any array for
  1163.      any value), Array Insert (insert a new element in an array), and Array
  1164.      Delete.  Without PowerBASIC, the programmer either must write an
  1165.      equivalent for each, or buy one.  It's not as if these commands are
  1166.      terribly complex, so there's not a lot of work involved -- but there
  1167.      is some work, and it is repeated in every program written, and those
  1168.      programs are thus larger and more likely to contain errors, and slower
  1169.      than the PowerBASIC equivalent besides.
  1170.      
  1171.      In every part of PowerBASIC, the same pattern is repeated.  Even
  1172.      mundane matters like compiling are addressed; PowerBASIC supports
  1173.      conditional compilation (making it easier to maintain separate
  1174.      versions of the same program in one source module).  PowerBASIC also
  1175.      supports metacommands that eliminates both long and complex command
  1176.      lines and lengthy and error-prone selections from cascading dialog
  1177.      boxes.  To force the compiler to create a program that will require an
  1178.      80386 processor, you would insert the metacommand $cpu 80386 at the
  1179.      start of the program, for example.  All executables can be compiled to
  1180.      stand-alone files that need nothing more than MSDOS to run.  The other
  1181.      
  1182.      The BASIC Code Cache                                           Page 18
  1183.      Volume  1, Number  1                                    April 20, 1993
  1184.  
  1185.      metacommands are also named in easily-remembered ways, making Power
  1186.      BASIC programs almost entirely self-documenting (at least potentially)!
  1187.      
  1188.      Other notable advances include an in-line assembler with a full
  1189.      knowledge of the environment (use MOV AX,X% to move the value of the
  1190.      BASIC variable X% to the AX register), TSR creation, string memory (in
  1191.      any single array or any number of arrays) up to the full amount of
  1192.      available memory -- not just 64K -- and things like block memory
  1193.      moves, MAX and MIN functions, bit functions (test, set, shift, and
  1194.      rotate), pointers, library support for arbitrary OBJ files, and minor
  1195.      niceties almost everywhere you look.
  1196.      
  1197.      Consider the INSTR function.  In any standard BASIC, INSTR returns the
  1198.      first matching position of one string within another; INSTR("ABC","C")
  1199.      will return the result 3.  PowerBASIC adds the ANY keyword for even
  1200.      more power, so the function INSTR("GFDSALK",ANY "QWERTAS") will return
  1201.      the result 4 (S is found before A).  The ANY keyword can also be used
  1202.      in commands like LTRIM, RTRIM, REPLACE, and others.  Communications
  1203.      capability extends to 115K baud and to other COM ports (to COM4, even
  1204.      all at once).  There is a MAP command which allows you to subdivide a
  1205.      flex string into separate parts, similar to a FIELD statement; in
  1206.      effect, you can define a type at run-time!  All this isn't just "neat"
  1207.      -- it's good, solid, and genuinely useful stuff.
  1208.      
  1209.      If you'd like to write TSR programs, PowerBASIC makes it easy; a
  1210.      complete TSR can take as little as five lines, and you don't need a
  1211.      third-party library -- the capability is built into PowerBASIC.
  1212.      
  1213.      In sum, PowerBASIC was designed from the ground up with a very
  1214.      different agenda than the other BASIC products.  PowerBASIC was
  1215.      written in response to BASIC users; nearly every feature that appeared
  1216.      on very many wish lists was included in PowerBASIC.  Some products
  1217.      have hidden agendas -- use them and you're buying a vision of the
  1218.      future of programming or computing that may or may not match what
  1219.      you'd like.  PowerBASIC is pragmatic; it's what you always wanted in a
  1220.      computer language, and may be far more than you ever expected to get.
  1221.      That strikes me as especially significant.  After all, don't you want
  1222.      to encourage a company that actually listens to its customers?
  1223.      
  1224.      I do.  I'm now moving all my BASIC software from the former leader to
  1225.      the new one, and that's not a step I take lightly.  After all, I've
  1226.      been using products from the other vendor since 1976, and there's a
  1227.      lot to move.  It's nice to discover that my EXE files are smaller and
  1228.      run faster, besides my source files being an average of 25% smaller!
  1229.                          Bruce W. Tonkin
  1230.                          President - T.N.T. Software
  1231.                          34069 Hainesville Road
  1232.                          Round Lake, IL  60073
  1233.      
  1234.      EDITOR'S NOTE
  1235.      Disk subscribers to The BASIC Code Cache will find TRYPB3.ZIP on disk
  1236.      number 2. This is a fully functional demonastration version of
  1237.      PowerBASIC 3.0.
  1238.      
  1239.      The BASIC Code Cache                                           Page 19
  1240.      Volume  1, Number  1                                    April 20, 1993
  1241.  
  1242.      Getting Netware Connection Information by Lewis Balentine
  1243.      
  1244.      This code provides three routines that return information on a work
  1245.      station's netware connections. It is an excellent example of what you
  1246.      can do with some of PowerBASIC's more advanced features. NET001.BAS
  1247.      can be found in the file PBCODE.ZIP.
  1248.      
  1249.      The functions are:
  1250.      
  1251.      DECLARE FUNCTION GetConnectNumber% ()
  1252.      DECLARE FUNCTION GetConnectInfo% (Con%, Reply AS ConInfoRep)
  1253.      DECLARE FUNCTION GetNode$ ()
  1254.      
  1255.      GetConnectNumber% returns the Netware Logical Connection number. This
  1256.      will tell you if you are logged into a server. GetConnectInfo%
  1257.      returns information about your connection and GetNode$ returns the
  1258.      6 byte Physical Node Address.
  1259.      
  1260.      GetNode$ takes advantage of PowerBASIC's in-line assember. It also
  1261.      calls the internal PowerBASIC routine GetStrLoc to return address
  1262.      information on a PB string. Be sure to check out the support routines
  1263.      that these functions call for more interesting code.
  1264.      
  1265.      ' This FILE: "NET001.BAS" is placed in the public domain by the author
  1266.      ' Lewis Balentine, 19 March 1993. The author specificly denies all
  1267.      'warranties, exspressed or implied, of fittness or function.
  1268.      ' ->>>> use or abuse as you see fit <<<<-
  1269.      '---------------------------------------------------------------------
  1270.      'PGN PAGE: XXX in this program remarks refers to a page in the book:
  1271.      '"Programers Guide to Netware", Charles G. Rose, (c) 1990 McGraw Hill.
  1272.      '=====================================================================
  1273.      
  1274.      $compile exe
  1275.      $debug map on
  1276.      $dim array
  1277.      
  1278.      DECLARE FUNCTION GetStrLoc&(byval AllocHandle%)' so ASM CALL can find it
  1279.      
  1280.      '---------------------------------------------------------------------
  1281.      ' Constants for use with PB3's REGS function/statement.
  1282.      %FLAGS = 0
  1283.      %AX    = 1
  1284.      %BX    = 2
  1285.      %CX    = 3
  1286.      %DX    = 4
  1287.      %SI    = 5
  1288.      %DI    = 6
  1289.      %BP    = 7
  1290.      %DS    = 8
  1291.      %ES    = 9
  1292.      
  1293.      '---------------------------------------------------------------------
  1294.      type ConInfoReq        ' Connection Information Request Buffer
  1295.          length  as word    ' (LoHi) Request buffer length (4 - 2 = 2)
  1296.      
  1297.      The BASIC Code Cache                                           Page 20
  1298.      Volume  1, Number  1                                    April 20, 1993
  1299.  
  1300.          cll     as byte    ' Set to &H16
  1301.          con     as byte    ' logical connection number
  1302.      end type
  1303.      
  1304.      type ConInfoRep        ' Connection Information Reply Buffer
  1305.          length  as word    ' (LoHi) Reply buffer length (64 - 2 = 62)
  1306.          id      as Dword   ' (HiLo) Object ID
  1307.          tipe    as word    ' (HiLo) Object Type
  1308.          nam     as string * 48  ' Object Name
  1309.          Yr      as Byte    ' Log in Year where 0 = 1980
  1310.          Mo      as Byte    '        Month      (1 to 12)
  1311.          Dy      as Byte    '        Day        (1 to 31)
  1312.          Hr      as Byte    '        Hour       (0 to 23)
  1313.          Mn      as Byte    '        Minute     (0 to 59)
  1314.          Sc      as Byte    '        Second     (0 to 59)
  1315.          Wk      as Byte    '        WeekDay where 0=Sunday
  1316.          Extra   as Byte    ' Undefined extra byte
  1317.      end type
  1318.      
  1319.      '---------------------------------------------------------------------
  1320.      ' the FourByte, TwoByte types and HiLoWord, HiLoDWord are used in the
  1321.      ' functions SwapBytesW and SwapBytesDW.
  1322.      Type FourByte
  1323.          B1 as Byte
  1324.          B2 as Byte
  1325.          B3 as Byte
  1326.          B4 as Byte
  1327.      end Type
  1328.      
  1329.      Type TwoByte
  1330.          B1 as Byte
  1331.          B2 as Byte
  1332.      end Type
  1333.      
  1334.      Union HiLoWord
  1335.          Wrd as Word
  1336.          BB  as TwoByte
  1337.      end Union
  1338.      
  1339.      Union HiLoDWord
  1340.          DW as Dword
  1341.          BB  as FourByte
  1342.      end Union
  1343.      
  1344.      '=====================================================================
  1345.      ' This is the "MAIN" code of the prgram. It prints Netware Connection
  1346.      ' Information about the workstation and logged on user.
  1347.      '=====================================================================
  1348.      start:
  1349.      dim info as ConInfoRep
  1350.      
  1351.      connect%=GetConnectNumber%
  1352.      
  1353.      print
  1354.      
  1355.      The BASIC Code Cache                                           Page 21
  1356.      Volume  1, Number  1                                    April 20, 1993
  1357.  
  1358.      
  1359.      if connect%=0 then
  1360.          print "This workstation is not logged in to the network."
  1361.          end
  1362.      end if
  1363.      
  1364.      errr%=GetConnectInfo%(connect%,info)
  1365.      
  1366.      if errr%<>0 then
  1367.          print "Get Netware Connection Information failed."
  1368.          end
  1369.      else
  1370.          Print "Logical Connection number is (DEC): ";connect%
  1371.          Print "                     LogIn Name is: "; trim$(info.nam)
  1372.          print "        Netware Object ID is (HEX): "; DWHex$(SwapBytesDW???(info.id))
  1373.          print "      Netware Object Type is (HEX): ";Right$(DWHex$(SwapBytesW??(info.tipe)),4)
  1374.          print "         WorkStation Node is (HEX): "; getnode$
  1375.      end if
  1376.      end
  1377.      '=============================================================================
  1378.      ' Below are the function used by the program.
  1379.      '=============================================================================
  1380.      ' function to return Netware Logical Connection number
  1381.      function GetConnectNumber%                  ' PGN PAGE: 274
  1382.      ' if 0 then not logged in
  1383.          local   c%
  1384.          !xor    AX,AX                           ' zero AX
  1385.          !mov    AH,&Hdc                         ' Netware API call for Connect #
  1386.          !int    &H21                            ' Call Netware (returns AX=&Hdc32)
  1387.          !xor    AH,AH                           ' Mask off the high byte
  1388.          !mov    c%,AX                           ' AL contains connection number
  1389.          GetConnectNumber%= c%
  1390.      end function
  1391.      '----------------------------------------------------------------------------
  1392.      ' function to return info about the Netware object at a specific connection #
  1393.      ' PGN PAGE: 272
  1394.      function GetConnectInfo% (con%, reply as coninforep) Local
  1395.          dim request as ConInfoReq
  1396.          request.length=2
  1397.          request.cll=&H16
  1398.          request.con=con%
  1399.          reply.length=62
  1400.          reg %ES, varseg(reply)
  1401.          reg %DI, varptr(reply)
  1402.          reg %DS, varseg(request)
  1403.          reg %SI, varptr(request)
  1404.          reg %AX, &HE300
  1405.          call interrupt &H21
  1406.          reply.Extra = Reg(%AX) and &H00FF   ' 0 indicates succesful call
  1407.          GetConnectInfo%=reply.extra
  1408.      end function
  1409.      '----------------------------------------------------------------------------
  1410.      ' funtion to return 6 byte Physical Node Address of the requesting workstation
  1411.      ' PowerBasic does not have a 6 byte integer type so we are going to return
  1412.      
  1413.      The BASIC Code Cache                                           Page 22
  1414.      Volume  1, Number  1                                    April 20, 1993
  1415.  
  1416.      ' a 12 byte string representation of the unsigned Hexidecimal number.
  1417.      ' There is probably a better way to do this, but ....
  1418.      function GetNode$                       ' PGN PAGE: 276
  1419.          temp$="000000000000"                ' 6 bytes requires 12 characters
  1420.          ! push      DI                      ; save Destination Index
  1421.          !
  1422.          ! mov       AX,&Hee00
  1423.          ! int       &H21                    ; Call Netware
  1424.          !
  1425.      '   ! mov       AX,&h4321               ;   for test of conversion
  1426.      '   ! mov       BX,&h8765               ;   for test of conversion
  1427.      '   ! mov       CX,&hCBA9               ;   for test of conversion
  1428.          !
  1429.          ! push      CX                      ; Node returned in CX,BX,AX
  1430.          ! push      BX
  1431.          ! push      AX
  1432.      
  1433.          ' setup our working string
  1434.          ! mov   AX,temp$                    ' string handle
  1435.          ! push  AX                          ' now for location and length
  1436.          ! call  getstrloc                   ' return: location=DX:AX, length=CX
  1437.          ! dec   CX                          ' reduce count by one
  1438.          ! add   AX, CX                      ' we need the end of the string
  1439.          ! mov   ES, DX                      ' store our address of string
  1440.          ! mov   DI, AX                      '   in ES:DI
  1441.      
  1442.      
  1443.          ! std                               ; set direction flag for decriment
  1444.          ! mov       CX,&h0003
  1445.          GetNodeLoop:
  1446.          ! pop       BX                      ; get word from stack
  1447.          ! mov       AH,4                    ; (4 nibbles)
  1448.          ! call      WHex                    ; translate
  1449.          ! loop      GetNodeLoop
  1450.      
  1451.          ! pop       DI                      ; restore resisters
  1452.          ! cld
  1453.          GetNode$=temp$
  1454.      end function
  1455.      '----------------------------------------------------------------------------
  1456.      ' functions to swap High and Low bytes of a Word/DWord
  1457.      ' Netware was origionally only available on a Motorola 6800 server. Motorola
  1458.      ' stores numbers with the most significant byte first. Intel stores numbers
  1459.      ' with the least significant byte first. This function is use to translate
  1460.      ' the old style unsigned wird values. Note that it does not change the input.
  1461.      function SwapBytesW?? (wrd??) Local
  1462.          dim temp as HiLoWord
  1463.          temp.Wrd=wrd??
  1464.          swap temp.bb.b1 , temp.bb.b2
  1465.          SwapBytesW??=temp.Wrd
  1466.      end function
  1467.      '----------------------------------------------------------------------------
  1468.      function SwapBytesDW??? (DW???) Local
  1469.          dim temp as HiLoDWord
  1470.      
  1471.      The BASIC Code Cache                                           Page 23
  1472.      Volume  1, Number  1                                    April 20, 1993
  1473.  
  1474.          temp.DW=DW???
  1475.          'print hex$(temp.bb.b1), hex$(temp.bb.b4)
  1476.          swap temp.bb.b1, temp.bb.b4
  1477.          swap temp.bb.b2, temp.bb.b3
  1478.          SwapBytesDW???=temp.DW
  1479.      end function
  1480.      '----------------------------------------------------------------------------
  1481.      ' function to return the value of the string representation of Hexidecimal
  1482.      ' number. PB's "&Hxxxx" is limited to compile time and/or two bytes.
  1483.      ' NOTE: This function assumes unsigned strings !
  1484.      ' NOTE: This function ignores the invalid characters!
  1485.      function DWHexVal???( DW as string) Local
  1486.          dim temp as string
  1487.          temp=ucase$(DW)
  1488.          while len(temp)>0
  1489.              p= instr("0123456789ABCDEF",left$(temp$,1))
  1490.              if p>0 then
  1491.                  shift left t???,4
  1492.                  t???=t???+(p-1)
  1493.              end if
  1494.              ' print p,t???,temp
  1495.              temp=mid$(temp,2)
  1496.          wend
  1497.          DWHexVal???=t???
  1498.      end function
  1499.      '----------------------------------------------------------------------------
  1500.      ' function to return a 8 character Hexidecimal string representation of
  1501.      ' a four byte DoubleWord variable. (PB's HEX$ function is limited to 2 Bytes)
  1502.      function DWHex$ (DW as DWord) Local
  1503.          temp$="87654321"                    ' allocate 8 byte character string
  1504.      
  1505.          ' PAGE: 333 of PB3 Programers Guide
  1506.          ' " ... save the SI,DI,BP,DS,SS and SP registers."
  1507.          ' of these we only modify the DI register.
  1508.          ! push      DI                      ; save Destination Index
  1509.      
  1510.          ' setup our working string
  1511.          ! mov   AX,temp$                    ' string handle
  1512.          ! push  AX                          ' now for location and length
  1513.          ! call  getstrloc                   ' return: location=DX:AX, length=CX
  1514.          ! dec   CX                          ' reduce count by one
  1515.          ! add   AX, CX                      ' we need the end of the string
  1516.      
  1517.          ' setup our DoubleWord Variable
  1518.          ! les   di,[bp+6]                   ' get the address from the stack
  1519.          ! mov   BX, es:[di]                 ' store lo word
  1520.          ! inc   di                          ' move index foward
  1521.          ! inc   di                          ' two bytes
  1522.          ! mov   CX, es:[di]                 ' store hi word
  1523.          ! mov   ES, DX                      ' store our address in of string
  1524.          ! mov   DI, AX                      '   in ES:DI
  1525.          ! std                               ' set the direction flag
  1526.          ! mov   AH,4                        ' 1 word = 4 nibbles
  1527.          ! call  Whex                        ' now convert
  1528.      
  1529.      The BASIC Code Cache                                           Page 24
  1530.      Volume  1, Number  1                                    April 20, 1993
  1531.  
  1532.          ! mov   BX,CX                       ' get the hi word
  1533.          ! mov   AH,4                        ' 1 word = 4 nibbles
  1534.          ! call  WHex                        ' convert it
  1535.          ! pop   DI                          ' restore Destination Index
  1536.          ' PAGE: 333 of PB3 Programers Guide
  1537.          ' " ... all these calls also require you clear ... the processor
  1538.          ' direction flag before returning to caller. ..."
  1539.          ! cld
  1540.          DWHex$=temp$
  1541.      end function
  1542.      '----------------------------------------------------------------------------
  1543.      ' This function trims the "white space" from both ends of string.
  1544.      ' It also removes ANY contol characters (0 to 31).
  1545.      function trim$(t$)
  1546.          dim temp as string
  1547.          for i=1 to len(t$)
  1548.              tt$=mid$(t$,i,1)
  1549.              if tt$=>" " then temp=temp+tt$
  1550.          next i
  1551.          trim$=ltrim$(rtrim$(temp))
  1552.      end function
  1553.      '=============================================================================
  1554.      ' below are misc ASSEMBLY soubroutines called from the inline ASM functions
  1555.      '=============================================================================
  1556.      ' Most, if not all, of this assembly work could have been done in pure Basic.
  1557.      ' The main reason I did it in assembly was to get some idea of what could 
  1558.      ' be done (and how) with the INLINE ASM capability of PB3. 
  1559.      ' Having gone to the trouble ..... I am going to use it.
  1560.      '-----------------------------------------------------------------------------
  1561.          ! ; ASM routine converts the WORD in BX to a Hex String representation
  1562.          ! ; on entry    
  1563.          ! ;     ES:DI = pointer to end of string (works right to left)
  1564.          ! ;     BX    = value to be converted
  1565.          ! ;     AH    = number of nibbles (hex digits) to convert (0 to 4)
  1566.          ! ; direction flag = set (decrement)
  1567.          ! ; on exit   
  1568.          ! ;     BX    = undefined (contents rotated, 4 digits->BXin=BXout)
  1569.          ! ;     AH    = zero
  1570.          ! ;     AL    = last Hex Character
  1571.          ! ;     AX    = undefined (AH =0, AL last Hex digit)
  1572.          ! ;     ES:DI = byte in front of hex string
  1573.          ! ; The only other register affected is the flag register.
  1574.          ! ; NOTES:
  1575.          ! ;   NO ERROR CHECKING, THIS WILL WRITE OVER ANYTHING (or at least try)!!
  1576.          ! ;   THIS ROUTINE USES A NEAR RETURN, MUST CALL FROM SAME CODE SEG !!!!
  1577.          WHex:
  1578.          ! cmp       AH,0                    ; if 0 then
  1579.          ! jz        WHexExit                ;   out of here
  1580.          ! mov       AL, BL                  ; get value from BX
  1581.          ! and       AL, &h0F                ; mask off low nibble
  1582.          ! dec       AH                      ; sub one from our counter
  1583.          ! ror       BX, 1                   ; rotate the next nibble in BX
  1584.          ! ror       BX, 1                   ;   four rotates are used so that
  1585.          ! ror       BX, 1                   ;   this will work on an 8088
  1586.      
  1587.      The BASIC Code Cache                                           Page 25
  1588.      Volume  1, Number  1                                    April 20, 1993
  1589.  
  1590.          ! ror       BX, 1                   ;   rotate is used to preserve BX
  1591.          ! cmp       AL, &H0009              ; if greater than 9 then
  1592.          ! jg        WHexAlpha               ;   jump to alpha character
  1593.          ! add       AL, &h30                ; else add offset for numeric
  1594.          ! stosb                             ; store val in AL at ES:DI, DI=DI-1
  1595.          ! jmp       WHex                    ; do it again Sam ...
  1596.          WHexAlpha:
  1597.          ! add       AL, &h37                ; add offset for alpha character
  1598.          ! stosb                             ; store val in AL at ES:DI, DI=DI-1
  1599.          ! jmp       WHex                    ; do it again Sam ...
  1600.          WHexExit:
  1601.          ! retn                              ; back to whince we came (I hope)
  1602.      '-----------------------------------------------------------------------------
  1603.      '   more to come, maybe ....
  1604.      ' End of File <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1605.      
  1606.  
  1607.  
  1608.  
  1609.  
  1610.  
  1611.  
  1612.  
  1613.  
  1614.  
  1615.  
  1616.  
  1617.  
  1618.  
  1619.  
  1620.  
  1621.  
  1622.  
  1623.  
  1624.  
  1625.  
  1626.  
  1627.  
  1628.  
  1629.  
  1630.  
  1631.  
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.      The BASIC Code Cache                                           Page 26
  1645.      Volume  1, Number  1                                    April 20, 1993
  1646.  
  1647.  
  1648.  
  1649.      ----------------------------------------------------------------------
  1650.                              V i s u a l   B a s i c
  1651.      ----------------------------------------------------------------------
  1652.  
  1653.      SpyWorks-VB from Desaware
  1654.      
  1655.      SpyWorks-VB is an advanced programming tool for Microsoft's new Visual
  1656.      Basic for Windows version 2.0. It consists of a set of custom
  1657.      controls, dynamic link libraries and applications that not only
  1658.      significantly extend the power of the Visual Basic language, but
  1659.      provide valuable debugging tools as well.
  1660.      
  1661.      VISUAL BASIC ENHANCEMENTS
  1662.      
  1663.      On the enhancement side, SpyWorks-VB provides three custom controls.
  1664.      The SBC.VBX, or generic subclass custom control provides you with
  1665.      complete access to the underlying windows message stream for the
  1666.      controls and forms in your application. The messages that you specify
  1667.      will trigger events in the SBC control. Each message can be processed
  1668.      before or after the default Visual Basic processing for that message,
  1669.      or the event can be simply posted so that your program will know that
  1670.      it occurred. The subclass control can even intercept Visual Basic
  1671.      messages to forms, controls, and VB2 graphical controls.
  1672.      
  1673.      The CBK.VBX, or generic callback custom control handles those
  1674.      situations where you are accessing a Windows API function or third
  1675.      party DLL function that requires a function address as a parameter.
  1676.      Generic callback provides a pool of "callback" function addresses
  1677.      which are mapped into VB events.
  1678.      
  1679.      The SBCKBD.VBX, or keyboard custom control allows you to detect all
  1680.      keystrokes before they are sent to your application, or to detect all
  1681.      keystrokes for the entire system.
  1682.      
  1683.      The DWSPYDLL.DLL dynamic link library not only provides the underlying
  1684.      code used by the controls described previously, but also provides a
  1685.      powerful set of functions for accessing hard to get at Windows API
  1686.      functions (such as those for the printer drivers). It also provides
  1687.      access to many of the Visual Basic API functions which normally cannot
  1688.      be accessed directly.
  1689.      
  1690.      VISUAL BASIC DEBUGGING TOOLS
  1691.      
  1692.      SpyWorks-VB provides a set of debugging tools that can shave hours off
  1693.      of the development process.
  1694.      
  1695.      SpyParam.exe uses the Windows 3.1 built in parameter error detection
  1696.      capability to detect and trap errors that occur while accessing API
  1697.      functions - errors that are often hard to find because they are simple
  1698.      ignored by Windows.
  1699.      
  1700.      SpyMem.exe is a complete memory/resource/module and task browser. Not
  1701.      only does it provide detailed information on various Windows objects,
  1702.      but you can compare the current state of the system to a saved
  1703.      
  1704.      The BASIC Code Cache                                           Page 27
  1705.      Volume  1, Number  1                                    April 20, 1993
  1706.  
  1707.      reference - ideal for determining if you have forgotten to free memory
  1708.      or resources before your program terminates.
  1709.      
  1710.      SpyMsg.exe is a classing "spy" type program with the ability to record
  1711.      any or all events to one or more Windows in your system. SpyMsg.exe
  1712.      adds a couple of new twists however, with its ability to detect not
  1713.      only Windows and Visual Basic messages, but also Visual Basic events.
  1714.      You can obtain a complete list of every event that occurs during the
  1715.      course of your program. Naturally, SpyMsg works with VB2 graphical
  1716.      controls as well.
  1717.      
  1718.      SpyWin.exe is a system window browser that lets you examine
  1719.      information about any or all windows, forms and controls in your
  1720.      system. This application is provided with complete source code so that
  1721.      you can learn some of the techniques used.
  1722.      
  1723.      SpyWorks-VB comes with on-line help, various sample programs, and a 30
  1724.      day money back guarantee (when you order directly from Desaware - your
  1725.      dealer may have other policies). All this for only $129.
  1726.      
  1727.      SpyWorks-VB is a powerful and flexible tool - but in order to use it
  1728.      effectively you will need to have access to information about the
  1729.      Windows API such as that included in the Widows Software Development
  1730.      Kit, The Windows Programmer's Reference from Microsoft, or the Visual
  1731.      Basic Programmer's Guide to the Windows API from Ziff-Davis press
  1732.      (written by the author of SpyWorks-VB).
  1733.      
  1734.      SpyWorks-VB requires Windows 3.1 and Visual Basic 2.0. The runtime
  1735.      custom controls may be distributed with your compiled application
  1736.      without royalties. SBC.VBX and CBK.VBX are Windows 3.0 compatible as
  1737.      well at runtime.
  1738.      
  1739.      Disk subscribers to The BASIC Code Cache can find a demo of
  1740.      SpyWorks-VB in the file SPYWRK.ZIP. You can order SpyWorks-VB by
  1741.      calling Desaware at (408) 377-4770.
  1742.      
  1743.  
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750.  
  1751.  
  1752.  
  1753.  
  1754.  
  1755.  
  1756.  
  1757.  
  1758.  
  1759.  
  1760.  
  1761.      The BASIC Code Cache                                           Page 28
  1762.      Volume  1, Number  1                                    April 20, 1993
  1763.  
  1764.      Tom Hanlin Checks in with PBClone for VB
  1765.      
  1766.      Tom Hanlin, shareware author extraordinaire, checks into the Visual
  1767.      Basic arena with his first offering, PBClone Windows. PBC is a
  1768.      collection of 79 routines callable from Visual Basic, or any language
  1769.      that can call DLLs.
  1770.      
  1771.      PBC provides a number of low level routines that were left out of
  1772.      Visual Basic, or done more efficiently. Included are routines that
  1773.      interrogate the hardware, calculate checksums and crcs, and perform
  1774.      array operations. Also, routines to PEEK and POKE memory are included.
  1775.      
  1776.      Some of the routines included are:
  1777.      
  1778.      Hardware:
  1779.          Comports        Returns the number of com ports installed
  1780.          GetComAddr      Returns address of a comport
  1781.          GetPrtAddr      Returns address of a printer port
  1782.          GetTick         Returns the current system timer tick
  1783.          PeekI and PeekL Peeks that return an integer or long respectively
  1784.          PokeI and PokeL Pokes that set an integer or long respectively
  1785.      
  1786.      Misc:
  1787.          DateSq and DateUnsq Date compression routines
  1788.          TimeSq and TimeUnsq Time compression routines
  1789.          IsAlNum         Checks to see if a character is alphanumeric
  1790.          IsControl       Checks to see if a character is a control code
  1791.      
  1792.      Matrix:
  1793.          PtrMatD         Initializes a double precision array with
  1794.                          increasing values
  1795.          SetMatC         Initializes a currency array to a set value
  1796.      
  1797.      If you have yet to try accessing a third party DLL from your Visual
  1798.      Basic programs, this is a good way to learn. If you have the disk
  1799.      version of The BASIC Code Cache, you can find the full version of
  1800.      PBCWIN in the file PBCWIN10.ZIP. If you have the electronic version,
  1801.      you can find this library as well as all of Tom's other libraries on
  1802.      the following BBSes:
  1803.      
  1804.      219-696-3415  IN  ToolKit (Ken Prevo's)  PC-Board  net: SourceNet 
  1805.          A programmer and power user board.  
  1806.          1 line, 1.2G disk space, HST Dual Standard modem.  
  1807.          Use the name HANLIN SOFTWARE and password SHAREWARE for access.  
  1808.          Voted 23rd Best BBS in the 1991 Best BBS contest.  
  1809.      
  1810.      301-596-7692  MD  Programmer's Corner  custom BBS   also 301-995-6873 
  1811.          All languages-- your one-stop programming shop.  
  1812.          11 lines, 1.5G disk space, v.32 9600 bps modems (some lines are
  1813.          2400).
  1814.      
  1815.      201-334-2555  NJ  Hacker Central  PC-Board  net: ILink 
  1816.          Software and hardware support for serious computer folks.  ILink,
  1817.          Intelec.  
  1818.      
  1819.      The BASIC Code Cache                                           Page 29
  1820.      Volume  1, Number  1                                    April 20, 1993
  1821.  
  1822.          2 lines, 930M disk space, 2400 public / 9600 private (HST Dual).  
  1823.      
  1824.      718-837-3236  NY  The Consultant BBS  PC-Board v14.5a 
  1825.          Programming, Consulting, Tech, Medical, Politics, and more.  ASP
  1826.          hub.  
  1827.          2 lines, 850M, USR HST on Node 1 (listed above), USR DS (v32bis)
  1828.          on Node 2.  
  1829.          Member of Association of Shareware Professionals.  "NYC's best
  1830.          FREE BBS".  
  1831.      
  1832.  
  1833.  
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.  
  1842.  
  1843.  
  1844.  
  1845.  
  1846.  
  1847.  
  1848.  
  1849.  
  1850.  
  1851.  
  1852.  
  1853.  
  1854.  
  1855.  
  1856.  
  1857.  
  1858.  
  1859.  
  1860.  
  1861.  
  1862.  
  1863.  
  1864.  
  1865.  
  1866.  
  1867.  
  1868.  
  1869.  
  1870.  
  1871.  
  1872.  
  1873.  
  1874.  
  1875.  
  1876.      The BASIC Code Cache                                           Page 30
  1877.      Volume  1, Number  1                                    April 20, 1993
  1878.  
  1879.  
  1880.  
  1881.      ----------------------------------------------------------------------
  1882.                              A c c e s s   B a s i c
  1883.      ----------------------------------------------------------------------
  1884.  
  1885.      Creating Custom Wizards with Access Basic
  1886.      
  1887.      The following three articles are part of the Microsoft Knowledge Base
  1888.      that can be found on Compuserve. They detail undocumented functions
  1889.      that are necessary to create Access Wizards. For those not familiar
  1890.      with Wizards, they are programs that automate the creation of new
  1891.      forms or reports. You can access the Microsoft Knowledge Base by
  1892.      typing GO MSDS at any ! prompt. This issue also contains a custom
  1893.      wizard from Microsoft that helps in creating menus for an Access
  1894.      application. In future issues of The BASIC Code Cache we will look
  1895.      into creating our own Wizards.
  1896.      
  1897.      Using Undocumented CreateForm(),CreateReport() Functions [B_WACCESS]
  1898.      ID: Q93096     CREATED: 23-NOV-1992   MODIFIED: 15-DEC-1992
  1899.       
  1900.      Summary:
  1901.       
  1902.      This article discusses the Microsoft Access undocumented functions
  1903.      CreateForm() and CreateReport(). If you intend to write your own
  1904.      FormWizard or ReportWizard, you can use these functions to create and
  1905.      customize a blank form or report to which you can add controls.
  1906.       
  1907.      This article assumes that you are familiar with Access Basic and
  1908.      designing forms and reports.
  1909.       
  1910.      More Information:
  1911.       
  1912.      CreateForm()/CreateReport() is roughly equivalent to choosing "New...
  1913.      Form/New... Report" from the File menu at the top of the screen. When
  1914.      the function is executed, a new empty form/report appears in an
  1915.      iconized state.
  1916.       
  1917.      Both functions return an object value that you can use for further
  1918.      manipulation, and neither function requires parameters.
  1919.       
  1920.      To use these functions, first define a form or report object
  1921.      variable, then assign the variable to the function name. An example of
  1922.      how to do this is:
  1923.       
  1924.         Dim MyForm As Form
  1925.         Set MyForm = CreateForm()
  1926.       
  1927.      After opening the form/report in design mode after executing the
  1928.      commands above, you can bind the form to a table or query by modifying
  1929.      the form's/report's RecordSource property:
  1930.       
  1931.         MyForm.RecordSource = "Categories"
  1932.       
  1933.      With the form/report in design mode, you can access and
  1934.      change any of the other design-time properties of the form/report. You
  1935.      
  1936.      The BASIC Code Cache                                           Page 31
  1937.      Volume  1, Number  1                                    April 20, 1993
  1938.  
  1939.      can also access and change properties of each of the form's/report's
  1940.      sections via the Section property. The Section property is actually an
  1941.      array with each array value being a reference to a form's/report's
  1942.      section. For forms, the Section property array is broken down as:
  1943.       
  1944.         Section(0) - Detail Section
  1945.         Section(1) - Form Header
  1946.         Section(2) - Form Footer
  1947.         Section(3) - Page Header
  1948.         Section(4) - Page Footer
  1949.       
  1950.      For reports, the section property array is broken down as:
  1951.       
  1952.         Section(0) - Detail Section
  1953.         Section(1) - Report Header
  1954.         Section(2) - Report Footer
  1955.         Section(3) - Page Header
  1956.         Section(4) - Page Footer
  1957.         Section(5) - Group Level 1 Header
  1958.         Section(6) - Group Level 1 Footer
  1959.         Section(7) - Group Level 2 Header
  1960.            ...etc.
  1961.       
  1962.      With this information, you can customize the design of a form/report
  1963.      section programmatically. The following example creates a new report,
  1964.      hides the page footer by setting its Visible property to false, sets
  1965.      the Height property of the detail section, and enables its
  1966.      KeepTogether property:
  1967.       
  1968.         Dim MyReport As Report
  1969.         Set MyReport = CreateReport()
  1970.         MyReport.Section(4).Visible = False
  1971.         MyReport.Section(0).Height = 1760
  1972.         MyReport.Section(0).KeepTogether = True
  1973.      
  1974.      For more information on Microsoft Access libraries, query on the
  1975.      following words in the Microsoft Knowledge Base:
  1976.      
  1977.          "libraries AND debugging AND creating" 
  1978.       
  1979.      For more information about other ReportWizard and FormWizard
  1980.      functions, query on the following words in the Microsoft Knowledge
  1981.      Base:
  1982.      
  1983.         "CreateControl AND CreateReportControl AND CreateForm AND 
  1984.         CreateReport AND 'Section Property' AND DeleteControl AND 
  1985.         DeleteReportControl AND CreateGroupLevel"
  1986.      
  1987.      
  1988.      Wizards Part II - CreateControl(), CreateReportControl()
  1989.      ID: Q93095     CREATED: 23-NOV-1992   MODIFIED: 23-NOV-1992 
  1990.       
  1991.      Summary:
  1992.       
  1993.      
  1994.      The BASIC Code Cache                                           Page 32
  1995.      Volume  1, Number  1                                    April 20, 1993
  1996.  
  1997.      This article discusses the Microsoft Access undocumented functions
  1998.      CreateControl() and CreateReportControl().  If you intend to write
  1999.      your own Forms and/or Reports Wizard, you can use these functions to
  2000.      create controls on a form or report that is available in Design mode.
  2001.       
  2002.      For more understanding of Microsoft Access Libraries, search
  2003.      on the Knowledge Base for the following keywords:
  2004.       
  2005.         libraries AND debugging AND creating
  2006.       
  2007.      For more information about other Wizard functions, query the Knowledge
  2008.      Base for:
  2009.       
  2010.      CreateControl AND CreateReportControl AND CreateForm AND CreateReport
  2011.          AND 'Section Property' AND DeleteControl AND DeleteReportControl
  2012.          AND CreateGroupLevel
  2013.       
  2014.      This article also assumes you are familiar with Access Basic and with
  2015.      designing forms and reports.
  2016.       
  2017.      More Information:
  2018.       
  2019.      CreateControl() and CreateReportControl() can be used to create new
  2020.      controls for a form/report opened in Design mode.  These functions
  2021.      require the name of the form/report represented as a string value,
  2022.      and a numeric code that represents the type of control.  The list of
  2023.      control types and their associated numeric codes are shown below:
  2024.       
  2025.         Label .......... 100
  2026.         Box ............ 101
  2027.         Line ........... 102
  2028.         Picture ........ 103
  2029.         Button ......... 104
  2030.         Radio Button ... 105
  2031.         Check Box ...... 106
  2032.         Ole Object ..... 108
  2033.         Text Box ....... 109
  2034.       
  2035.      The CreateControl() and CreateReportControl() functions return a
  2036.      control object value, so you must first define a control variable,
  2037.      then Set the variable to the function name.  Note the code example
  2038.      below which creates a form, then adds a button to the form:
  2039.       
  2040.         Dim MyForm As Form, MyControl As Control
  2041.         Set MyForm = CreateForm()
  2042.         Set MyControl = CreateControl(MyForm.FormName, 104)
  2043.       
  2044.      After executing the code example above, you can modify the properies
  2045.      of the new control via the control variable you defined.  For example:
  2046.       
  2047.         MyControl.Width = 2000
  2048.         MyControl.Caption = "&Sum All Records"
  2049.       
  2050.      For controls that are frequently associated with fields in a table or
  2051.      
  2052.      The BASIC Code Cache                                           Page 33
  2053.      Volume  1, Number  1                                    April 20, 1993
  2054.  
  2055.      query, you can modify the ControlSource property to bind the control.
  2056.      Some controls are created with Height and Width properties set to 0,
  2057.      so that they are - in effect - not visible.  In addition, controls
  2058.      appear at the uppermost left-hand corner of the form by default.
  2059.      Because of this, you should make it a habit to adjust the size and
  2060.      position of the control immediately after creating it.  The example
  2061.      below shows how to create, size, move, and bind a text box.
  2062.       
  2063.         Set MyControl = CreateControl(MyForm.FormName, 109)
  2064.         MyControl.Width = 1500
  2065.         MyControl.Height = 200
  2066.         MyControl.Top = 440
  2067.         MyControl.Left = 200
  2068.         MyControl.ControlSource = "[Category ID]"
  2069.       
  2070.      In addition to specifying the form name and type of control, you can
  2071.      optionally specify the Section in which the control should be created.
  2072.      Note the syntactical structure of CreateControl(), (which is identical
  2073.      to the syntactical structure of CreateReportControl()):
  2074.       
  2075.         Function CreateControl (FormName As String,
  2076.                                 ControlType As Integer
  2077.                                 [,SectionNumber As Integer])
  2078.       
  2079.      Use the SectionNumber parameter to indicate what section the control
  2080.      is to be placed into.  The section that is associated with the
  2081.      
  2082.      SectionNumber is the same as the index representing a section in a
  2083.      Section property array.
  2084.      
  2085.      
  2086.      Wizards Part III - DeleteControl, DeleteReportControl
  2087.      ID: Q93094     CREATED: 23-NOV-1992   MODIFIED: 23-NOV-1992
  2088.      
  2089.      Summary:
  2090.       
  2091.      This article discusses the Microsoft Access undocumented commands
  2092.      DeleteControl, DeleteReportControl, and the undocumented function
  2093.      CreateGroupLevel().  If you intend to write your own Forms and/or
  2094.      Reports Wizard, you can use these functions to delete controls on a
  2095.      form or report that is available in Design mode, and create groups on
  2096.      a Report that is available in Design mode.
  2097.       
  2098.      For more understanding of Microsoft Access Libraries, search
  2099.      on the Knowledge Base for the following keywords:
  2100.       
  2101.         libraries AND debugging AND creating
  2102.       
  2103.      For more information about other Wizard functions, query the Knowledge
  2104.      Base for:
  2105.       
  2106.      CreateControl AND CreateReportControl AND CreateForm AND CreateReport
  2107.          AND 'Section Property' AND DeleteControl AND DeleteReportControl
  2108.          AND CreateGroupLevel
  2109.      
  2110.      The BASIC Code Cache                                           Page 34
  2111.      Volume  1, Number  1                                    April 20, 1993
  2112.  
  2113.       
  2114.      More Information:
  2115.       
  2116.      DeleteControl and DeleteReportControl can be used to delete a control
  2117.      that exists on a form/report in design mode.  Both of these functions
  2118.      require a string value that represents the name of the form and a
  2119.      string value that represents the name of the control.
  2120.       
  2121.      DeleteControl and DeleteReportControl are commands - not functions.
  2122.      They do not return a value.
  2123.       
  2124.      The example below creates a form, then creates a button on the form,
  2125.      displays a message, then deletes the button on the form:
  2126.       
  2127.         Dim MyForm As Form, MyControl As Control
  2128.         Set MyForm = CreateForm()
  2129.         Set MyControl = CreateControl(MyForm.FormName, 104)
  2130.         MsgBox "About to Delete " & MyControl.ControlName
  2131.         DeleteControl MyForm.FormName, MyControl.ControlName
  2132.       
  2133.      When you delete a control using DeleteControl or DeleteReportControl,
  2134.      there is no visual feedback that the control is gone if the
  2135.      form/report is not iconized.  The control still appears as if it were
  2136.      not deleted even though you could not click it into focus.  To make
  2137.      the deleted control disappear in such a case, you would have to
  2138.      repaint the form design window by minimizing and restoring it.
  2139.       
  2140.      If you have a report available in design mode, you can create groups
  2141.      for it programmatically by using the CreateGroupLevel() function.  The
  2142.      syntactical structure of CreateGroupLevel() is shown below:
  2143.       
  2144.         Function CreateGroupLevel(ReportName$,Expression$,
  2145.                                   HasHeader$, HasFooter$)
  2146.       
  2147.      ReportName is a string expression that indicates the name of the
  2148.      Report.
  2149.       
  2150.      Expression is a string expression that represents the field name or
  2151.      calculated field on which the group will be based.
  2152.       
  2153.      HasHeader and HasFooter indicate whether the group includes a group
  2154.      header or group footer, respectively.
  2155.       
  2156.      When CreateGroupLevel() is executed, it adds a group at the innermost
  2157.      level.  For example, if one group already exists, CreateGroupLevel()
  2158.      will create a second group within the first group.  CreateGroupLevel()
  2159.      returns a number indicating which level it created, beginning with
  2160.      zero.  In the example just mentioned, CreateGroupLevel() would return
  2161.      1 since it is the second group, and the first group was Group 0.
  2162.      
  2163.      The preceeding articles are Copyright 1992 by Microsoft Corp.
  2164.      
  2165.  
  2166.  
  2167.      The BASIC Code Cache                                           Page 35
  2168.      Volume  1, Number  1                                    April 20, 1993
  2169.  
  2170.  
  2171.  
  2172.      ----------------------------------------------------------------------
  2173.                              T h e   B u g   L i s t
  2174.      ----------------------------------------------------------------------
  2175.  
  2176.      Buglist for Microsoft Visual Basic
  2177.      
  2178.      Believe it or not, all software has bugs. Some are called features.
  2179.      Whatever they are called, I'd like to inform you of them. In every
  2180.      issue of The BASIC Code Cache, The Bug List will detail some of the
  2181.      bugs and quirks in our commercial development tools. This issue
  2182.      details articles on Visual Basic for Windows and Visual Basic for
  2183.      MSDos bugs that are available in the Microsoft Knowledge Base. These
  2184.      can be found on Compuserve by typing GO MKB at any ! prompt.
  2185.      
  2186.      Visual Basic for Windows
  2187.      ------------------------
  2188.      Q94166: GP/UAE When Closing a DDE Application trom the Task List
  2189.      Q94167: GP/UAE with Stop Statement in Event Procedure and Deleted Sub
  2190.      Q94216: GP/UAE After Undoing Edit of an Option Explicit Statement
  2191.      Q94217: GP/UAE When Assign NULL to VBM_GETPROPERTY of Data Type HLSTD
  2192.      Q94242: Using Graphics Method on Database Objects May Cause GP/UAE
  2193.      Q94244: GP/UAE When Large Tag with MultiSelect of 30 or More Controls
  2194.      Q94290: Setting Add Watch May Cause Your Program to Reset
  2195.      Q94292: Setting Add Watch May Cause GP Fault or UAE
  2196.      Q94293: Painting Problems When FontItalic Set to True for Text Box
  2197.      Q94296: Grid Control Painted Incorrectly When PGUP or PGDN Pressed
  2198.      Q94351: GP/UAE When New Project Loaded After Large Previous Project
  2199.      Q94698: No Out of Memory Error Generated with Text Box > 32K
  2200.      Q94773: Attempting to Refresh Null TableDef Field Causes GP Fault
  2201.      Q94774: GP Fault When Using 8514 Driver with Long String in Text Box
  2202.      Q94892: Making .EXE File May Cause GP Fault If Forms Saved as Binary
  2203.      Q94939: Bad .MAK File Prevents Display of Make EXE File Dialog
  2204.      Q95197: Stack Fault When 2-Item Combo Box Has Small Width Set in Move
  2205.      Q95285: Large Sub, Function, or Module Can Cause GP Fault or UAE
  2206.      Q95290: GP/UAE When Create or Use a Huge Array with Large Elements
  2207.      Q95428: Error Message: Timeout While Waiting for DDE Response
  2208.      Q95429: FixedCols Can Cause Paint Problem With Grid Control
  2209.      Q95430: GP/UAE When Multi-Select Controls w/ No Properties in Common
  2210.      Q95431: Type Mismatch Error When Use VAL Function on Large Hex Value
  2211.      Q95498: Problems Calling DoEvents from a Scroll Bar Change Event
  2212.      Q95499: Stack Fault May Occur If Trapping Divide By Zero
  2213.      Q95500: GP Fault When Close Form That Contains a Single MCI Control
  2214.      Q95501: MAPI: GP Fault When Attempt to Download 923 or More Messages
  2215.      Q95508: Extra Characters in Masked Edit Cause Empty InvalidText Box
  2216.      Q95509: Text Box/Masked Edit in Select Mode if MsgBox in LostFocus
  2217.      Q95513: Negative ScaleHeight Resizes Control When Form Saved as ASCII
  2218.      Q95514: Focus Rectangle Remains When Grid Loses Focus
  2219.      Q95525: GP Fault When Erase User-Defined Array of Variable Strings
  2220.      Q95590: Loading Project Gives Error: Custom control 'Graph' not found
  2221.      Q95829: GP Fault When Making EXE If Declare Is Missing Lib & DLL Name
  2222.      Q95830: Stack Fault When Move Method Makes Combo Box Width Too Small
  2223.      Q96097: Resizing MDIForm with UI Does Not Update Height and Width
  2224.      
  2225.      Visual Basic for DOS
  2226.      
  2227.      The BASIC Code Cache                                           Page 36
  2228.      Volume  1, Number  1                                    April 20, 1993
  2229.  
  2230.      --------------------
  2231.      Q96942: ""No currently active form"" with ISAM Statement In Quick
  2232.      Q80412: ""Internal Error"" for SWAP of TYPE Elements in SUB Using VAL
  2233.      Q90396: ERDEV$ Returns Incorrect Value Under MS-DOS 5.0
  2234.      Q90905: Click Still Occurs when Using SetFocus to Prevent Focus Change
  2235.      Q90961: SETUP.EXE on Bernoulli Hard Disk Is Not Supported
  2236.      Q92953: Stand-Alone Program Using Overlays and ISAM Hangs on Open
  2237.      Q93670: Using Run on Program That Has Overlays Causes Incorrect Error
  2238.      Q93674: Run in Procedure That Dimensions Array Hangs VB Environment
  2239.      Q94007: Basic Serial Communications Programs May Hang With No Error
  2240.      Q94160: Text Box Does Not Highlight Text When Word Double-Clicked
  2241.      Q94260: Pmt# Causes Illegal Function Call Error If No Math Coprocessor
  2242.      Q94261: Code Remains in VBDOS.EXE After Change in FD.EXE
  2243.      Q94262: Computer Hangs When Click Form Without Focus Then CTRL+BREAK
  2244.      Q94289: Mouse Cursor Disappears When Using the CodeView Debugger
  2245.      Q94663: Blank Screen In Monochrome Mode
  2246.      Q94664: Chaining with Modal Form or Msg Box in Menu May Hang Computer
  2247.      Q94692: Assignment in Immediate Window Causes Syntax Check In Editor
  2248.      Q94693: ALTSETUP.BAT Does Not Create NEW-VARS.BAT
  2249.      Q94694: C7 Module, Overlay, and Run-time Module Makes Computer Hang
  2250.      Q94695: Error: Executable code not allowed in module level of a form
  2251.      Q94730: Corrections for Errors in the Visual Basic for MS-DOS Manuals
  2252.      Q94777: Arrow Keys Don't Activate Control Box in Form Containing Menus
  2253.      Q94779: Disk not ready Error Saving File After Change to Invalid Drive
  2254.      Q94780: ISAMCVT Problems Converting BTRIEVE Files
  2255.      Q94781: Static Common Array Greater than 65510K May Hang the Computer
  2256.      Q94782: Clipboard Not Cleared After Restart in Interpreter Environment
  2257.      Q94786: File Not Found When Directory Name Contains Period
  2258.      Q94787: Unable to Move or Size Form After Executing Width Statement
  2259.      Q94788: Changing Visible or Enabled Property Can Cause Extra Change
  2260.      Q94789: Height/Width Properties of Attached Scroll Bars May Be Wrong
  2261.      Q94790: Errors When Use CHAIN: Illegal function call or Bad file mode
  2262.      Q94791: Selecting a Menu Suspends All User Events
  2263.      Q94792: Making the ENTER Key Act Like a TAB Key in Visual Basic
  2264.      Q94793: Minimum Width of Text Box is 4 Characters Even Without Border
  2265.      Q94823: PACKING.TXT for VB for MS-DOS Version 1.0 Professional Edition
  2266.      Q94824: COMPAT.TXT for Visual Basic for MS-DOS 1.0
  2267.      Q94831: Undocumented Error: Too many local strings in Sub/Function
  2268.      Q94832: Value Property May Change When You Click the Scroll Bar Thumb
  2269.      Q94833: Array Errors When Call Function in Other Module w/ No Declare
  2270.      Q94834: Scrolling List Box Causes Click Event and Change in Selection
  2271.      Q94835: No Resize Event When Maximize MDI Child
  2272.      Q94836: Cannot Distinguish CTRL+DEL and CTRL+BACKSPACE In Key Events
  2273.      Q94868: Linking with CMNDLG.LIB or SPIN.LIB Can Cause Library Error
  2274.      Q94897: PACKING.TXT for VB for MS-DOS Version 1.0 Standard Edition
  2275.      Q94937: Computer Hangs When Load Then Unload Form in Form_Load Event
  2276.      Q94938: Overflow Error When Use ISAMREPR.EXE to Repair ISAM Database
  2277.      Q95180: Getting Started with CodeView in Visual Basic for MS-DOS
  2278.      Q95181: Create Link Overlays Using Parentheses or a .DEF File
  2279.      Q95291: Obtaining the Module Name and Address of an Error
  2280.      Q95363: Viewing Basic Variable-Length String Variables in CodeView
  2281.      Q95432: Cannot Profile Program Compiled in Programming Environment
  2282.      Q95433: /ES Option Is Not Valid in the Standard Edition
  2283.      Q95438: OS/2 Version 2.0 System Error SYS3175 from LINK.EXE
  2284.      
  2285.      The BASIC Code Cache                                           Page 37
  2286.      Volume  1, Number  1                                    April 20, 1993
  2287.  
  2288.      Q95461: Memory Loss with Repeated Display of MsgBox or Modal Form
  2289.      Q95481: On Gosub or On Goto Causes Error: Variable not declared
  2290.      Q95863: Wrong Number of Dimensions in Common or Dim Statement
  2291.      Q95942: HelpSetOptions Sets Visible Property to False on Wrong Button
  2292.      Q96068: Use && to Display Ampersand Character in MsgBox Text
  2293.      Q96099: How to Drop Down a Menu on the Startup Form of an Application
  2294.      Q36576: CTRL+Z Embedded in Source Truncates BC.EXE Compilation
  2295.      Q40547: BC.EXE Will Not Compile Files Named USER.*
  2296.      
  2297.  
  2298.  
  2299.  
  2300.  
  2301.  
  2302.  
  2303.  
  2304.  
  2305.  
  2306.  
  2307.  
  2308.  
  2309.  
  2310.  
  2311.  
  2312.  
  2313.  
  2314.  
  2315.  
  2316.  
  2317.  
  2318.  
  2319.  
  2320.  
  2321.  
  2322.  
  2323.  
  2324.  
  2325.  
  2326.  
  2327.  
  2328.  
  2329.  
  2330.  
  2331.  
  2332.  
  2333.  
  2334.  
  2335.  
  2336.  
  2337.  
  2338.  
  2339.  
  2340.  
  2341.  
  2342.      The BASIC Code Cache                                           Page 38
  2343.