home *** CD-ROM | disk | FTP | other *** search
/ ftp.pasteur.org/FAQ/ / ftp-pasteur-org-FAQ.zip / FAQ / visual-basic-faq / windows < prev   
Internet Message Format  |  1997-05-07  |  126KB

  1. Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!news.starnet.net!news.starnet.net!news.dra.com!feed1.news.erols.com!howland.erols.net!cs.utexas.edu!news.cs.utah.edu!news.cc.utah.edu!park.uvsc.edu!not-for-mail
  2. From: knosack@park.uvsc.edu (Kris Nosack)
  3. Newsgroups: comp.lang.basic.visual.misc,comp.answers,news.answers
  4. Subject: FAQ: (8/95) comp.lang.basic.visual.* VB/Win Frequently Asked Questions
  5. Supersedes: <visual-basic-faq-windows-1-860253040@uib.no>
  6. Followup-To: comp.lang.basic.visual.misc
  7. Date: 5 May 1997 14:10:50 -0000
  8. Organization: Visual Basic FAQ Maintainers
  9. Lines: 3036
  10. Approved: news-answers-request@MIT.Edu
  11. Distribution: world
  12. Expires: 07 Jun 1997 14:10:45 (Z)
  13. Message-ID: <visual-basic-faq-windows-1-862841445@uib.no>
  14. Reply-To: Jan.Haugland@uib.no (Jan Steinar Haugland)
  15. NNTP-Posting-Host: park.uvsc.edu
  16. Summary: Frequently asked questions concerning Visual Basic for Windows.
  17. Keywords: FAQ VISUAL BASIC WINDOWS
  18. X-Posting-Frequency: Posted on the 5th of each month.
  19. X-Content-Currency: This FAQ changes regularly.  When a saved or printed copy
  20.                     is over 6 months old, please obtain a new one.
  21. Xref: senator-bedfellow.mit.edu comp.lang.basic.visual.misc:158348 comp.answers:25843 news.answers:101825
  22.  
  23. Posted-By: auto-faq 3.1.1.2
  24. Archive-name: visual-basic-faq/windows
  25.  
  26. Last-modified: 22-Aug-95
  27.  
  28. Covers VB 4.0 (briefly)
  29.  
  30. *** ATTENTION ***
  31. A greatly expanded and updated version of this FAQ can now be found on the
  32. WWW at http://home.sol.no/jansh/vb/default.htm - you are strongly encouraged
  33. to refer to the WWW version.  The WWW version may be "ported" to text and
  34. posted to the VB newsgroups, but there are no definate plans to do this at
  35. this time.
  36.  
  37. Please send all feedback on this document to jansh@online.no (Jan S. Haugland)
  38. Please don't send VB questions to the FAQ maintainers' private email account.
  39.    
  40.  
  41.                    VISUAL BASIC FOR WINDOWS (VB/Win)
  42.                  Frequently asked Questions & Answers
  43.                             Section IX - B
  44.    
  45.    
  46.    The following symbols indicates new & updated topics:
  47.    
  48.    [++] means topic is updated in this issue
  49.    [**] means topic is new in this issue
  50.    
  51.    Hope this makes it easier for Our Regular Readers   ;-)
  52.    
  53.    
  54.    
  55.    TABLE OF CONTENTS:
  56.    ******************
  57.    
  58.    A. PREFACE
  59.    1. About this document
  60.    2. Where to get the VB/Win FAQ [++]
  61.    3. Kudos & comments
  62.    
  63.    B. GENERAL VISUAL BASIC QUESTIONS
  64.    1. Does VB/Win make standalone .EXE files?
  65.    2. What is the current version of Visual Basic for Windows? [++]
  66.    3. Where can I get updated VB and other Microsoft files?
  67.    4. Help! I am lost on ftp.microsoft.com.
  68.    5. Where can I get good up-to-date information about VB? [++]
  69.    6. WWW pages for VB! [**]
  70.    7. Are there any examples of commercial applications built using
  71.        Visual Basic?
  72.    8. Limits of VB?
  73.    
  74.    C. COMMON VISUAL BASIC PROGRAMMING QUESTIONS
  75.    1. What's the difference between MODAL and MODELESS forms? [++]
  76.    2. When/Why should I use Option Explicit?
  77.    3. Why does everybody say I should save in TEXT not BINARY?
  78.    4. Is the Variant type slower than using other variable types?
  79.    5. How do I make a text box not beep but do something else when I
  80.        hit the Enter key?
  81.    6. How do I implement an incremental search in list/dir/combo/file
  82.        boxes?
  83.    7. How do I get the Tab key to be treated like a normal character?
  84.    8. How do I make an animated icon for my program?
  85.    9. What is passing by reference?
  86.    10. I get a "file not found" error on the IIF function when I
  87.        distribute by program. Uh?
  88.    11. Is there any way to pass a variable to a form apart from using
  89.        global variables?
  90.    12. How should dates be implemented so they work with other
  91.        language and country formats?
  92.    13. Can a VB application be an OLE server?
  93.    14. How do I dial a phone number without using the MSCOMM VBX?
  94.    15. I have [several] megabytes of memory. Why do I get an "out of
  95.        memory" error? [++]
  96.    16. How do I mimic a toggle button? [++]
  97.    17. How do I get my application on top?
  98.    18. Is there a way to break long lines in VB code?
  99.    19. How do I remove/change the picture property of a control at
  100.        design time?
  101.    20. Is a [foo] VBX/DLL available as shareware/freeware?
  102.    21. How do I make my applications screen-resolution independent?
  103.    22. How do I do Peek and Poke and other low-level stuff? [++]
  104.    23. Why doesn't "my string" & Chr$(13) do what I want?
  105.    24. How do I prevent multiple instances of my program?
  106.    25. How do I implement an accelerator key for a text box?
  107.    26. How do I force a file dialogue box to reread the currect disk?
  108.    27. How do I get the number of free bytes on a disk? [++]
  109.    28. Data Control missing from toolbox when I use VB under NT 3.5.
  110.        Huh?
  111.    
  112.    D. ADVANCED VISUAL BASIC PROGRAMMING ISSUES
  113.    1. How do I tell when an application executed using the SHELL
  114.        command is finished?
  115.    2. How do I access C style strings?
  116.    3. How can I change the printer Windows uses in code without using
  117.        the print common dialog? How can I change orientation?
  118.    4. Any tips for speeding up VB?
  119.    5. How do I speed up control property access?
  120.    6. How much gain in performance will I get if I write my number
  121.        crunching routines in C instead of Visual Basic?
  122.    7. How do you make a TEXTBOX read only? Or, how do I prevent the
  123.        user from changing the text in a TEXTBOX?
  124.    8. How can I create a VBX?
  125.    9. How do you change the system menu (on the Control-Menu Box)?
  126.    10. How do I play MID, WAV or other multimedia files?
  127.    11. How can I call a 'hidden' DOS program from VB?
  128.    12. How do I do drag & drop between applications?
  129.    13. How do I use GetPrivateProfileString to read from INI files?
  130.    14. How do I implement Undo?
  131.    15. How do I create a window with a small title bar as in a
  132.        floating toolbar?
  133.    16. What is Pseudocode?
  134.    17. Does VB support pointers to functions?
  135.    18. How do I program the Novell NetWare API from VB?
  136.    19. Visual Basic 4 news [**]
  137.    20. How do you change the icon and otherwise manipulate the DOS
  138.        box?
  139.    21. How do I make the mouse cursor invisible/visible?
  140.    22. How do I create controls dynamically (at run-time)?
  141.    23. How do I set the Windows wallpaper at runtime?
  142.    24. How do I call help files from a VB program? [**]
  143.    
  144.    E. CALLING THE WINDOWS API AND DLLs IN GENERAL
  145.    1. What is the Windows API?
  146.    2. How do I call a DLL?
  147.    3. What about DLL calls that require callbacks?
  148.    4. Tips for calling DLLs (such as the Windows API)
  149.    
  150.    F. VISUAL BASIC AND DATABASES
  151.    1. Why can't I use an index with my VB accessed database?
  152.    2. "Can't find installable ISAM" or Why does my compiled VB
  153.        database app generate an error when it ran just fine in the
  154.        design environment?
  155.    3. Is the Access Engine and Visual Basic Pro good enough for
  156.        database work?
  157.    4. How do you avoid the "Invalid use of null" error when reading
  158.        null values from a database?
  159.    5. What is "NULL"?
  160.    6. How can I access a record by record number?
  161.    7. How about Access 2.0 compatibility?
  162.    8. Tips for VB database programming:
  163.    9. How come I get a "No Current Record" error when I use a a Data
  164.        Control on an empty table?
  165.    10. How can I speed up my VB database application?
  166.    11. How do I get a bitmap picture in a field in an Access
  167.        database?
  168.    12. What is "Reserved Error -1209"?
  169.    13. "Cannot perform operation. illegal.." with Paradox 3.5
  170.        table(s)
  171.    14. I'm getting error message "Reserved Error [-nnnn] ("There is
  172.        no message for this error")" from Jet Engine 2.0. Huh?
  173.    15. Why do I get "object not an array" when I try reference the
  174.        fields of a global object variable which I have set to a table?
  175.    16. Steps for securing an Access 2.0 database [**]
  176.    
  177.    G. DISTRIBUTING VISUAL BASIC APPLICATIONS
  178.    1. What are some tips for using Setup Wizard?
  179.    2. Are there restrictions on what I can distribute with my VB
  180.        program?
  181.    3. What alternatives to setup wizard do I have?
  182.    4. Do I need to worry about users who have Progman replacements
  183.        such as Norton Desktop and PC Tools?
  184.    5. Can I distribute my app without vbrunXXX.dll?
  185.    6. Why won't my setup program install commdlg.dll et. al.?
  186.    7. Where do I install VBXs and DLLs?
  187.    
  188.    H. MISCELLANEOUS TIPS AND INFORMATION
  189.    1. Multiple identifiers after the DIM statement can be confusing
  190.    2. "Clean up" your project before final EXE compilation.
  191.    3. Multiple END statements can be dangerous; or, The program that
  192.        refused to terminate.
  193.    4. What are the latest versions of the various files used by VB?
  194.    
  195.    I. VISUAL BASIC FOR APPLICATIONS (VBA)
  196.    1. Any tips for VB/Win 3 programmers moving to VBA?
  197.    2. Does VBA support VBXs?
  198.    3. How do I access properties on my dialog boxes in VBA?
  199.    4. How do I use database routines from Excel VBA?
  200.    
  201.  
  202.  
  203. A.   PREFACE
  204.  
  205. 1.   About this document
  206.    
  207.    This document is a compilation of frequently asked questions and
  208.    their answers about Visual Basic for Windows and Visual Basic for
  209.    Applications which have been gathered from posts to the
  210.    comp.lang.basic.visual.* newsgroups.  Although efforts have been
  211.    made to find obvious errors, there is no guarantee that the
  212.    information in this document is error-free. Neither the FAQ
  213.    maintainer nor anyone else associated with this document assume
  214.    ANY liability for the content or use of this document. If you find
  215.    any errors, please report them to the address given below.
  216.    
  217.    This FAQ document is protected by international copyright
  218.    regulations. Permission is granted to distribute it freely, both
  219.    in electronic and written format, provided no charge is made.
  220.    Also, do not make changes to this document without the consent of
  221.    the maintainer. Usenet netiquette applies.
  222.  
  223. 2.   Where to get the VB/Win FAQ [++]
  224.    
  225.    Most FAQs (including this one) are available at the anonymous ftp
  226.    archive site "rtfm.mit.edu". All parts of the VB FAQ may be found
  227.    here:
  228.    
  229.      ftp://rtfm.mit.edu/pub/usenet/comp.lang.basic.visual.misc/
  230.    
  231.    **Alternative FTP Sites**:
  232.    The following are alternative sites to rtfm:
  233.    
  234.    North America: ftp.uu.net                     /usenet/news.answers
  235.    Europe:        ftp.uni-paderborn.de           /pub/FAQ
  236.                   ftp.Germany.EU.net             /pub/newsarchive/news.answers
  237.                   grasp1.univ-lyon1.fr           /pub/faq
  238.                   ftp.win.tue.nl                 /pub/usenet/news.answers
  239.                   ftp.sunet.se                   /pub/usenet
  240.    Asia:          nctuccca.edu.tw                /USENET/FAQ
  241.                   hwarang.postech.ac.kr          /pub/usenet/news.answers
  242.    
  243.    (FYI:  "rtfm" stands for "Read The ******* Manual".  I kid you
  244.    not!)
  245.    [Andre van Meulebrouck (vanmeule@ils.nwu.edu)]
  246.    
  247.    You can also have the VB FAQs e-mailed to you by sending a message
  248.    to
  249.    "mail-server@rtfm.mit.edu" with ONLY the text
  250.    
  251.      send usenet/comp.lang.basic.visual.misc/*
  252.    
  253.    in the BODY of the message.
  254.    
  255.    Alternative mailservers for those who have no ftp access
  256.      ftpmail@decwrl.dec.com or ftpmail@cs.uow.edu.au
  257.      bitftp@pucc.princeton.edu or ftpmail@lth.se
  258.      bitftp@dearn or to bitftp@vm.gmd.de (Europe only)
  259.      ftpmail@ftp.uni-stuttgart.de
  260.      ftpmail@grasp.insa-lyon.fr or ftpmail@ieunet.ie
  261.      bitftp@plearn.edu.pl or bitftp@plearn (Europe)
  262.      ftpmail@doc.ic.ac.uk or ftpmail@sunsite.unc.edu
  263.    [thanks to Jakob Faarvang (jakobf@apexsc.com)]
  264.    
  265.    For all mailservers:
  266.    Use the "index" command to get a list of files available at the
  267.    site.
  268.    Use the "help" command to get more detailed instructions.
  269.    (NOTE: commands are in BODY of mail message!)
  270.    
  271.    Note that a Web-browser like Netscape or Microsoft Internet
  272.    Explorer easily can access an ftp site, view and download files.
  273.    The ftp address on the top of this point (ftp://...) is formatted
  274.    for these browsers; just copy and paste the text directly into the
  275.    "URL" line.
  276.    
  277.    There is currently work going on to make these available in HTML
  278.    format (for Web-browsers). This work is done by Peter Millard
  279.    <millard@buffnet.net>. Look at:
  280.    
  281.      http://www.buffnet.net/~millard/vblinks.htm
  282.    
  283.    or go directly to the copies of his HTML FAQ's (when finished!):
  284.    
  285.      http://www.buffnet.net/~millard/vbgenfaq.htm
  286.      http://www.buffnet.net/~millard/vbdosfaq.htm
  287.    
  288.  
  289. 3.   Kudos & comments
  290.    
  291.    In this document, whenever a long line of code must be split into
  292.    two or more lines of text in the code examples, a | symbol will
  293.    precede each line which should be appended to the line above it.
  294.    
  295.    As the FAQ maintainer, I don't have time to explore all of the
  296.    aspects of Visual Basic. Neither have I time or knowhow to
  297.    personally answer direct technical questions thoroughly. I rely on
  298.    your submissions to improve the quality and inclusiveness of this
  299.    document. If you have found a VB hint, tip, trick, work-around,
  300.    etc., please write it up and send it to me!
  301.    
  302.    Jan Steinar Haugland (jansh@online.no), VB/Win FAQ maintainer
  303.    
  304.    Please note that my first language is not English. You can safely
  305.    ignore all typos, but if you find an error that is so embarrassing
  306.    you can't help pulling your hair and screaming loud, just send me
  307.    a note and I'll correct it quietly. OK?
  308.    
  309.    This document is a collective effort! I would like to thank all
  310.    contributers, and also all those who have given constructive
  311.    feedback. This FAQ is now widely distributed in the net community.
  312.    
  313.    Special thanks to the following people who have made many and
  314.    invaluable contributions to the VB/Win FAQ:  Kris Nosack (the
  315.    previous maintainer), Peter Millard, Nic Gibson, Mr. "D" (the
  316.    anonymous contributor), George Tatge (gat@csn.org), Andy Dingley
  317.    (dingbat@codesmth.demon.co.uk), Ayn Shipley (ashipley@hookup.net)
  318.    and those I may have forgotten (sorry).
  319.    
  320.    John McGuire (jmcguire@jax.jaxnet.com), a longtime VB user,
  321.    recently went through the FAQ and found lots of things worth his
  322.    comments. Many of his corrections and suggestions are implemented
  323.    throughout. Thanks!
  324.    
  325.    Everybody: Your help is GREATLY appreciated!
  326.  
  327. B.   GENERAL VISUAL BASIC QUESTIONS
  328.   
  329.  
  330. 1.   Does VB/Win make standalone .EXE files?
  331.    
  332.    VB/Win produces .exe files, but they are not standalone. All
  333.    VB/Win programs must be distributed with the VBRUNx00.DLL file
  334.    (where x is the major version number). This DLL must accompany all
  335.    VB/Win programs, but only one such file should reside on every
  336.    system where VB programs are used.
  337.  
  338. 2.   What is the current version of Visual Basic for Windows? [++]
  339.    
  340.    VB/Win is just between version 3.0 and 4.0 as of writing this. 4.0
  341.    is about to be released around the same time as Windows 95. This
  342.    will contain both a 16-bit and a 32-bit (for NT and Win95) version
  343.    of the developing environment and the intergrated compiler.
  344.  
  345. 3.   Where can I get updated VB and other Microsoft files?
  346.    
  347.    Microsoft Software Library (MSL) is accessible from the following
  348.    services:
  349.    
  350.    - Compu$erve
  351.    
  352.      GO MSL
  353.      Search for <filename.EXE>
  354.    
  355.    - Microsoft Download Service (MSDL)
  356.      Dial (206) 936-6735 to connect to MSDL
  357.    
  358.    - Internet (anonymous FTP)
  359.      ftp ftp.microsoft.com
  360.      Change to the \softlib\mslfiles directory
  361.      (There are a LOT of files in this directory! It is not
  362.      advisable to list all the files unless you have good time.
  363.      See map below.)
  364.  
  365. 4.   Help! I am lost on ftp.microsoft.com.
  366.    
  367.    You no longer have to be! The site have been reorganised, and
  368.    you'll find the file DIRMAP.TXT in root (or whatever it's called
  369.    on a 3.5 NT server). 
  370.  
  371.    NOTE: Directory and file names at ftp.microsoft.com are NOT case
  372.    sensitive.
  373.    
  374.    Thanks to Richard Mason (richard@whitney.demon.co.uk) for the map
  375.    he made for us before this long overdue reorganisation, and thanks
  376.    for bringing this to my attention.
  377.  
  378. 5.   Where can I get good up-to-date information about VB? [++]
  379.    
  380.    If you do any VB programming at all, you really should get the
  381.    latest copy of the Microsoft Knowledge Base from one of the
  382.    sources listed above!  The filename is VBKB.EXE or VBKB_FT.EXE for
  383.    the version with full text searching. The Knowledge Base is a
  384.    Windows help formatted document that is updated almost monthly.
  385.    (Beware: The files are huge!)
  386.    
  387.    The EXE files on ftp.microsoft.com (and other places) are simple
  388.    self-extracting files. They don't do any automatic updating of
  389.    your system, just dump the file(s) inside them in the current
  390.    directory on your disk, uncompressed and ready for use. Just
  391.    replace the old files on your system with the new files (same
  392.    name, usually).
  393.    
  394.    This FAQ (ahem) is a pretty good source as a digest of many of the
  395.    VB issues that are discussed in the comp.lang.basic.visual.*
  396.    newsgroups, but as such the information contained in this FAQ may
  397.    not have been thoroughly tested or verified.
  398.    
  399.    For easier access to and use of this FAQ document, get the Windows
  400.    Help file format FAQ doc by anonymous ftp to quasar.sba.dal.ca and
  401.    look under /www/hlp. The .HLP version is made by Tim Roberts
  402.    (TJR@SBACOOP.SBA.DAL.CA). This is HIGHLY RECOMMENDED.
  403.    
  404.    Dave McCarter puts out a nice Windows help formatted document
  405.    called "Visual Basic Tips and Tricks". A good resource with
  406.    information that isn't found in the Knowledge Base. It can be
  407.    found by anonymous ftp to ftp.cica.indiana.edu
  408.    /pub/pc/win3/programr/vbasic/ as VBTIPS??.ZIP, where '??' is the
  409.    version number (yes, get the one with the highest number).
  410.    
  411.    [[ Mark Schoonover has started a monthly magazine called _VBWin
  412.    Programmer's Magazine_ that is compiled around the Discussion of
  413.    Microsoft Visual Basic and Related Issues mailing list. This
  414.    magazine is available at the usual ftp sites like cica and at his
  415.    BBS (619) 571-2846. Mark can be contacted at schoon@cts.com. It
  416.    also has its own anonymous ftp site: ftp.cts.com in the
  417.    /pub/schoon/VBWM.Issues directory. - ED: this appears to be down,
  418.    alas. ]]
  419.    
  420.    Jakob Faarvang (jakobf@apexsc.com) maintains the useful CLBV
  421.    Digest:
  422.    
  423.      http://www.apexsc.com/vb/clbv-digest/
  424.    
  425.    and
  426.    
  427.      ftp.apexsc.com:/pub/cgvb/clbv-digest/
  428.    
  429.    Address for him regarding CLBV Digest is clbv-digest-
  430.    editor@apexsc.com
  431.    
  432.    There is presently an effort to put together a VB code library so
  433.    that VB users can share their best - and trickiest - programming
  434.    work. The code library project is being spear headed by Hein Ragas
  435.    who has managed to get a directory on CICA for code snippets to be
  436.    deposited. Stayed tuned to comp.lang.basic.visual.misc for more
  437.    information.
  438.    
  439.    There's a VISBAS-L mailing list for Visual Basic (Thanks to David
  440.    Liden (DL9U@Virginia.EDU) for tracking it down for me when it
  441.    moved). You can subscribe to this mailing list by sending an email
  442.    to
  443.    
  444.      listserv@listserv.tamu.edu
  445.    
  446.    Place the following text in the *body* of the message (no, not the
  447.    subject line):
  448.    
  449.      SUB VISBAS-L Real Name
  450.    
  451.    Where Real Name is just that, *your full real name* not your email
  452.    address. Note that the traffic on this list may overflow your
  453.    mailbox if you have a limited mail buffer. Expect around 40-50
  454.    messages every weekday, a bit less during weekends. Also, to
  455.    unsubscribe, do as above but with "UNSUB" in the body of the
  456.    message to the LISTSERV address, *not* to the VISBAS-L list
  457.    address itself (Believe it or not, we usually receive 2-3
  458.    sub/unsub mails evur  day on the list, and we're really fed up!)
  459.    Also, this mail server was split and a new list called VBDATA-L
  460.    was made for Vb database (Jet) related topics. Same procedure for
  461.    registering (SUB VBDATA-L Real Name).
  462.    
  463.    The address for the MS ACCESS listserver is
  464.    listserv@indycms.bitnet or listserv@indycms.iupui.edu The list
  465.    name is ACCESS-L. To subscribe, you follow the same procedure as
  466.    for the other lists.
  467.    
  468.    Sorry, I know no mailservers or other Internet resources dedicated
  469.    to VBA specifically. Send me any information you may have, and
  470.    I'll bring it on.
  471.    
  472.    There are several Usenet newsgroups dedicated to MS Windows
  473.    programming and use. In fact, far too many to list here :-)
  474.    
  475.    NOTE: PLEASE don't post VB stuff to comp.lang.visual. This group
  476.    has *nothing* to do with Visual Basic, and the academics
  477.    discussing "real" visual programming there are very, very annoyed
  478.    at what they call "quasi-visual" stuff and postings about those
  479.    languages to their group.
  480.    
  481.    If you have a Compu$erve account, you will find a forum for Visual
  482.    Basic there, including some support from Microsoft:
  483.    
  484.    MS BASIC Forum    (GO MSBASIC)
  485.    
  486.    Message Sections Available:             Libraries Available:
  487.     1 Forum News/Info                       1 MS Info and Index
  488.     2 Setup Wizard/Kit                      2 Setup Wizard/Kit
  489.     3 Data Access Objects                   3 Data Access Objects
  490.     4 The Data Control                      4 The Data Control
  491.     5 Programming Issues                    5 Programming Issues
  492.     6 ODBC Connectivity                     6 ODBC Connectivity
  493.     7 SQL Queries                           7 SQL Queries
  494.     8 ProEdition Controls                   8 ProEdition Controls
  495.     9 Calling API's/DLL's                   9 Calling API's/DLL's
  496.    10 Using OLE/DDE                        10 VBWIN-ODBC/Database
  497.    11 MSCOMM control                       11 MSCOMM control
  498.    12 MCI/MAPI controls                    12 MCI/MAPI controls
  499.    13 DOS Visual Basic                     13 DOS Visual Basic
  500.    14 DOS and Mac Basic                    14 DOS and Mac Basic
  501.    15 Suggestions/Mktg.                    15 Suggestions/Mktg.
  502.    16 CDK                                  16 CDK
  503.    17 3rd Party Products                   17 3rd Party Products
  504.    
  505.    There are magazines dedicated to VB. The best known is Fawcett
  506.    Technical Publications' _Visual Basic Programmer's Journal_
  507.    (VSPJ). Phone 800-848-5523 (for US credit card orders) or 303-541-
  508.    0610 (int'l and US other orders), Email 74003.224@compuserve.com
  509.    to Shirley Modric for subscription info. Address is 280 Second
  510.    Street, Suite 200, Los Altos, CA 94022-3603 USA.
  511.    
  512.    From Randy Coates (rcoates@telerama.lm.com):
  513.    I currently subscribe to "Inside Visual BASIC for Windows" from
  514.    the Cobb Group.  Although it is a helpful monthly paper (about 14
  515.    pages per publication), I find it to be overpriced when compared
  516.    to VB Programmers Journal.  Here is the information anyway:
  517.    Domestic $59/yr ($7.00 each); Outside US $79/yr ($8.50 each)
  518.    Phone: Toll Free: 800-223-8720),  Local: 502-491-1900, Customer
  519.    Relations Fax: 502-491-8050, Editorial Department Fax: 502-491-
  520.    4200. Address: _Inside Visual BASIC for Windows_, 9420 Bunsen
  521.    Parkway, Suite 300, Louisville, KY  40220.
  522.    
  523.    (Note: for completeness other VB magazines should be listed, and I
  524.    would like to receive info on those!)
  525.    
  526.  
  527. 6.   WWW pages for VB! [**]
  528.    
  529.    Carl 'n Gary's Visual Basic HomePage is a good place to start:
  530.    
  531.       http://www.apexsc.com/vb/
  532.    
  533.    This page has hotlinks to lots of goodies, including the FAQs,
  534.    clbv.* archives (with search tool), etc. Send any e-mail inquiries
  535.    (about the page!) to:
  536.    
  537.       vb-admin@apexsc.com
  538.    
  539.    [Gary Wisniewski (gary@apexsc.com)]
  540.  
  541. 7.   Are there any examples of commercial applications built using
  542.    Visual Basic?
  543.    
  544.    Profit by Microsoft was written mostly in Visual Basic. In fact,
  545.    Profit was one of three programs selected as PC Magazine's
  546.    Editor's Choice among Windows small business accounting packages.
  547.    Most of the current version of Quicken was written in VB2. The
  548.    viewer/launcher/installer in the oh-so-popular Way Cool [Topic]
  549.    for Windows series of CD-ROMs was written in VB3.
  550.    
  551.    Microsoft uses VB extensively for smaller utilities. 3 of the
  552.    small apps in the Windows and Windows for Workgroups Resource
  553.    Toolkits are written in VB. Also, if you have the Microsoft
  554.    Bookshelf CD-ROM, you will notice that the MVOPTION.EXE program,
  555.    which is an "options" program for MS Viewer, is created in VB.
  556.    
  557.    Note: The existence of VBX files in a package doesn't ecessarily
  558.    mean that it was written in VB. The most popular C++ compilers
  559.    also support VBXes.
  560.  
  561. 8.   Limits of VB?
  562.    
  563.    Are you kidding? VB have *no* limitations... Uh, yeah ;-)
  564.    
  565.    For starters:
  566.    
  567.    * It's not a true compiler, hence it's slow for non-interface
  568.    stuff (it's of
  569.      course slow for interface stuff as well, but that's *Windows*
  570.    not VB)
  571.    
  572.    * It's not really object-oriented (Try looking for the parent of
  573.    ie. a line
  574.      control, and you'll wonder why it has no hWnd  - SpyWorks is an
  575.    add-on you
  576.      may need if this is annoying)
  577.    
  578.    * A statement must be on a single line! (Note: Fixed in VB4!!!!)
  579.    
  580.    * No arrays of constants.
  581.    
  582.    * Your Complaint Here!
  583.    
  584.    An enormous amount of contributers to this topic! Can you guess
  585.    why?
  586.    [Entry suggested by Andre van Meulebrouck (vanmeule@netcom.com)]
  587.  
  588.  
  589. C.   COMMON VISUAL BASIC PROGRAMMING QUESTIONS
  590.   
  591.  
  592. 1.   What's the difference between MODAL and MODELESS forms? [++]
  593.    
  594.    MODAL forms are forms which require user input before any other
  595.    actions can be taken place. In other words, a modal form has
  596.    exclusive focus in that application until it is dismissed. When
  597.    showing a modal form, the controls outside this modal form will
  598.    not take user interaction until the form is closed. The internal
  599.    MsgBox and InputBox forms are examples of modal forms. To show a
  600.    form modally, use the syntax:
  601.    
  602.      MyForm.SHOW 1
  603.    
  604.    MODELESS forms are those which are shown but do not require
  605.    immediate user input. MDI child forms are always modeless. To show
  606.    a form modeless, use the syntax:
  607.    
  608.      MyForm.SHOW
  609.    
  610.    (Thanks to John M. Calvert (calvertj@magi.com) for correcting a
  611.    slightly embarrassing mistake in previous versions of this topic)
  612.  
  613. 2.   When/Why should I use Option Explicit?
  614.    
  615.    Option Explicit forces you to declare all variables before using
  616.    them. Opinions vary greatly on this subject. The main reason to
  617.    use the OPTION EXPLICIT statement at the top of all modules is to
  618.    minimize the amount of bugs introduced into your code by
  619.    misspelling a variable name. Most variants of BASIC (including VB)
  620.    have the capability to create variables 'on the fly' (without any
  621.    declarations). This capability can be a double edged sword.
  622.    
  623.    At the minimum, some suggest using the DEFINT A-Z statement in leu
  624.    of OPTION EXPLICIT. This statement will cause any variables which
  625.    are created on the fly to be created as integers as opposed to
  626.    variant (VB 3.0) or single precision (VB 1.0 and 2.0). (Integers
  627.    take up less memory).
  628.    
  629.    The OPTION EXPLICIT statement causes VB to 'disable' its ability
  630.    to create variables on the fly. Thus, all variables must be
  631.    declared using a DIM or REDIM statement. All variables not
  632.    declared will cause an error when the OPTION EXPLICIT statement is
  633.    used. This will eliminate bugs caused by a misspelled variable.
  634.    The option works module-wide, so you can have some modules with
  635.    and some without this option in your project.
  636.  
  637. 3.   Why does everybody say I should save in TEXT not BINARY?
  638.    
  639.    Actually, saving in binary mode is a bit faster, so why do we
  640.    recommend you to save in text?
  641.    
  642.    If you save the source and the project as text, it becomes ASCII
  643.    (or really, ANSI) code that you can edit with any text editor or
  644.    (if you are careful when you save) word processor. If you save in
  645.    binary, only the VB development environment, current or later
  646.    versions, will understand the code. The Setup Wizard can not scan
  647.    binary projects. Also, source documenters and other programming
  648.    tools usually require text mode. If you use text, you can use a
  649.    simple text editor (ie. notepad) to cut and paste code from other
  650.    source/form modules into your current project. Some 'tricks' (like
  651.    making an array of 1 control into a single non-array control
  652.    again) is easily done with an editor but not that easy in the
  653.    environment. If you want to print your project to paper the
  654.    file|print option in the VB environment is often not good enough;
  655.    you may want to import the text files into your word processor.
  656.    And, finally, if something goes wrong (only one byte is changed!)
  657.    you may be out of luck in binary mode. In text mode you will more
  658.    easily be able to fix it.
  659.  
  660. 4.   Is the Variant type slower than using other variable types?
  661.    
  662.    Generally, yes, if we are talking numeric variable types. The
  663.    Variant type also increases memory overhead. To test the speed
  664.    difference, try the following piece of code in something like a
  665.    button_click event and keep the debug window on the screen:
  666.    
  667.      Dim Va As Variant
  668.      Dim In As Integer
  669.      T1! = Timer
  670.      For i% = 1 To 32766
  671.        Va = i%
  672.      Next i%
  673.      T2! = Timer
  674.      Debug.Print "With variant:  "; Format$((T2! - T1!), "0.0000")
  675.      T1! = Timer
  676.      For i% = 1 To 32766
  677.        In = i%
  678.      Next i%
  679.      T2! = Timer
  680.      Debug.Print "With integer:  "; Format$((T2! - T1!),"0.0000")
  681.    
  682.    This test shows (on our test system) that integers are ~60%
  683.    faster! However, for strings there where no real difference, or in
  684.    some instances, variants were faster than strings for routines
  685.    with heavy conversion usage. For the best result in your
  686.    application, test your routines directly.
  687.  
  688. 5.   How do I make a text box not beep but do something else when I
  689.    hit the Enter key?
  690.    
  691.    Put "something else" in your _KeyPress event, depending on what
  692.    you really want. This code example makes *nothing* happen, for an
  693.    extended period of time:
  694.    
  695.      Sub Text1_KeyPress (KeyAscii As Integer)
  696.          If KeyAscii = 13 Then   '13 is Key_Return
  697.             KeyAscii = 0
  698.          End If
  699.      End Sub
  700.    
  701.    This might not be a very nice thing to do, since your users
  702.    usually have some intention when they press Enter. Often they will
  703.    want to jump to the next control, like the Tab key does. To have
  704.    the Enter key emulate the Tab key action, you will need to add the
  705.    line 'SendKeys "{tab}"' above 'KeyAscii=0' in the example above
  706.    (Yes, I thought KeyAscii=9 works but it doesn't! Tab is obviously
  707.    handled by Windows on a lower level).
  708.    
  709.    By the way, you'll also find this in the Microsoft VB Knowledge
  710.    Base (see KB Q78305 and Q85562).
  711.    
  712.    Note: If MultiLine=True you will *not* want to disable the normal
  713.    behaviour of the Enter key.
  714.  
  715. 6.   How do I implement an incremental search in list/dir/combo/file
  716.    boxes?
  717.    
  718.    This is your lucky day. Dan Champagne (Dan_Champagne@dell.com)
  719.    made some VB code (no DLLs are necessary!) which easily provides
  720.    this feature for your applications:
  721.    
  722.      ' Code by Dan Champagne
  723.      ' 4/18/94
  724.      
  725.      ' This code can be used to do an incremental search in either a
  726.      ' list box, dir, combo, or a file box. The following code is set
  727.      ' for a file box called FILE1. To make it work with a list box, or
  728.      ' a file box with a different name, change all occurences of FILE1
  729.      ' with whatever you or VB has named your list, combo, dir, or file box.
  730.      ' There are two places where you will need to change these. They are
  731.      ' on the last couple of lines in the KeyPress code.
  732.      ' Also, thanks to John Tarr for helping debug the code.
  733.      
  734.      'In a .BAS file, add the following:
  735.      'searchme$ is a global vaiable that will keep track of what the
  736.      'user has typed so far.
  737.      Global searchme$
  738.      
  739.      'The following needs to be on one line.
  740.      Declare Function SendMessageBystring& Lib "User" ALIAS
  741.      |"SendMessage" (ByVal hWnd%, ByVal wMsg%, ByVal
  742.      |wParam%, ByVal lParam$)
  743.      
  744.      Global Const WM_USER = &H400
  745.      Global Const LB_SELECTSTRING = (WM_USER + 13)
  746.      Global Const LB_FINDSTRING = (WM_USER + 16)
  747.      
  748.      'In File1 under keydown, add the following:
  749.      'This checks if the user has pressed the up or down arrow.
  750.      'If they have, reset searchme$ to "".
  751.      If KeyCode = 40 Or KeyCode = 38 Then
  752.         searchme$ = ""
  753.      End If
  754.      
  755.      'In File1 under lostfocus, pathchange, patternchange, and click add:
  756.      
  757.      'If the user has done any of the above, reset the searchme$
  758.      'string.
  759.      searchme$ = ""
  760.      
  761.      'In File1 under keypress add:
  762.      
  763.      Dim result&
  764.      
  765.      Select Case KeyAscii
  766.          Case 8     'Backspace
  767.              If searchme$ <> "" Then
  768.                  searchme$ = Left$(searchme$, Len(searchme$) - 1)
  769.              Else
  770.                 File1.ListIndex = 0
  771.              End If
  772.              KeyAscii = 0
  773.              Exit Sub
  774.          Case 27    'Escape
  775.              searchme$ = ""
  776.              KeyAscii = 0
  777.              Exit Sub
  778.          Case 13    'Enter
  779.              searchme$ = ""
  780.              KeyAscii = 0
  781.              Exit Sub
  782.          Case Asc("a") To Asc("z"), Asc("A") To Asc("Z"), Asc("'"),
  783.          |Asc("."), Asc(" "), Asc("0") To Asc("9")
  784.              searchme$ = searchme$ & Chr$(KeyAscii)
  785.              KeyAscii = 0
  786.      End Select
  787.      
  788.      result& = SendMessageBystring(FILE1.hWnd, LB_FINDSTRING,
  789.      |0, searchme$)
  790.      
  791.      If result& = -1 Then
  792.         searchme$ = Left$(searchme$, Len(searchme$) - 1)
  793.      Else
  794.         result& = SendMessageBystring(FILE1.hWnd, LB_SELECTSTRING,
  795.         |-1, searchme$)
  796.      End If
  797.  
  798. 7.   How do I get the Tab key to be treated like a normal character?
  799.    
  800.    You must set TabStop = False for ALL controls on the active form.
  801.    Then you will be able to insert "tab" (chr 9) characters in
  802.    controls like the text box.
  803.    
  804.    If you feel you need the Tab key to behave "normal" (ie. jump to
  805.    next control) outside this specific control, it is trivial to
  806.    emulate its functionality in code:
  807.    
  808.      Sub Command1_KeyDown (KeyCode As Integer, Shift As Integer)
  809.        If KeyCode = 9 Then
  810.          If Shift = 0 Then
  811.             Command2.SetFocus 'Tab=Next control
  812.          ElseIf Shift = 1 Then
  813.             Command3.SetFocus 'Shift-Tab=Prev.ctrl.
  814.          End If
  815.        End If
  816.      End Sub
  817.    
  818.    ...etc.
  819.  
  820. 8.   How do I make an animated icon for my program?
  821.    
  822.    For an example on how you change the icon for your application as
  823.    it is displayed when it is minimized, see the example REDTOP in
  824.    the \samples\picclip directory for VB/Win 3 Pro. This demonstrates
  825.    a fancy animated icon.
  826.  
  827. 9.   What is passing by reference?
  828.    
  829.    Arguments are either passed by reference or by value. When they
  830.    are passed by value, they cannot be changed by the procedure or
  831.    function they are passed to. They *can* be altered when passed by
  832.    reference, since passing by reference is just passing the address.
  833.    
  834.    Note that procedures are less strict about variable types when you
  835.    use BYVAL. If you declare that your Sub takes a Variant, VB takes
  836.    that seriously and gives a nasty "mismatch error" if you try to
  837.    pass ie. a string to it. Make it ByVal (at the cost of some speed)
  838.    and your sub will be more tolerant.
  839.    
  840.    Also note the following nasty trap:  Arguments are passed by
  841.    reference unless enclosed by parentheses or declared using the
  842.    ByVal keyword. [VBWin Language Ref., p. 55]
  843.  
  844. 10.  I get a "file not found" error on the IIF function when I
  845.    distribute by program. Uh?
  846.    
  847.    There's a documentation error, since the manual does not tell you
  848.    that the IIF function requires the file MSAFINX.DLL to be
  849.    distributed with your application. No, IIF is not financial (I
  850.    should know, I study finance right now, or at least I should be
  851.    doing that ;-] ).
  852.  
  853. 11.  Is there any way to pass a variable to a form apart from using
  854.    global variables?
  855.    
  856.    The standard workaround is to put an invisible text box (or
  857.    caption or any other control that suits your use.) on the target
  858.    form and access it by Form.textbox = "value". Then you can use the
  859.    Change event of that control to do anything you want in that form.
  860.    Also, check out the .Tag property which is a "what-you-want"
  861.    property where you can hook any string you want onto a control.
  862.    This property can also be accessed from other modules.
  863.    [Dave Mitton (mitton@dave.enet.dec.com)]
  864.    
  865.    Perhaps a more elegant and flexible way is to implement a stack
  866.    with similar routines. I've done this for a math project, but this
  867.    stack was rather complicated and special purpose (and inspired by
  868.    HP calculators, of whihc I'm a great fan).
  869.    
  870.    Jan G.P. Sijm (jan.sijm@intouch.nl) have implemented some routines
  871.    for general stacks:
  872.    
  873.    '-----------------------------------------------------------------
  874.    ---
  875.    Option Explicit                        'Variable declarations
  876.    required
  877.    Dim m_vStack() As Variant              'Stack of variant types
  878.    
  879.    '*-------------
  880.    '*  This function will pop a value of a stack of variant
  881.    '*  values. The value to be popped (e.g. the variable it
  882.    '*  is assigned to) must have one of the basic variable
  883.    '*  types that Visual Basic supports. The type of the
  884.    '*  return value is determined by the type of the variable
  885.    '*  it is assigned to.
  886.    '*
  887.    '*  Input    : None
  888.    '*  Modifies : m_vStack, Stack of variant's
  889.    '*  Return   : Value of last pushed variant
  890.    '*-------------
  891.    Function stkPop () As Variant
  892.      Dim iM As Integer
  893.      iM = UBound(m_vStack)                'Get current stack size
  894.      stkPop = m_vStack(iM)                'Pop value from stack
  895.      iM = iM - 1                          'Decrement number of
  896.    elements
  897.      ReDim Preserve m_vStack(iM) As Variant
  898.    End Function
  899.    
  900.    '*-------------
  901.    '*  This function will push a value onto a stack of
  902.    '*  variant values. The value to be pushed must have one
  903.    '*  of the basic variable types that Visual Basic supports
  904.    '*
  905.    '*  Input    : vValue, Value to be pushed
  906.    '*  Modifies : m_vStack, Stack of variant's
  907.    '*-------------
  908.    Sub stkPush (ByVal vValue As Variant)
  909.      Dim iM As Integer
  910.      On Error Resume Next                 'Trap for undimensioned
  911.    array
  912.      iM = UBound(m_vStack)                'Get current array size
  913.      iM = iM + 1                          'Increment number of
  914.    elements
  915.      ReDim Preserve m_vStack(iM) As Variant
  916.      m_vStack(iM) = vValue                'Push value on stack
  917.    End Sub
  918.    
  919.    'This is a short example of how the stack routines can be used in
  920.    a
  921.    'Visual Basic program. This example will push three parameters
  922.    onto
  923.    'the stack. A modal dialog is displayed. The dialog will pop the
  924.    'parameters from the stack and set edit controls with the values.
  925.    
  926.    Sub ShowDialog()
  927.      '
  928.      '  Push the parameters for the dialog
  929.      '  onto the stack and display the dialog
  930.      '
  931.      stkPush sName
  932.      stkPush sStreet
  933.      stkPush sCity
  934.      dlgPerson.Show MODAL
  935.    End Sub
  936.    
  937.    Form_Load()
  938.      '
  939.      ' Pop the parameters of this dialog from the
  940.      ' stack in REVERSED ORDER and place the values
  941.      ' in the appropriate edit controls.
  942.      '
  943.      dfCity.Text = stkPop()
  944.      dfStreet.Text = stkPop()
  945.      dfName.Text = stkPop()
  946.    End Sub
  947.    '-----------------------------------------------------------------
  948.    ---
  949.  
  950. 12.  How should dates be implemented so they work with other language
  951.    and country formats?
  952.    
  953.    If you use ie. MM/DD/YY format dates in a program, you will get
  954.    either a runtime-error (ie. month>12) or the wrong date (ie. March
  955.    12 instead of December 3) when your program is used in Europe. And
  956.    vice versa, of course. Even Microsoft's own example programs (like
  957.    the MAPI sample) make this stupid mistake and fail miserably. Use
  958.    the Format command to make sure you get the date you want. For
  959.    example:
  960.    
  961.      strTodaysDate = Format[$](Now, "Short Date")
  962.    
  963.    As a side note, Microsoft has taken much heat on the newsgroup for
  964.    VB's bad support for internationalization! Just try to make a date
  965.    literal in source code that works everywhere as a little exercise.
  966.    Answer elsewhere in this document. No prizes  :-)
  967.  
  968. 13.  Can a VB application be an OLE server?
  969.    
  970.    No. You'll have to use an external DLL/VBX. If you see any
  971.    examples, please tell the newsgroup.
  972.  
  973. 14.  How do I dial a phone number without using the MSCOMM VBX?
  974.    
  975.    The MSCOMM VBX that comes with VB/Pro is great for creating
  976.    communication programs, but it's overkill for dialing a phone
  977.    number. Try the following code:
  978.    
  979.      PhoneNumber$ = "(123)456-7890"
  980.      Open "COM2:" For Output As #1   'or COM1
  981.      Print #1, "ATDT" & PhoneNumber$ & Chr$(13)
  982.      Close #1
  983.    
  984.    Ian Storrs <exuian@exu.ericsson.se> informed me that he had
  985.    experienced problems with this when the VB program was run from a
  986.    network drive. A file named "COM1" was created on the disk! Jeff
  987.    Rife <jrife@health.org> put in the ":" after COM2 to solve that
  988.    problem!
  989.    
  990.    This trick is probably not a good idea for bigger applications,
  991.    but it's nice for small personal utilities.
  992.  
  993. 15.  I have [several] megabytes of memory. Why do I get an "out of
  994.    memory" error? [++]
  995.    
  996.    This problem and its solution(s) should not be applicable to
  997.    Windows 95.
  998.    
  999.    Unfortunately, Microsoft has been more famous for memory barriers
  1000.    than anything else. This is a late descendant of the infamous 640K
  1001.    barrier that has been plaguing us for years. Although Windows
  1002.    allows the user to access several megabytes of memory, it uses two
  1003.    limited (64K) memory areas called User Heap and GDI Heap for some
  1004.    specific data structures. Go to the Help|About box in Program
  1005.    Manager to see the percentage of free resources in the *most*
  1006.    exhausted heap. If these areas are exhausted, you are out of luck.
  1007.    VB programs are unfortunately rather greedy on these structures.
  1008.    Windows 4 is supposed to free us from this limitation...
  1009.    
  1010.    Note that every visible control (ie every button) is a window to
  1011.    Windows. Every new control takes up some bytes in the precious
  1012.    User heap.
  1013.    
  1014.    Also, there is another way to run out of memory in Windows, not
  1015.    related to VB. Windows requires free Upper Memory Area (UMA, also
  1016.    called Upper Memory Blocks, not to be confused with High RAM,
  1017.    which is the first 64K of extended memory) to do certain tasks. If
  1018.    you use QEMM or DOS 6+ MemMaker and you have many device drivers
  1019.    (network, etc) this area may have been filled up before you launch
  1020.    Windows. You will then be unable to start applications, even
  1021.    though you have plenty of free RAM. The problem can be solved with
  1022.    careful memory setup, but this is far beyond the scope of this
  1023.    FAQ.
  1024.    
  1025.    On a completely unrelated problem: When you run a program with an
  1026.    outline control with some ATI graphics cards, it may crash with
  1027.    just that error message. (see Knowledge Base Q100194 PRB: "Some
  1028.    ATI Video Drivers Hang When Using MSOUTLIN.VBX")
  1029.  
  1030. 16.  How do I mimic a toggle button? [++]
  1031.    
  1032.    The only "fix" we know for this problem is to use a picture or
  1033.    image control to mimic the action of a button or button3d control.
  1034.    You need two bitmaps, one for buttonup and one for buttondown (and
  1035.    perhaps one more for inactive state). This is a kluge, we know.
  1036.    Look at the button bar used in the MDINOTE sample program supplied
  1037.    with VB for an example of this.
  1038.  
  1039. 17.  How do I get my application on top?
  1040.    
  1041.    To force a form to the front of the screen, do the following
  1042.    command:
  1043.    
  1044.      Form1.ZOrder
  1045.    
  1046.    To make the application *stay* on top, put the Zorder command in a
  1047.    Timer event repeatedly called, say, every 1000 msecs. This makes a
  1048.    "softer" on-top than other methods, and allows the user to make a
  1049.    short peek below the form.
  1050.    
  1051.    There are two different "Zorder"'s of forms in Windows, both
  1052.    implemented internally as linked lists. One is for "normal"
  1053.    windows, the other for real "topmost" windows (like the Clock
  1054.    application which is distributed with MS Windows). The Zorder
  1055.    command above simply moves your window to the top of the "normal"
  1056.    window stack. To make your window truly topmost, use the
  1057.    SetWindowPos API call like this:
  1058.    
  1059.      'Make these declares:
  1060.      Declare Function SetWindowPos Lib "user" (ByVal h%,
  1061.      |ByVal hb%, ByVal x%, ByVal y%, ByVal cx%, ByVal cy%,
  1062.      |ByVal f%) As Integer
  1063.      Global Const SWP_NOMOVE = 2
  1064.      Global Const SWP_NOSIZE = 1
  1065.      Global Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE
  1066.      Global Const HWND_TOPMOST = -1
  1067.      Global Const HWND_NOTOPMOST = -2
  1068.      
  1069.      'To set Form1 as a TopMost form, do the following:
  1070.      res% = SetWindowPos (Form1.hWnd, HWND_TOPMOST, 0, 0,
  1071.      |0, 0, FLAGS)
  1072.      'if res%=0, there is an error
  1073.      
  1074.      'To turn off topmost (make the form act normal again):
  1075.      res% = SetWindowPos (Form1.hWnd, HWND_NOTOPMOST, 0, 0,
  1076.      |0, 0, FLAGS)
  1077.  
  1078. 18.  Is there a way to break long lines in VB code?
  1079.    
  1080.    There is unfortunately no line continuation character in VB/Win
  1081.    3.0. Excel 5 VBA does, however, use Space+Underscore (" _") as a
  1082.    line continuation character, and we hope this will be included in
  1083.    the next version of VB.
  1084.    
  1085.    There are a few tricks you can use to reduce line length, but
  1086.    unfortunately there is very little to do with DECLARE statements
  1087.    which can get very long.
  1088.    
  1089.    Print your source in landscape   :-/
  1090.  
  1091. 19.  How do I remove/change the picture property of a control at
  1092.    design time?
  1093.    
  1094.    Mark the (bitmap) or (icon) text in the property window and press
  1095.    Del or Backspace. "No!" I hear you cry, "It doesn't work". Well,
  1096.    it does if you first select the object from the combo box at the
  1097.    top of the Properties Window, and then immediately afterwards
  1098.    doubleclick (or paint over) the "(bitmap)" text and press Del.
  1099.    Alternatively, just click on another control, then click back to
  1100.    the first control. Now Del works. Who said "bug"?
  1101.    
  1102.    If you want to paste your picture directly into the VB program by
  1103.    pressing Ctrl-V when you are editing the picture property, you
  1104.    will have to use a semilar procedure: select the control, select
  1105.    the property, press Ctrl-V. If you try it again without
  1106.    deselecting the control first (or selecting it from the combo
  1107.    box), it doesn't work.
  1108.  
  1109. 20.  Is a [foo] VBX/DLL available as shareware/freeware?
  1110.    
  1111.    Part 4 of the FAQ is Adam Harris' excellent "Shareware Custom
  1112.    Controls List". Please consult this list before you post this
  1113.    question.
  1114.    
  1115.    The following type of controls are NOT known to be available as
  1116.    sw/pd/fw for Visual Basic, only as commercial toolboxes (If you
  1117.    feel like making any of these for VB and sharing it for a modest
  1118.    fee, you will become very popular!):
  1119.    
  1120.    a.   ZModem communication control/source
  1121.    
  1122.    b.   Rich Text Format-control or other mixed font/word processor
  1123.       control (rumours indicate that this will be in the Windows 4 API, and
  1124.       therefor available from VB)
  1125.    
  1126.    c.   Matrix math
  1127.    
  1128.    If any of these should be available, please tell us.
  1129.  
  1130. 21.  How do I make my applications screen-resolution independent?
  1131.    
  1132.    There are two methods: Either get a custom control that does the
  1133.    job for you, or you write lots of complicated code in the Load and
  1134.    Resize events.
  1135.    
  1136.    For the first option, check out VideoSoft's $hareware VSVBX.VBX
  1137.    (download VSVBX.ZIP from Cica or mirrors). It has a will of its
  1138.    own, as you will experience, but it's generally better than trying
  1139.    what is described below.
  1140.    
  1141.    For the brave (or stupid), try to write "screen resolution-smart
  1142.    code" in the form's Load event. If the form is resizable (normally
  1143.    it should be), you'll have to put some magic into the Resize event
  1144.    as well. There are 4 rules of thumb:
  1145.    
  1146.    a.   Do not trust the form's height and width properties.  These
  1147.       measure the entire form, not the client area where your controls are.
  1148.       To see this in action, create a simple applet with the only code being
  1149.       in the resize event which resets a line control from 0,0 to the form's
  1150.       width,height properties.  The top left corner is in the client area,
  1151.       the bottom right corner disappears.  The API call GetClientRect will
  1152.       return the size of the client area in pixels.  You can use the screen
  1153.       object's TwipsPerPixelX and TwipsPerPixelY properties to convert from
  1154.       pixels to twips. If that's not enough, GetWindowRect will return the
  1155.       actual size of the entire form, client and non-client areas combined.
  1156.       GetSystemMetrics will return individual pieces of things like border
  1157.       width/hight, caption height, etc.
  1158.    
  1159.    b.   Use the TextWidth and TextHeight properties.  You can use them
  1160.       off the form if all your controls share the same font, otherwise use
  1161.       them off of the given control.  I typically do a TextWidth("X") and
  1162.       TextHeight("X") to get a value which I use as a margin between
  1163.       controls.  I grab these values on startup, and multiply it by 2, 1.5,
  1164.       .75, .5, .25 to get varying margin sizes, depending on how close or
  1165.       far apart I want to space things. If your control has an autosize
  1166.       property, you may want to use it, and then calculate the maximum width
  1167.       of a control in a given "column" of controls on your screen and
  1168.       position all of them accordingly.
  1169.    
  1170.    c.   Try not to resize your controls in the resize event.  You will
  1171.       spawn another resize event in the process.  Of course, you can use a
  1172.       flag to determine whether the resize event is the original event or
  1173.       the spawned one.  Using the load event, and setting the forms borders
  1174.       to fixed minimizes the amount of work you have to do.
  1175.    
  1176.    d.   Make sure you use a consistant scale.  I don't even bother with
  1177.       the scale properties, but instead just convert pixels (from API calls)
  1178.       into twips and be done with it.  If you do use scale properties, be
  1179.       sure you convert your numbers correctly.  I had no end of difficulty
  1180.       when I failed to convert into twips with one number that was used in a
  1181.       series of calculations to position controls.  Also be sure all your
  1182.       controls share the same SCALE -- another nasty problem I had before I
  1183.       gave up on them completely.
  1184.       [Thanks to our generous anonymous source "D"]
  1185.  
  1186. 22.  How do I do Peek and Poke and other low-level stuff? [++]
  1187.    
  1188.    VB provides no mechanism for this.  There are several 3rd party
  1189.    pkgs. which provide this.  Also, this often comes up in regards to
  1190.    the comm ports and you can many times do what you want with the
  1191.    mscomm.vbx.
  1192.    [George Tatge (gat@csn.org)]
  1193.    
  1194.    On The Developer Network Library CD, you'll find the following:
  1195.    
  1196.    VBASM is a Microsoft(R) Visual Basic(R) dynamic-link library (DLL)
  1197.    that
  1198.    helps Visual Basic programmers accomplish tasks that are difficult
  1199.    or
  1200.    impossible using Visual Basic alone. This sample application
  1201.    includes
  1202.    two programs, SNOOPER and TXTALIGN, that demonstrate the DLL's
  1203.    use.
  1204.    The DLL contains many low-level routines such as access to real
  1205.    and
  1206.    protected mode interrupts, port input/output (I/O), peek/poke,
  1207.    control
  1208.    manipulation, and so on. These routines and their associated
  1209.    functions
  1210.    include:
  1211.    
  1212.    * Control Manipulation
  1213.    vbGetCtrlHwnd, vbGetCtrlModel, vbGetCtrlName, vbRecreateCtrl
  1214.    
  1215.    * Pointer and Memory
  1216.    vbGetData, vbGetLongPtr, vbPeek, vbPeekw, vbPoke, vbPokew, vbSAdd,
  1217.    vbSetData, vbSSeg, vbVarPtr, vbVarSeg
  1218.    
  1219.    * Byte/Word/Long Manipulation
  1220.    vbHiByte, vbHiWord, vbLoByte, vbLoWord, vbMakeLong, vbMakeWord
  1221.    
  1222.    * I/O Access
  1223.    vbInp, vbInpw, vbOut, vbOutw
  1224.    
  1225.    * Interrupts
  1226.    vbInterrupt, vbInterruptX, vbRealModeIntX
  1227.    
  1228.    * Others
  1229.    vbGetDriveType, vbShiftLeft, vbShiftRight
  1230.    [Deane Gardner <deaneg@ix.netcom.com> quotes Microsoft]
  1231.    
  1232.    There's a shareware package for in/out routines, btw.
  1233.  
  1234. 23.  Why doesn't "my string" & Chr$(13) do what I want?
  1235.    
  1236.    You need to also add a Chr$(10):  "my string" & Chr$(13) &
  1237.    Chr$(10) will give you a CR and LF.
  1238.    [George Tatge (gat@csn.org)]
  1239.  
  1240. 24.  How do I prevent multiple instances of my program?
  1241.    
  1242.    In VB 3, the property App.PrevInstance is set to True if an older
  1243.    instance of the program already exist.
  1244.    
  1245.    The following piece of code, stolen from MS KB article Q102480,
  1246.    will activate the old instance and then terminate itself:
  1247.    
  1248.      Sub Form_Load ()
  1249.        If App.PrevInstance Then
  1250.           SaveTitle$ = App.Title
  1251.           App.Title = "... duplicate instance."      'Pretty, eh?
  1252.           Form1.Caption = "... duplicate instance."
  1253.           AppActivate SaveTitle$
  1254.           SendKeys "% R", True
  1255.           End
  1256.        End If
  1257.      End Sub
  1258.    
  1259.    As Robert Knienider(rknienid@email.tuwien.ac.at) informed me, this
  1260.    piece of code WILL NOT work for non-English versions of MS Windows
  1261.    where the word for "Restore" does not have "R" as the underlined
  1262.    word. Replace the "R" in the SendKeys line above with "{ENTER}" or
  1263.    "~".
  1264.    
  1265.    Note that you shouldn't prevent multiple instances of your
  1266.    application unless you have a good reason to do so, since this is
  1267.    a very useful feature in MS Windows. Windows will only load the
  1268.    code and dynamic link code *once*, so it (normally) uses much less
  1269.    memory for the later instances than the first.
  1270.  
  1271. 25.  How do I implement an accelerator key for a text box?
  1272.    
  1273.    You want to use a label caption to identify a text box and to act
  1274.    as if it were the text box caption:
  1275.    
  1276.    Example:
  1277.    
  1278.    &Label1  [text1      ]
  1279.    
  1280.    How should I do to set the focus to text1, by typing <ALT>L
  1281.    
  1282.    Make sure that the TabIndex property for the text box is 1 greater
  1283.    than the
  1284.    label's TabIndex. Since a label can't have the focus, the focus
  1285.    will go to the next item in the tab order, which would be the text
  1286.    box.
  1287.    
  1288.    Here's any easy way to set the TabIndex for a busy form. Select
  1289.    the object that should be last in the tab order and then select
  1290.    the TabIndex property. Press 0 (zero), click on the next to last
  1291.    object, press 0, click on the  the next object back, press 0, etc.
  1292.    When you're done, all of the TabIndexes  will be in order, because
  1293.    VB increments all of the higher TabIndexes when you put in a lower
  1294.    number.
  1295.    
  1296.    Many thanks to Jonathan Kinnick and Gary Weinfurther that provided
  1297.    the answer
  1298.    on the FIDO net echo VISUAL_BASIC.
  1299.    [Tiago Leal (Tiago.Leal@p25.f1.n283.z2.gds.nl)]
  1300.  
  1301. 26.  How do I force a file dialogue box to reread the currect disk?
  1302.    
  1303.    If you make a simple dialogue box modelled after common dialogue
  1304.    (normally you should *use* the common dialogue VBX!), you will
  1305.    notice that reselecting the diskette drive will not really rescan
  1306.    the disk. Very annoying to change to C:, and to reselect A: just
  1307.    to make it read the directory of a new diskette.
  1308.    
  1309.    To solve this problem, put
  1310.    
  1311.      drive1.refresh
  1312.      dir1.refresh
  1313.      file1.refresh
  1314.    
  1315.    in the code for the "Rescan" button (or whatever).
  1316.  
  1317. 27.  How do I get the number of free bytes on a disk? [++]
  1318.    
  1319.    As far as I know, there is three possibilities:
  1320.    1. SETUPKIT.DLL as mentioned above
  1321.    2. Arjen Broeze's VBIO.VBX or something like that, with a lot of
  1322.    options.
  1323.    3. Make your own DISKINFO.DLL from the example code in VBKB
  1324.    article Q106553.
  1325.    
  1326.    See Article Q113590 (or Q106553) in Microsoft's VB KnowledgeBase.
  1327.    A short extract follows:
  1328.    
  1329.    Declare Function DiskSpaceFree Lib "SETUPKIT.DLL" () As Long
  1330.    
  1331.    Dim free_space& ' Holds number of bytes returned from
  1332.    DiskSpaceFree().
  1333.    ChDrive "c:"    ' Change to the drive you want to test.
  1334.    free_space& = DiskSpaceFree()
  1335.    [Geir Tutturen(itfgt@nlh10.nlh.no)]
  1336.  
  1337. 28.  Data Control missing from toolbox when I use VB under NT 3.5.
  1338.    Huh?
  1339.    
  1340.    Open the VB.INI file and add these lines under the [Visual Basic]
  1341.    heading:
  1342.    
  1343.    ReportDesign=1
  1344.    DataAccess=1
  1345.    [Danny Ames (dames@pic.net)]
  1346.  
  1347.  
  1348. D.   ADVANCED VISUAL BASIC PROGRAMMING ISSUES
  1349.   
  1350.  
  1351. 1.   How do I tell when an application executed using the SHELL
  1352.    command is finished?
  1353.    
  1354.    Shell() doesn't really return a task handle, it returns an
  1355.    instance handle. Any documentation that says otherwise is wrong.
  1356.    But never mind that; the answer to your question is to use the API
  1357.    call GetModuleUsage.
  1358.    
  1359.      'Put this in the general declarations of your form/module
  1360.      Declare Function GetModuleUsage Lib "Kernel" (ByVal
  1361.      |hModule As Integer) As Integer
  1362.      
  1363.      'Here's where you shell out to the other program
  1364.      intHandle = Shell("PROGRAM.EXE")
  1365.      Do While GetModuleUsage(intHandle) > 0
  1366.         DoEvents
  1367.      Loop
  1368.    [Kenn Nesbitt, Microsoft Consulting Services (kennn@netcom.com)]
  1369.    
  1370.    The FindWindow command can also be used (search the Tips help file
  1371.    for "How VB Can Determine if a Specific Windows Program Is
  1372.    Running"). I have had to use this when the program I shelled to
  1373.    unloaded itself and ran a different EXE. My program thought the
  1374.    shell was done (since the shelled EXE ended), but it really had
  1375.    just "moved on" to another EXE. Generally, the code in cases like
  1376.    this must be customized to fit the situation.
  1377.    [John McGuire (jmcguire@jax.jaxnet.com)]
  1378.  
  1379. 2.   How do I access C style strings?
  1380.    
  1381.    Use the 'lstrlen' and 'lstrcpy' calls found in the Kernel DLL.
  1382.  
  1383. 3.   How can I change the printer Windows uses in code without using
  1384.    the print common dialog? How can I change orientation?
  1385.    
  1386.    You can change the printer the VB 3.0 Printer object is pointing
  1387.    to programmatically (without using the common dialogs). Just use
  1388.    the WriteProfileString API call and rewrite the [WINDOWS],  DEVICE
  1389.    entry in the WIN.INI file!  VB will instantly use the new printer,
  1390.    when the next Printer.Print command is issued. If you get the old
  1391.    printer string before you rewrite it (GetProfileString API call),
  1392.    you can set it back after using a specific printer. This technique
  1393.    is especially useful, when you want to use a FAX printer driver:
  1394.    Select the FAX driver, send your fax by printing to it and switch
  1395.    back to the normal default printer.
  1396.    [Hajo Schmidt (hajo@bwl.bwl.th-darmstadt.de)]
  1397.    
  1398.    It is recommended (and polite, as we're multitasking) to send a
  1399.    WM_WININCHANGE (&H1A) to all windows to tell them of the change.
  1400.    Also, under some circumstances the printer object won't notice
  1401.    that you have changed the default printer unless you do this.
  1402.    
  1403.      Declare Function SendMessage(ByVal hWnd As Integer,
  1404.      |ByVal wMsg As Integer, ByVal wParam As Integer,
  1405.      |lParam As Any) As Long
  1406.      Global Const WM_WININICHANGE = &H1A
  1407.      Global Const HWND_BROADCAST = &HFFFF
  1408.      ' Dummy means send to all top windows.
  1409.      
  1410.      ' Send name of changed section as lParam.
  1411.      lRes = SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0,
  1412.      |ByVal "Windows")
  1413.    [Nic Gibson (nic@skin.demon.co.uk)]
  1414.    
  1415.    To change between landscape and portrait orientation, search of
  1416.    VBKB_FT on "lands*" finds Article ID: Q80185 "How to Set Landscape
  1417.    or Portrait for Printer from VB App".
  1418.    
  1419.    This is an extract:
  1420.    
  1421.    Declare Function Escape% Lib "GDI" (ByVal hDC%, ByVal nEsc%, ByVal
  1422.    nLen%,
  1423.      |lpData As Any, lpOut As Any)
  1424.    
  1425.    Sub Command1_Click ()
  1426.       Const PORTRAIT = 1
  1427.       Const LANDSCAPE = 2
  1428.       Const GETSETPAPERORIENT = 30
  1429.       Dim Orient As OrientStructure
  1430.       Printer.Print ""
  1431.       Orient.Orientation = LANDSCAPE
  1432.       x% = Escape(Printer.hDC, GETSETPAPERORIENT, Len(Orient), "",
  1433.    Null)
  1434.       Print x%
  1435.    End Sub
  1436.    [Ayn Shipley (ashipley@hookup.net)]
  1437.  
  1438. 4.   Any tips for speeding up VB?
  1439.    
  1440.    Who said "code in C"???? ;-)
  1441.    
  1442.    a.   When SHOWing a form with lots of bound controls, have a blank
  1443.       frame covering everything. Then, in the Form_Activate event, set the
  1444.       Frame.Visible = False. This greatly speeds the display of the form and
  1445.       hides ugly thrashing as the data controls initialize.
  1446.       [Christopher Biow (biow@cs.umd.edu)]
  1447.    
  1448.    b.   Try to keep any Global definitions to a minimum.  Massive numbers
  1449.       of global variables really seem to slow VB Windows down (besides
  1450.       chewing up memory).  In other words, if you've pasted a lot of stuff
  1451.       from the globals.txt file, trim all definitions and variables you
  1452.       don't use in your application.
  1453.    
  1454.    c.   Keep the total number of controls and forms used to a minimum
  1455.       (you've probably already guessed that).
  1456.    
  1457.    d.   Keep fancy graphics to a minimum (another one you know).
  1458.    
  1459.    e.   Try "pre-processing" in the background (using Do_Events).
  1460.       Doesn't really speed anything up, but often there is a lot of "idle"
  1461.       time while the user is selecting menu's, buttons and such - if you can
  1462.       do some calculations, image loading or whatever during this idle time
  1463.       your user perceives the application is faster than it really is.
  1464.    
  1465.    f.   Hide often-used forms rather than unloading them. Unloading saves
  1466.       memory, but it takes longer to re-load a form than to simply "un-hide"
  1467.       it.
  1468.       [Tips b to f by Galen Raben (galenr@gr.hp.com)]
  1469.    
  1470.    The following tip is along the same lines, but with a code sample.
  1471.    They are provided by Andy Dingley (dingbat@codesmth.demon.co.uk):
  1472.    
  1473.    You're limited by the system as to how quickly you can go from
  1474.    calling frmMyForm.Show to being able to type into the controls,
  1475.    but you can make the form *appear* to display faster. One
  1476.    technique is to keep forms loaded, and just switch their
  1477.    visibility on and off. This is heavy on resource usage, and
  1478.    doesn't help for the first time they're shown.
  1479.    
  1480.    Most forms have some processing (eg. querying a table to fill a
  1481.    list box) that goes on when they're first opened, and this is what
  1482.    causes the most serious delay. It's possible to display the form,
  1483.    make its controls appear on screen, then do the slow processing
  1484.    before finally making the form "live". As the user can see things
  1485.    happening, the perceived delay is less obvious.
  1486.    
  1487.    Include the following code in your form:
  1488.    
  1489.      Option Explicit
  1490.      Dim FirstActivation as integer
  1491.      
  1492.      Sub Form_Activate
  1493.         DoEvents   'Allow the _Load event to be seen on screen
  1494.         If FirstActivation Then
  1495.      
  1496.            ' Do all the slow loading stuff here
  1497.            If FillComboBox <> 0 Then
  1498.               Unload Me 'If it all goes horribly wrong, then you
  1499.                         'can call Unload from an _Activate event
  1500.                         '(Which you can't do from the _Load event)
  1501.            End If
  1502.            FirstActivation = False
  1503.         End If
  1504.         Screen.MousePointer = DEFAULT
  1505.      End Sub
  1506.      
  1507.      Sub Form_Load
  1508.         FirstActivation = True
  1509.      End Sub
  1510.      
  1511.    Show the form by using:
  1512.      
  1513.      Screen.MousePointer = HOURGLASS
  1514.      frmMyForm.Show MODAL
  1515.      
  1516.    
  1517.    Bruce Garrett (bruceg@access2.digex.net) had the following tips
  1518.    from his VBITS 93 notes:
  1519.    
  1520.    - Polling a control for its properties directly is 10 to 20
  1521.      times slower then placing the property values you need into
  1522.      variables and testing the value of the variables.
  1523.    
  1524.    - Swap tuning: Modules are not loaded until used; put related
  1525.      code in the same modules, reduce the number of intermodule
  1526.      calls and keep modules small.
  1527.    
  1528.    - Binary file I/O is faster then Text/Random.
  1529.    
  1530.    There was also a lot of discussion about "apparent" speed i.e: how
  1531.    it looks on the screen as opposed to how fast it's chugging
  1532.    internally. It was noted that the cute little flashing menu items
  1533.    and exploding windows in the Mac amounted to a little razzle-
  1534.    dazzle to distract you from how long it took to actually load
  1535.    something and get it on the screen.  Keeping all your forms loaded
  1536.    but hidden until needed was suggested.  Also the use of progress
  1537.    indicators and a simple quickly loaded and drawn startup form.
  1538.    Also preloading data you expect to need.
  1539.  
  1540. 5.   How do I speed up control property access?
  1541.    
  1542.    Instead of using a property in a loop, you will be better off
  1543.    using a normal variable in the loop and then assign the variable
  1544.    once to the property afterwards. Also, when reading a property,
  1545.    you should read it once into a variable instead of using it in a
  1546.    loop.
  1547.    
  1548.    Sometimes it is not possible to simply put contents of a property
  1549.    into a variable. For example, if you are using a list box or you
  1550.    need to conserve memory. In these cases you can send the
  1551.    WM_SetRedraw message to the control to prevent redrawing. You can
  1552.    typically increase the speed 6-10 times - or even more.
  1553.    
  1554.      'Add the following declares:
  1555.      Declare Function SendMessage Lib "User" (ByVal hWnd As
  1556.      |Integer, ByVal wMsg As Integer, ByVal wParam As
  1557.      |Integer, lParam As Any) As Long
  1558.      Const WM_SetRedraw = &HB
  1559.      
  1560.      'Add this to your code:
  1561.      Result% = SendMessage(Text1.hWnd, WM_SetRedraw, 0, 0)
  1562.      'redraw off
  1563.      'Do your stuff here!
  1564.      Result% = SendMessage(Text1.hWnd, WM_SetRedraw, 1, 0)
  1565.      'redraw on
  1566.    
  1567.    This same method applies to list boxes and other controls.
  1568.  
  1569. 6.   How much gain in performance will I get if I write my number
  1570.    crunching routines in C instead of Visual Basic?
  1571.    
  1572.    Probably the best solution to the number crunching problem is to
  1573.    write the number crunching routines as a custom control or a DLL,
  1574.    and plug it into a VB app. VB interface handling is not
  1575.    significantly slower than, say C++, and most of the wait is
  1576.    associated with Windows.
  1577.    
  1578.    Some real world experience speaks volumes about this one:
  1579.    
  1580.    I wrote some time consuming code in VB to solve a combinatorical
  1581.    (does this word exist in English?) problem. The code consists of
  1582.    one main recursive function, which calls itself very often. It
  1583.    took a night to compute a certain problem. I was rather
  1584.    disappointed and then decided to write the central routine in C++.
  1585.    It was a 1:1 transcription. The routine was compiled with the MS
  1586.    C++-Compiler. It took only 22 Minutes for the same problem.
  1587.    Amazing, isn't it? The routine doesn't do any floating point
  1588.    arithmetic, only integer, and handles some arrays. The PC was a
  1589.    33MHz 486. And the second amazing thing is, that a IBM RS6000
  1590.    (560)-Risc-machine needed 17 Min for the same code. I was the only
  1591.    one on the machine. I thought it should be much faster. The MS C++
  1592.    seems to make very fast, optimized code. The optimization was
  1593.    configured to make fast code.
  1594.    [Christoph Steinbeck (steinbeck@uni-bonn.de)]
  1595.  
  1596. 7.   How do you make a TEXTBOX read only? Or, how do I prevent the
  1597.    user from changing the text in a TEXTBOX?
  1598.    
  1599.    There's a lot of ideas on this one. You can grab the _KeyPress and
  1600.    _KeyDown events and set them to zero. However, the best idea is to
  1601.    use the Windows API SendMessage function to tell the control to
  1602.    become read-only:
  1603.    
  1604.      'After making the following declarations...
  1605.      Global Const WM_USER = &H400
  1606.      Global Const EM_SETREADONLY = (WM_USER + 31)
  1607.      Declare Function SendMessage Lib "User" (ByVal hWnd As
  1608.      |Integer ByVal wMsg As Integer, ByVal wParam As
  1609.      |Integer, lParam As Any) As Long
  1610.      
  1611.      'Then Try:
  1612.      SendMessage(Text1.hWnd, EM_SETREADONLY, 1, 0)
  1613.      [Pete Jones (pjones@csi.compuserve.com)]
  1614.    
  1615.    This will still allow the user to copy *from* the text box. If you
  1616.    need to disable this (why?), steal the Ctrl-C in the _KeyPress
  1617.    event.
  1618.  
  1619. 8.   How can I create a VBX?
  1620.    
  1621.    VBXs (Visual Basic eXtensions) are practically always written is C
  1622.    (Borland C++, but mainly MS VC++). You should refer to the
  1623.    _Control Development Guide_ (in VB Professional Features Vol. I)
  1624.    and any relevant documentation for your compiler. Followup
  1625.    questions should normally be directed to comp.os.ms-
  1626.    windows.programmer.* or comp.lang.c*.
  1627.    
  1628.    There are some example VBX's with C code supplied with VB3 Pro.
  1629.    You'll find them under the directory [VB]\CDK.
  1630.  
  1631. 9.   How do you change the system menu (on the Control-Menu Box)?
  1632.    
  1633.    You can turn off the minimize and maximize menu options by
  1634.    changing properties, but what if you need to remove the "close"
  1635.    option?
  1636.    
  1637.      'Make the following declares.
  1638.      Declare Function GetSystemMenu Lib "User" (ByVal hWnd
  1639.      |As Integer, ByVal bRevert As Integer) As Integer
  1640.      Declare Function RemoveMenu Lib "User" (ByVal hMenu
  1641.      |As Integer, ByVal nPosition As Integer, ByVal wFlags As
  1642.      |Integer) As Integer
  1643.      Global Const MF_BYPOSITION=&H400
  1644.      
  1645.      'Use the following code to remove the "close" option.
  1646.      SystemMenu% = GetSystemMenu (hWnd, 0)
  1647.      Res% = RemoveMenu(SystemMenu%,6, MF_BYPOSITION)
  1648.      '(also remove the separator line)
  1649.      Res% = RemoveMenu(SystemMenu%,6, MF_BYPOSITION)
  1650.    
  1651.    Adding menu items to the control menu is more complicated, since
  1652.    you need to respond to the events triggered when the user selects
  1653.    the new options. The newest Message Blaster (msgblast.vbx, see
  1654.    details in beginning of FAQ about how to get files) contains
  1655.    example code.
  1656.  
  1657. 10.  How do I play MID, WAV or other multimedia files?
  1658.    
  1659.    Use the MSMCI.VBX, provided with VB/Win Pro 3.0. You can also
  1660.    declare and call the MM-functions manually:
  1661.    
  1662.      Declare Function mciExecute Lib "MMSystem"
  1663.      |(ByVal FileName as String) As Integer
  1664.      
  1665.      Sub Form1_Click ()
  1666.          iResult = mciExecute("Play c:\windows\mkmyday.wav")
  1667.      End Sub
  1668.    
  1669.    Also:
  1670.    
  1671.    Playing a WAV file is covered in the VB Tips help file (there is a
  1672.    Windows call that is for this specificially; see below). The
  1673.    routine won't play MIDI files or other sound formats, however.
  1674.    
  1675.    Declare Function sndPlaySound Lib "MMSYSTEM.DLL"
  1676.     |(ByVal WavFile$, ByVal Flags%) As Integer
  1677.    Global Const SND_SYNC = &H0
  1678.    Global Const SND_ASYNC = &H1
  1679.    Global Const SND_NODEFAULT = &H2
  1680.    Global Const SND_LOOP = &H8
  1681.    Global Const SND_NOSTOP = &H10
  1682.    Global Const SND_USUAL = SND_ASYNC And SND_NODEFAULT
  1683.    [John McGuire (jmcguire@jax.jaxnet.com)]
  1684.  
  1685. 11.  How can I call a 'hidden' DOS program from VB?
  1686.    
  1687.    If you run a DOS program minimized using the SHELL command, it
  1688.    will never complete. This is because DOS tasks by default are NOT
  1689.    setup to run in the background. The easiest way to get around this
  1690.    is to make a PIF file for the program you need to run with the
  1691.    "Background" option checked. Then SHELL to the PIF file to run the
  1692.    DOS program and it will return control to your VB application when
  1693.    it terminates.
  1694.    
  1695.    Tip: If you edit or replace the _DEFAULT.PIF file in the Windows
  1696.    directory to allow execution in background, this will apply to all
  1697.    DOS boxes that is not run with it's own .pif!
  1698.  
  1699. 12.  How do I do drag & drop between applications?
  1700.    
  1701.    MSGBLAST.ZIP (the famous Message Blaster by Ed Staffin and Kyle
  1702.    Marsh) available on Cica and mirrors tell you *everything* you
  1703.    want to know about this and other advanced stuff. This is now
  1704.    (inexpensive) shareware, but the older freeware version is still
  1705.    supposed to be available. Get the file mentined above for more
  1706.    info.
  1707.    
  1708.    Short glossary for the confused ones  :-)
  1709.    Drag & Drop Client: the form you drop objects to/on
  1710.    Drag & Drop Server: the form you drag object(s) from
  1711.  
  1712. 13.  How do I use GetPrivateProfileString to read from INI files?
  1713.    
  1714.    There's a good example of accessing *.INI files in the Knowledge
  1715.    Base, but here's the basic idea:
  1716.    
  1717.      'You declare these API function as usual:
  1718.      Declare Function GetPrivateProfileString Lib "Kernel"
  1719.      |(ByVal lpApplicationName As String, ByVal lpKeyName
  1720.      |As Any, ByVal lpDefault As String, ByVal
  1721.      |lpReturnedString As String, ByVal nSize As Integer,
  1722.      |ByVal lpFileName As String) As Integer
  1723.      
  1724.      'Then in your code you do like below:
  1725.      strIniFile = "WIN.INI"
  1726.      strSection = "MyProgram"
  1727.      strKey = "Language"
  1728.      strDefault = "English"
  1729.      iLength = 70
  1730.      strReturn = String$(iLength, " ")  'Pad the string first!
  1731.      iResult = GetPrivateProfileString(strSection, strKey,
  1732.      |strDefault, strReturn, iLength, strIniFile)
  1733.    
  1734.    WARNING: Be aware that there was an ERROR in the Windows 3.1 API
  1735.    documentation that came with VB. Here's the scoop:
  1736.    
  1737.    Knowledge Base article Q110826 (DOCERR: GetPrivateProfileString
  1738.    Declaration Incorrect in API) corrects a documentation error for
  1739.    the GetPrivateProfileString function call as described in the
  1740.    Windows version 3.1 API Reference help file that shipped with
  1741.    Microsoft Visual Basic version 3.0 for Windows. The CORRECT
  1742.    declaration is as follows:
  1743.    
  1744.      Declare Function GetPrivateProfileString Lib "Kernel"
  1745.      |(ByVal lpApplicationName As String, ByVal lpKeyName
  1746.      |As Any, ByVal lpDefault As String, ByVal
  1747.      |lpReturnedString As String, ByVal nSize As Integer,
  1748.      |ByVal lpFileName As String) As Integer
  1749.    
  1750.    Note that the "ByVal" keyword was omitted from the second
  1751.    parameter in the online reference. This means that the function is
  1752.    passing the second parameter (lpKeyName) by reference. It needs to
  1753.    be passed by value.
  1754.    
  1755.    The most common problem that occurs when using the incorrect
  1756.    declaration is that when the function is called, it returns a copy
  1757.    of "lpdefault" in the "lpReturnedString" parameter instead of the
  1758.    actual value referenced by KeyName.
  1759.    
  1760.    OOPS: As P. Wierenga (pwiereng@sol.UVic.CA) told me, the same doc
  1761.    error applies to Writeblablabla:
  1762.    
  1763.    DOCERR: WriteProfileString Declaration Incorrect in API Article
  1764.    ID: Q115328
  1765.    
  1766.    The correct declaration is as follows:
  1767.    
  1768.    Declare Function WritePrivateProfileString Lib "Kernel"
  1769.                                     (ByVal lpApplicationName As
  1770.    String,
  1771.                                      ByVal lpKeyName As Any,
  1772.                                      ByVal lpString As Any,
  1773.                                      ByVal lplFileName As String) As
  1774.    Integer
  1775.    
  1776.    (all on one line of course!)
  1777.    
  1778.  
  1779. 14.  How do I implement Undo?
  1780.    
  1781.    For most controls, you will have to keep track of changes
  1782.    yourself. There's no magic involved, just some coding. However, if
  1783.    you use the standard Text box or Combo box, Windows provides a
  1784.    "free" undo function for you!
  1785.      
  1786.      'Do the following declares:
  1787.      Declare Function SendMessage Lib "User" (ByVal hWnd As
  1788.      |Integer, ByVal wMsg As Integer, ByVal wParam As
  1789.      |Integer, lParam As Any) As Long
  1790.      Global Const WM_USER = &h400
  1791.      Global Const EM_UNDO = WM_USER + 23
  1792.      
  1793.      'And in your Undo Sub do the following:
  1794.      UndoResult = SendMessage(myControl.hWnd, EM_UNDO, 0, 0)
  1795.      'UndoResult = -1 indicates an error.
  1796.  
  1797. 15.  How do I create a window with a small title bar as in a floating
  1798.    toolbar?
  1799.    
  1800.    Download the MSGBLAST VBX from ftp.microsoft.com (filename
  1801.    msgblast.zip) or (better) from ftp.cica.indiana.edu or mirrors.
  1802.    The example files provide an example of a form with a small title.
  1803.    When you see it, you'll understand why I haven't include a full
  1804.    explanation here!
  1805.  
  1806. 16.  What is Pseudocode?
  1807.    
  1808.    VB/Win does not generate machine code like most compilers do.
  1809.    Instead it creates what is called pseudocode (a real misnomer,
  1810.    IMO). A good explanation is given below:
  1811.    
  1812.    A bit of history: the original P-code was an instruction set for a
  1813.    "virtual Pascal" machine. This came with a portable Pascal
  1814.    compiler written at ETH in Zuerich. The portable compiler produced
  1815.    instructions for this phony machine which had an instruction set
  1816.    ideally suited to the stack and heap management of Pascal.  To
  1817.    executed portable Pascal programs, you had two choices: either
  1818.    write an interpreter for P-code, or translate the small set of P-
  1819.    code instructions (there were about 80) into assembler; assemble
  1820.    it; and run it at native speed.  Thus "P-code" originally stood
  1821.    for "Portable" or "Pascal" code. The broader meaning, "pseudo-
  1822.    code" came later. P-code was widely popularized by the UCSD Pascal
  1823.    system, a small workstation that was implemented entirely in Pcode
  1824.    and interpreted. It was sold for some years, and one company even
  1825.    re-did the microcode for a PDP-11 microchip to interpret P-code.
  1826.    The original Borland Turbo Pascal had obvious similarities to the
  1827.    UCSD system although it was not interpreted. The dialect was
  1828.    virtually identical.  Today P-code is used extensively in
  1829.    Microsoft apps, for two reasons. First, it is much more compact
  1830.    than  native code; so the apps are smaller. Second, having an
  1831.    interpreter at the core of an app makes it much easier to
  1832.    customize and extend. That is why VB is becoming the heart of the
  1833.    MS major apps.  It is simply not true that P-code apps run much
  1834.    slower than native apps. The slowdown is determined by the
  1835.    granularity of the interpreted routines. If every little thing is
  1836.    an interpreted op, the slowdown might be as much as 3-to-1 for the
  1837.    80x86 architecture, or about 2-to-1 for the Motorola 68000 family
  1838.    (which is better suited to writing interpreters).  But in
  1839.    practice, modern P-code systems have large-scale instructions,
  1840.    each of which is executed by a big compiled subroutine. These subs
  1841.    run at native speed, so the overhead of the interpreter is
  1842.    occasional at worst.
  1843.    [Roger E. Ison (r_ison@csn.org)]
  1844.    
  1845.    It is also possible that since the code may not need recompilation
  1846.    to run on other platforms *if* the run-time interpreter is first
  1847.    ported, VB applications can become very portable. This depends on
  1848.    Microsoft's long-term plans.
  1849.    
  1850.    A note on the word "pseudocode": I wrote above that it is a
  1851.    misnomer, and I stand on that. Pseudocode is *really* the pascal-
  1852.    like (mostly) explanation of an algorithm that is intended for
  1853.    human readers, not computers. But since somehow the term
  1854.    pseudocode stuck to the psaudo-machine-code created by VB the word
  1855.    is used here.
  1856.  
  1857. 17.  Does VB support pointers to functions?
  1858.    
  1859.    No, it does not.
  1860.    [George Tatge (gat@csn.org)]
  1861.  
  1862. 18.  How do I program the Novell NetWare API from VB?
  1863.    
  1864.    Tom Tregilgas (Tom.Tregilgas@InfoB.unisg.ch) had a lot of
  1865.    information on this one. Normally I leave it to the other FAQ
  1866.    parts to list books & how-to-get-info's, but since this topic is
  1867.    very specific and more NetWare than VB I include all the stuff
  1868.    here for your convenience:
  1869.    
  1870.    If you are interested in seeing how Visual Basic can be used for
  1871.    NetWare programming, obtain the following files from your friendly
  1872.    neighboorhood Novell FTP Mirror site.
  1873.    
  1874.    Mirror sites are (according to ftp.novell.com):
  1875.    
  1876.          Novell Germany            ftp.novell.de
  1877.          Netherlands               ftp.rug.nl
  1878.          United Kingdom            ftp.salford.ac.uk
  1879.          Logan, Utah               netlab2.usu.edu
  1880.          New Zealand               tui.lincoln.ac.nz
  1881.          Tuscaloosa, Alabama       risc.ua.edu
  1882.          Ottowa, Ontario, CA       novell.nrc.ca
  1883.          Boston, Mass              bnug.proteon.com
  1884.    
  1885.    novlib\11\nivb.zip              Netware Interface for Visual Basic
  1886.    novlib\11\nwtest.zip            NetWare Test for Visual Basic
  1887.    
  1888.    There are also two Novell App Notes on the subject of using
  1889.    NetWare with Visual Basic (although this is _NOT_ supported by
  1890.    Novell...) which are:
  1891.    
  1892.    October 92      Interfacing Visual Basic for Windows and NetWare
  1893.    July 93         A NetWare Interface for Visual Basic
  1894.    
  1895.    The AppNotes can be obtained by contacting the Novell Research
  1896.    Order Desk, FAX: +1 303 294-0903, Voice 800 377-4136, +1 303 297-
  1897.    2725.  Address as follows:
  1898.    
  1899.    Novell Research Order Desk
  1900.    1601 Park Avenue West
  1901.    Denver, CO 80216-5199
  1902.    
  1903.    AppNotes are $95/year ($135 outside US)
  1904.    
  1905.    Here are a few books which might help you out to figure the calls
  1906.    out:
  1907.    
  1908.    Windows Development on NetWare Systems, Lori Gauthier and Sue
  1909.    Whitehead (c) 1994, Windcrest, Blue Ridge Summit, PA 17294-0850
  1910.    (McGraw-Hill) $34.95 Comes with disk This book also tells you how
  1911.    to "upgrade" to the currently supported SDK calls
  1912.    
  1913.    NetWare System Interface Technical Overview, Novell (c) 1990,1989
  1914.    (Addison-Wesley), $32.95 (describes Novell's C Network Compiler
  1915.    API's)
  1916.    
  1917.    Visual Basic Programmer's Guide to the Windows API, Daniel
  1918.    Appleman Ziff-Davis Press, 5903 Christie Ave, Emeryville, CA
  1919.    94608, $34.95  Comes with disk
  1920.    
  1921.    It should be mentioned that the APIs included with the NIVB are
  1922.    _not_ current, and for this purpose, you should get the Novell SDK
  1923.    kit. Also, Novell will not support NIVB, but you can sometimes get
  1924.    some helpfrom Compu$erve, or from others on the Infobahn <g>
  1925.    
  1926.    Good luck!
  1927.    
  1928.    p.s. It behooves you to become a member in the PDP (Professional
  1929.    Developer's Program) since you get the AppNotes (& Bullets!)
  1930.    for...free.
  1931.    
  1932.    p.p.s. Novell does NOT support the NIVB...
  1933.    
  1934.    p.p.p.s. Also, no docs come with it.  You'll probably need the
  1935.    Client C SDK kit to be able to really _use_ the code.
  1936.    
  1937.    p.p.p.p.s. To make things even better, the calls in NIVB are
  1938.    fairly old, and not of the Client C SDK kit variety.  However,
  1939.    there _are_ books which could help you out, e.g. "NetWare System
  1940.    Interface Technical Overview", by Novell. ISBN:0-201-57027-0,
  1941.    published by Addison-Wesley Publishing co, $32.95 US, $42.95 in
  1942.    Canada.
  1943.    
  1944.    Update:
  1945.    
  1946.    AppNotes are dead, however, Develper Notes live on.  There is one
  1947.    article about NetWare programming with Visual Basic here:
  1948.    
  1949.    July/Aug 94     NetWare Programming in Visual Basic:
  1950.                    Using Apiary's NetWare Client SDK for Visual Basic
  1951.  
  1952. 19.  Visual Basic 4 news [**]
  1953.    
  1954.    Here is the news we have observed (and which was a guess in
  1955.    previous versions of this FAQ)
  1956.    
  1957.    a.   Two versions: 32-bit and 16-bit
  1958.       Like Visual C++ 1.5, VB 4 comes with compilers for the 16-bit API from
  1959.       Windows 3.1 as well as a real 32-bit compiler (or pseudocompiler) for
  1960.       Windows 95 (and NT) bundled together.
  1961.    
  1962.    b.   New features inherited from VBA
  1963.       
  1964.       1)   VB 4.0 is really VB Applications Edition 2.0
  1965. 2)   Line continuation character " _" (space+underscore)
  1966.       
  1967.       3)   WITH statement, known from Pascal, to save typing and make code
  1968.            cleaner. An example:
  1969.         
  1970.              With Form1
  1971.                With Text1
  1972.                  Bold = true
  1973.                  FontName = "New Times Roman"
  1974.                End With
  1975.              End With
  1976.       
  1977.       4)   FOR EACH .. NEXT statement allows you to make changes to a group
  1978.            of objects at once better than FOR..NEXT. Syntax:
  1979.    
  1980.              For Each element In group
  1981.                      [statements]
  1982.                      [Exit For]
  1983.                      [statements]
  1984.              Next [element]
  1985.       
  1986.       5)   OPTIONAL statement allows you to leave some Variant parameteres
  1987.            undefined when calling a user-defined sub or function. Also an ARRAY
  1988.            function that returns an array form a list supplied as parametres, and
  1989.            a special optional ParamArray optional parameter of Variants.
  1990.       
  1991.       6)   Boolean data type. Coded as 16-bit (2-byte), but can only have
  1992.            TRUE or FALSE value.
  1993.       
  1994.       7)   Byte data type (8-bit). Can have values from 0 to 255.
  1995. 8)   FUNCTION can be of user-defined type.
  1996.       
  1997.       9)   OLE Automation allows detailed control over objects taken from
  1998.            ie. Excel or Word.
  1999.       
  2000.       10)  Reusable Objects and Collections, called Classes
  2001.       
  2002.       11)  Property Procedures allows you to add custom properties to form
  2003.            and some other modules.
  2004.       
  2005.       12)  New enhanced development environment, which includes an object
  2006.            browser and allows add-ins. Pro edition also allows creation of your
  2007.            own add-ins. (For some strange reason, the 32-bit version of this does
  2008.            not use Win95 file dialog boxes!)
  2009.       
  2010.       13)  Conditional compilation: allows one source for 32- and 16-bit
  2011.            versions.
  2012. 14)  Data bound DBList, DBCombo, and DBGrid controls! VB 4 uses Jet
  2013. 2.5 engine.
  2014.    
  2015.    c.   VBX is dead. Long live OCX!
  2016.       
  2017.       You may not feel for celebrating this either, but the 32 bit VB 4 will
  2018.       not support the old 16-bit VBX'es. The 16-bit version of VB 4 will
  2019.       support them for backwards compatibility, but be aware that OLE 2 and
  2020.       OCX is the way of the future, at least if Microsoft gets it as they
  2021.       want.
  2022.  
  2023. 20.  How do you change the icon and otherwise manipulate the DOS box?
  2024.    
  2025.    Enclosed is the results of my digging around to enable me to
  2026.    change the icon
  2027.    of a DOS box launched with the SHELL function. It illustrates most
  2028.    aspects
  2029.    of dealing with DOS boxes.
  2030.    
  2031.    Example of launching PIF file minimized and running it in the
  2032.    background (Needs Execute Background box checked in PIF file), and
  2033.    assigning the PIF file a new Icon rather than the default DOS Box
  2034.    Icon.
  2035.    
  2036.    (Note: it seems this method changes the icon of ALL the active DOS
  2037.    boxes)
  2038.    
  2039.    Code follows:
  2040.    x-----------------------------------------------------------------
  2041.    ----x
  2042.    Option Explicit
  2043.    
  2044.    Global Const SWP_NOSIZE = 1
  2045.    Global Const SWP_NOMOVE = 2
  2046.    Global Const SWP_NOACTIVATE = &H10
  2047.    Global Const SWP_SHOWWINDOW = &H40
  2048.    Global Const SWP_HIDEWINDOW = &H80
  2049.    Global Const SWP_FLAGS = SWP_NOMOVE Or SWP_NOSIZE Or
  2050.    SWP_NOACTIVATE
  2051.    Global Const SWP_SHOW = SWP_SHOWWINDOW Or SWP_FLAGS
  2052.    Global Const SWP_HIDE = SWP_HIDEWINDOW Or SWP_FLAGS
  2053.    Global Const HWND_BOTTOM = 1
  2054.    Global Const GCW_HICON = (-14)
  2055.    Global Const GCW_HMODULE = (-16)
  2056.    
  2057.    Declare Function GetModuleUsage Lib "Kernel" (ByVal hWnd%) As
  2058.    Integer
  2059.    Declare Function ExtractIcon Lib "Shell" (ByVal hInst%, ByVal
  2060.    lpExeName$,
  2061.    |ByVal hIcon%) As Integer
  2062.    Declare Function DestroyIcon Lib "User" (ByVal hIcon%) As Integer
  2063.    Declare Function FindWindow Lib "User" (ByVal lpClassName As Any,
  2064.    ByVal
  2065.    |lpCaption As Any) as Integer
  2066.    Declare Function SetWindowPos Lib "User" (ByVal h%, ByVal hb%,
  2067.    ByVal X%,
  2068.    |ByVal y%, ByVal cx%, ByVal cy%, ByVal F%) as Integer
  2069.    Declare Function GetClassWord Lib "User" (ByVal hWnd%, ByVal
  2070.    nIndex%)
  2071.    |As Integer
  2072.    Declare Function SetClassWord Lib "User" (ByVal hWnd%, ByVal
  2073.    nIndex%,
  2074.    |ByVal wNewWord%) As Integer
  2075.    
  2076.    Sub LaunchPif(PifFile as String, IconName as String)
  2077.        Dim Res As Integer     'Return value from API call
  2078.        Dim MyInst As Integer  'Instance handle for this app
  2079.        Dim PifIcon As Integer 'Pif Icon Resource name
  2080.        Dim OldIcon as Integer 'Original Pif Icon resource (default =
  2081.    0)
  2082.        Dim PifhWnd As Integer 'Dos Box Window handle
  2083.        'Launch PIF file
  2084.        PifInst = Shell(PifFile, 6)
  2085.        'Get Instance handle for main MDI Window (assumed to be
  2086.    frmMDI)
  2087.        MyInst = GetClassWord((frmMDI.hWnd), GCW_HMODULE)
  2088.        'Create new Icon resouce by loading Icon from disk file
  2089.        'Check Icon file exists
  2090.        If Dir$(IconName) <> "" Then
  2091.           'Make sure string is null terminated
  2092.           IconName = IconName & Chr$(0)
  2093.           'Create Icon resource in this window
  2094.           PifIcon = ExtractIcon(MyInst, IconName, 0)
  2095.        Else
  2096.           PifIcon = 0
  2097.        End If
  2098.        'Reset Default Icon on DOS Box to PifIcon
  2099.        'Check PIF file still running and Icon resource created
  2100.        If GetModuleUsage(PifInst) <> 0 and PifIcon > 0 Then
  2101.           'Get Pif Window handle
  2102.           PifhWnd = FindWindow(0&, "Window name in PIF file")
  2103.           'Set Icon handle to PifIcon resource
  2104.           OldIcon = SetClassWord(PifhWnd, GCW_HICON, PifIcon)
  2105.           'Hide and show window to get a redraw of the Icon
  2106.           Res = SetWindowPos(PifhWnd, HWND_BOTTOM, 0, 0, 0, 0,
  2107.    SWP_HIDE)
  2108.           Res = SetWindowPos(PifhWnd, HWND_BOTTOM, 0, 0, 0, 0,
  2109.    SWP_SHOW)
  2110.        End If
  2111.    
  2112.        'Wait for PIF file to complete
  2113.        Do While GetModuleUsage(PifInst) <> 0
  2114.           DoEvents
  2115.        Loop
  2116.    
  2117.        If PifIcon > 0 then
  2118.           'Reset Icon to original
  2119.           Res = SetClassWord(PifhWnd, GCW_HICON, OldIcon)
  2120.           'Tidy up by removing PIF Icon resource
  2121.           Res = DestroyIcon(PifIcon)
  2122.        Endif
  2123.    End Sub
  2124.    x-----------------------------------------------------------------
  2125.    ----x
  2126.    [Dr David Baird (BairdD@AgResearch.CRI.NZ)]
  2127.  
  2128. 21.  How do I make the mouse cursor invisible/visible?
  2129.    
  2130.    Use the API call ShowCursor(False) or ShowCursor(True). Just be
  2131.    aware that the Windows cursor is a shared object, so if your
  2132.    process hides it then it must also redisplay it as well. Also the
  2133.    function is not truly "True" or "False" in nature - it is LIFO, so
  2134.    that if your process has for some reason set it "False" multiple
  2135.    times then you must set it "True" the same number of times in
  2136.    order to re-display the cursor. Hard to explain but play with it -
  2137.    you'll see what I mean...
  2138.    [Galen Raben (galenr@hpgrla.gr.hp.com)]
  2139.  
  2140. 22.  How do I create controls dynamically (at run-time)?
  2141.    
  2142.    Search of VBKB_FT on "control* near array*" finds a number of
  2143.    articles, including Article ID: Q79029 "Creating Nested Control
  2144.    Arrays in Visual Basic" This is THE article to read to understand
  2145.    control arrays (plus a number of other neat concepts). In
  2146.    particular, look at the procedure "loadall_click".
  2147.    
  2148.    The key is that you need to create the first instance of
  2149.    your_control (ie. your_control(0)) at design time.
  2150.    [Ayn Shipley (ashipley@hookup.net)]
  2151.  
  2152. 23.  How do I set the Windows wallpaper at runtime?
  2153.    
  2154.    I'm surprised this isn't in the FAQ yet. [ED: now it is!] You need
  2155.    the SystemParametersInfo API function and the SPI_SETDESKWALLPAPER
  2156.    constant.
  2157.    
  2158.    For this you will need the following constants and function
  2159.    declaration...
  2160.    
  2161.    Const SPI_SETDESKWALLPAPER = 20
  2162.    Const SPIF_SENDWININICHANGE = &H2
  2163.    Const SPIF_UPDATEINIFILE = &H1
  2164.    Declare Function SystemParametersInfo Lib "User" (ByVal uAction As
  2165.     |Integer, ByVal uParam As Integer, lpvParam As Any, ByVal
  2166.    fuWinIni As
  2167.     |Integer) As Integer
  2168.    
  2169.    'You then call the function as follows...
  2170.    
  2171.    Result% = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, ByVal
  2172.    BMPFile$,
  2173.     |SPIFlags%)
  2174.    
  2175.    '... where SPIFlags% is 0 if the change is not to be made
  2176.    permanent, or
  2177.    '(SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE) if it is to be
  2178.    carried across
  2179.    'into future Windows sessions.
  2180.    
  2181.    NOTE: Please be certain to include the ByVal keyword before the
  2182.    bitmap
  2183.    filename, as this argument is declared as Any, NOT as ByVal
  2184.    String.
  2185.    [Luke Webber(webber@werple.apana.org.au)]
  2186.  
  2187. 24.  How do I call help files from a VB program? [**]
  2188.    
  2189.    There are 2 ways you can display help files:
  2190.    1) In code
  2191.       a) Using the common dialog control
  2192.       b) Making a winhelp api call
  2193.       (see below for examples)
  2194.    2) Pressing F1 when App.HelpFile is set to your
  2195.       help file.
  2196.       Note - if a control's HelpContextID property is
  2197.       set to the context id of a help topic, that topic
  2198.       will be displayed if the control has focus and the
  2199.       user presses F1, otherwise the contents is displayed.
  2200.    
  2201.    (see Mapping Context-Sensitive Topics, Chapter 6 pg. 117
  2202.     of the Professional Features Book 1 for information on
  2203.     setting the context ids for your help file. Many help
  2204.     authoring tools will generate the context ids for you.)
  2205.    
  2206.    - Include constant.txt in your project
  2207.    - Set App.HelpFile = "c:\yourfile.hlp"
  2208.    - Declare the following function in a .bas module
  2209.      (make sure it is all on one line):
  2210.    
  2211.    'Function for display windows help files
  2212.    Declare Function WinHelp Lib "User" (ByVal hWnd As Integer,
  2213.    ByVal lpHelpFile As String, ByVal wCommand As Integer,
  2214.    dwData As Any) As Integer
  2215.    
  2216.    COMMON DIALOG:
  2217.    ---------------
  2218.    Note - The HelpContext property can only be assigned
  2219.    an integer. The equivalent WinHelp Api call can use a long.
  2220.    In this example the context id is 1000
  2221.    
  2222.    jump to a context id within help file.
  2223.      CMDialog1.HelpFile = "c:\yourfile.hlp"
  2224.      CMDialog1.HelpCommand = HELP_CONTEXT
  2225.      CMDialog1.HelpContext = 1000
  2226.      CMDialog1.Action = 6
  2227.    
  2228.    bring up contents
  2229.      CMDialog1.HelpFile = "c:\yourfile.hlp"
  2230.      CMDialog1.HelpCommand = HELP_CONTENTS
  2231.      CMDialog1.Action = 6
  2232.    
  2233.    bring up search window
  2234.      CMDialog1.HelpFile = "c:\yourfile.hlp"
  2235.      CMDialog1.HelpCommand = HELP_PARTIALKEY
  2236.      CMDialog1.HelpKey = ""
  2237.      CMDialog1.Action = 6
  2238.    
  2239.    quit help
  2240.      CMDialog1.HelpFile = "c:\yourfile.hlp"
  2241.      CMDialog1.HelpCommand = HELP_QUIT
  2242.      CMDialog1.HelpContext = 0
  2243.      CMDialog1.Action = 6
  2244.    
  2245.    
  2246.    WINHELP API:
  2247.    -----------------
  2248.    In the following examples iRetCde is declared as an integer.
  2249.    
  2250.    Jump to context id (e.x., context id is 1000)
  2251.      iRetCde = WinHelp(Me.hWnd, "c:\yourfile.hlp", HELP_CONTEXT,
  2252.    ByVal CLng(1000))
  2253.    
  2254.    bring up contents
  2255.      iRetCde = WinHelp(Me.hWnd, "c:\yourfile.hlp", HELP_CONTENTS,
  2256.    CLng(0))
  2257.    
  2258.    bring up search window
  2259.      iRetCde = WinHelp(Me.hWnd, "c:\yourfile.hlp", HELP_PARTIALKEY,
  2260.    ByVal "")
  2261.    
  2262.    quit help
  2263.      iRetCde = WinHelp(Me.hWnd, "c:\yourfile.hlp", HELP_QUIT,
  2264.    CLng(0))
  2265.    
  2266.    [Blake Miller (bemiller@amoco.com)]
  2267.  
  2268.  
  2269. E.   CALLING THE WINDOWS API AND DLLs IN GENERAL
  2270.   
  2271.  
  2272. 1.   What is the Windows API?
  2273.    
  2274.    The Windows API (Application Program Interface) is a collection of
  2275.    Dynamic-Link Libraries (DLLs) that do most of the common things in
  2276.    Windows. Calls to the Windows API gives you access to routines
  2277.    that do things like drawing menu bars, manipulating bitmaps,
  2278.    playing sound files, and pretty much every other function of
  2279.    Windows.
  2280.  
  2281. 2.   How do I call a DLL?
  2282.    
  2283.    Basically, you declare a DLL procedure which you can call in your
  2284.    VB program which in turn passes data to and/or retrieves data from
  2285.    the DLL. You should read the section of the VB manual that talks
  2286.    about calling DLLs ("Chapter 24  Calling Procedures in DLLs" in
  2287.    the VB 3.0 Programmer's Guide). This chapter covers the basics of
  2288.    using the Windows API DLLs and calling DLLs in general. Beyond
  2289.    that you may want to find a good book on this subject since it is
  2290.    too large to cover here (see the Book Listing in the Appendix of
  2291.    the General FAQ - Part 1). Don't be too intimidated!  Using DLLs
  2292.    (especially many of the Windows API functions) is quite easy, once
  2293.    you learn how to call them. In fact, many of the newer DLLs
  2294.    include VB-compatible modules!
  2295.  
  2296. 3.   What about DLL calls that require callbacks?
  2297.    
  2298.    VB does not support callbacks, but various extensions can help.
  2299.    
  2300.    Dan Appleman's "Visual Basic Programmer's Guide to the Windows
  2301.    API" comes with a floppy disk which code samples and tools. It
  2302.    also includes a VBX which supports the callbacks which many API
  2303.    calls require. Dan is also founder and president of Desaware which
  2304.    sells more extensive tools, including SpyWorks, for VB developers.
  2305.    [Walter Hill (whill@netcom.com)]
  2306.  
  2307. 4.   Tips for calling DLLs (such as the Windows API)
  2308.    
  2309.    
  2310.    a.   Using the BYVAL keyword is critical. Using it when you're
  2311.       supposed to call by reference and (more common) not using it when you
  2312.       are to give a value to the external function are the single most
  2313.       common mistakes. Wrong calling convention can often result in a
  2314.       General Protection Fault (GPF) or, even worse, corruption of another
  2315.       applications' data.
  2316.    
  2317.    b.   Check return and parameter types. For return types, a C function
  2318.       declared as "void" means you use a Sub not a Function.
  2319.    
  2320.    c.   Initialize strings by padding it to the necessary length! If you
  2321.       pass a string that is too short to the API it will happily write past
  2322.       the end of the string and possibly corrupt data.
  2323.    
  2324.    d.   Use Option Explicit. A typing error that results in a bug in the
  2325.       VB source will occasionally cause a GPF when you call external code.
  2326. e.   It's a jungle out there! Check parameter values as there is no
  2327. type checking outside VB. If you make a mistake, you'll often get a
  2328. GPF.
  2329.    
  2330.    f.   Save before you run! You may even need to restart Windows after a
  2331.       GPF, since DLL's often aren't unloaded properly. As a second option
  2332.       you can check out WPS (Windows Process Status) which is distributed
  2333.       with VB/Pro and placed in the CDK directory. This utility allows you
  2334.       to kick out any module (EXE, DLL) from memory (shooting yourself in
  2335.       the foot if you want to. WPS is a nice way to find out what DLLs are
  2336.       actually used, but save your work first!).
  2337.  
  2338.  
  2339. F.   VISUAL BASIC AND DATABASES
  2340.   
  2341.  
  2342. 1.   Why can't I use an index with my VB accessed database?
  2343.    
  2344.    There is a mistake in the docs which says you can set the active
  2345.    index for a recordset. You can't. The data control uses the
  2346.    primary key for tables and physical order (I think) for dynasets.
  2347.    [Nic Gibson (nic@skin.demon.co.uk)]
  2348.    
  2349.    NOTE: You can of course set the indexes yourself using code in
  2350.    VB/Pro (Table objects), but Data Control's can't. Sorry for the
  2351.    problems this possible misunderstanding caused!
  2352.    
  2353.    Thanks to John McGuire (jmcguire@jax.jaxnet.com) for clarifying
  2354.    this.
  2355.    
  2356.  
  2357. 2.   "Can't find installable ISAM" or Why does my compiled VB database
  2358.    app generate an error when it ran just fine in the design environment?
  2359.    
  2360.    You can thank Microsoft for documenting this topic so poorly. When
  2361.    you compile your VB database application, you must also have an
  2362.    INI file for it which provides the correct pointers to the
  2363.    appropriate database drivers. Therefore, if your application is
  2364.    named "INVOICE.EXE", you will need to have a properly configured
  2365.    "INVOICE.INI" file in your Windows directory. The file,
  2366.    EXTERNAL.TXT, that came with VB should explain all about it.
  2367.  
  2368. 3.   Is the Access Engine and Visual Basic Pro good enough for
  2369.    database work?
  2370.    
  2371.    That, of course, depends. Generally the answer is "yes", but you
  2372.    may need some third-party add-on products.
  2373.    
  2374.    These are the major weaknesses of VBPro's database functions:
  2375.    
  2376.    a.   Limited data controls: No add, delete or search button; no bound
  2377.       list box or masked edit control and - the worst - no bound grid!
  2378. b.   No run-time query builder ("how good is your user in SQL?") or
  2379. report builder.
  2380. c.   No direct advanced control of the Access 1.1 (or 2) Database
  2381. Engine (ie. security, optimization, etc).
  2382.    
  2383.    d.   SQL us SLOW. Handcoding is much faster (but harder to code)
  2384.    
  2385.    The good news is that lots of companies are willing to sell you
  2386.    products which address one or more of the above weaknesses.
  2387.    
  2388.    Also, if you build a database application with advanced database
  2389.    relations, it can be a good idea to build the database itself with
  2390.    Access and the front-end with VB.
  2391.  
  2392. 4.   How do you avoid the "Invalid use of null" error when reading
  2393.    null values from a database?
  2394.    
  2395.    If you try to retrieve a null value (empty field) from a database,
  2396.    you will get the error: "Invalid use of Null". Here is one way to
  2397.    get around this problem:
  2398.    
  2399.    I've worked around this problem with the following code:
  2400.    
  2401.      TextBox.Text = MyTest.Fields("TestFld") & ""
  2402.    
  2403.    This code converts the Null-Value into an empty string.
  2404.    [Ralf Metzing (rmm@dragon.stgt.sub.org)]
  2405.  
  2406. 5.   What is "NULL"?
  2407.    
  2408.    Contrary to popular belief, Null is not nothing. It's even less
  2409.    than nothing.   8^)
  2410.    
  2411.    The VB documentation describes all the horrors of misunderstanding
  2412.    the infamous NULL. Since people don't read the documentation, we
  2413.    feel like informing that
  2414.    
  2415.      If ThisVarIsNull = NULL then DoSomething
  2416.    
  2417.    will *always* fail, and the DoSomething can't possibly be
  2418.    executed. You *must* use IsNull(ThisVarIsNull) which will return
  2419.    True if the var is Null (phew!).
  2420.    
  2421.    If you want to find out why someone came to think of this strange
  2422.    value, read some relational database theory.
  2423.  
  2424. 6.   How can I access a record by record number?
  2425.    
  2426.    Use a counter or index field - or even better, a Bookmark property
  2427.    - for this.
  2428.    
  2429.    It is *impossible* to ask a relational database system to give you
  2430.    ie. "field number 3 in record number 10" since by definition a
  2431.    relational database does not have row or column numbers. Databases
  2432.    allowing direct access like that is not even remotely relational.
  2433.    
  2434.    Access (and therefore, VB) is about as close to a real relational
  2435.    database system as you can get.
  2436.  
  2437. 7.   How about Access 2.0 compatibility?
  2438.    
  2439.    You need the compatibility layer availability. The file COMLYR.EXE
  2440.    is in the MSBASIC library on Compuserve. This file provides all
  2441.    the items necessary for compatibility between VB 3.0 and Access
  2442.    2.0.
  2443.    [Fred Griffin (72321.3230@compuserve.com)]
  2444.    
  2445.    For unknown reasons you can't install the compatibility layer
  2446.    without Acess 2.0 being installed, even if you just want to open a
  2447.    database from VB that was created by someone else.
  2448.    [Kent Boortz <boortz@sics.se>]
  2449.    
  2450.    The file COMLYR.EXE can be downloaded from ftp.microsoft.com. It
  2451.    is located in the directory /softlib/mslfiles. (NOTE: A "DIR" in
  2452.    this directory is rarely a wise course of action. There is an
  2453.    enormous amount of files im /mslfiles.)
  2454.  
  2455. 8.   Tips for VB database programming:
  2456.    
  2457.    
  2458.    a.   Use Access and QBE. Once it's "working" (even if the parameters
  2459.       are hardcoded), then open up View.SQL and copy the stuff from the SQL
  2460.       window into your VB code. If you need to insert VB variables, try
  2461.       testing this under Access by using parameters instead. They're then
  2462.       nice & easy to spot when it comes to converting into VB - I always
  2463.       call my parameters "PR_xxxx", so I can just search my VB code for this
  2464.       to find any instances that I've missed.
  2465.    
  2466.    b.   It never works first time. So put an error handler into your VB
  2467.       code that copies the contents of SQLStr onto the clipboard, should the
  2468.       query fail. Now it's quick & easy to switch back to Access, find a
  2469.       scratch query and paste the erroneous SQL into that. It's *much*
  2470.       easier to debug a SQL query in Access, after the variables have been
  2471.       merged in, than it is to do it blind from VB.
  2472.    
  2473.    c.   Use carriage returns to break up your SQL. One before each
  2474.       reserved word is sensible. They're not significant in SQL. I assume
  2475.       you're not stupid enough to put them in the middle of field names -
  2476.       unfortunately Debug.Print is!
  2477.    
  2478.    d.   When merging in the contents of a variable (building a SQL query
  2479.       in a VB string), it should *always* be surrounded by an ampersand and
  2480.       3 double quotes, or an ampersand and 2 mixed quotes, depending on your
  2481.       local conventions:
  2482.       
  2483.         SQLStr = SQLStr & "WHERE Username <= """ & Username$ """ "
  2484.       
  2485.         or
  2486.       
  2487.         SQLStr = SQLStr & "WHERE Username <= '" & Username$ "' "
  2488.    
  2489.    e.   If you're using dates, then it will *always* be one quote, a hash
  2490.       and an ampersand:
  2491.       
  2492.         SQLStr = SQLStr & "WHERE Start_Date <= #" &
  2493.         |Format$(CutOffDate,"Long Date") & "# "
  2494.    
  2495.    f.   Another tip with dates is to format them with the long date
  2496.       format, not the short date. This is then safe against the
  2497.       transatlantic reversal of month & day position.
  2498.    
  2499.    g.   If you're merging in a field/table name, enclose it in square
  2500.       brackets. That way the SQL will still be valid if the variable
  2501.       contains spaces:
  2502.       
  2503.         SQLStr = "SELECT * FROM [" & TableName$ "] ;"
  2504.       
  2505.       When building SQL strings in VB, then you'll often do this on several
  2506.       lines, concatenating SQLStr with the new string. If you leave a space
  2507.       at the end of every string, then you can guarantee you won't have
  2508.       problems with the text from successive lines running into each other.
  2509.    
  2510.    h.   If you're using Access 1, you'll keep running into the 1024
  2511.       character limit on the length of a SQL string. Keep the table & field
  2512.       names short, especially if many JOINs are concerned. Using underscores
  2513.       in names is shorter than spaces, as you don't need the extra 2
  2514.       characters for the square brackets around them. If your SQL is
  2515.       slightly too long, then you'll probably see a "Missing semicolon"
  2516.       error, even though the semicolon is obviously there (To you, anyway!).
  2517.    
  2518.    i.   Making a QueryDef is a complicated process that is often slower
  2519.       than executing the query ! Don't mess with the .SQL property, as that
  2520.       is equally slow (Access needs to do a lot of work to turn SQL into its
  2521.       internal query format). Two ways around this: Use ready-built queries,
  2522.       written with Access. If you need to merge in values from variables,
  2523.       then use a query with parameters. Setting parameter values is quick to
  2524.       execute.
  2525.    
  2526.    j.   If you really need to build SQL on the fly -- you need to build
  2527.       an ad hoc query, or to supply table or field names (which can't be
  2528.       done with query parameters), then try using:
  2529.       
  2530.         database.Execute SQLStr
  2531.       
  2532.       As this doesn't build a QueryDef, then it's quick.
  2533.       [Tips a to j by Andy Dingley(dingbat@codesmth.demon.co.uk)]
  2534.    
  2535.    k.   Make sure all Tables, Dynasets, Snapshots, Databases, and other
  2536.       data access objects are properly closed before ending the program. As
  2537.       near as I can tell, the pointers to these objects are not destroyed if
  2538.       your VB program doesn't Close them (including when a program crashes).
  2539.       A Microsoft guy did say he can't find anything that confirms that they
  2540.       close, but (of course) he wouldn't say for certain that they aren't
  2541.       closed. Based on resources after serious crashes (that I couldn't walk
  2542.       the program out of by hand), I don't think they're automatically
  2543.       closed.
  2544.       [John McGuire (jmcguire@jax.jaxnet.com)]
  2545.  
  2546. 9.   How come I get a "No Current Record" error when I use a a Data
  2547.    Control on an empty table?
  2548.    
  2549.    Well, this is a "feature" courtesy of Microsoft.  KB article
  2550.    Q106494 explains this in detail.  Basically, the workaround is to
  2551.    add an empty record to the table before the user can do anything
  2552.    (or before you try to do any Moves on the Table).
  2553.    [George Tatge (gat@csn.org)]
  2554.  
  2555. 10.  How can I speed up my VB database application?
  2556.    
  2557.    KB article Q109830 gives some hints.  Things you should do
  2558.    include:
  2559.    
  2560.    - Use Snapshots when possible.
  2561.    - Use transactions whenever possible.
  2562.    - Use Dynasets when possible.
  2563.    - Use SQL action queries when possible.
  2564.    [George Tatge (gat@csn.org)]
  2565.    
  2566.    Major Weakness: SQL is SLOW! A hand-coded search (with indices) is
  2567.    MUCH faster than an equivalent SQL call, especially with complex
  2568.    search criteria. For example:
  2569.    
  2570.      SELECT * FROM Table WHERE SSN = '555-33-1234' AND Posted #01-31-
  2571.    95#
  2572.    
  2573.    is a lot slower than:
  2574.    
  2575.      Table.Index = "SSN"
  2576.      Table.Seek "=", "555-33-1234"
  2577.      If Not Table.NoMatch Then
  2578.        While Not Table.EOF
  2579.          If Table("SSN") "555-33-1234" Then
  2580.            Table.MoveLast  'Forces an EOF
  2581.          ElseIf Table("Posted") #01-31-95# Then
  2582.            'Do something
  2583.          End If
  2584.          Table.MoveNext
  2585.        Wend
  2586.      End If
  2587.    
  2588.    Granted, it is a LOT more code, but I ran a VERY similar query
  2589.    that took THIRTY HOURS! The equivalent hand-written code took
  2590.    ELEVEN MINUTES! That's 163 times faster! I think basically SQL
  2591.    isn't very good at figuring out which indexes to use (I also think
  2592.    I've read something to the effect that the newer version, 2.0 or
  2593.    2.5, IS better at this).
  2594.    [John McGuire (jmcguire@jax.jaxnet.com)]
  2595.  
  2596. 11.  How do I get a bitmap picture in a field in an Access database?
  2597.    
  2598.    See p.466 of the Visual Basic (3.0) Programmer's Guide. It
  2599.    contains a section called "Using Bound Picture Box and Image
  2600.    Controls". Basically you have to bind the VB PictureBox to a field
  2601.    in the Access DB, set the .Picture property in the PictureBox, and
  2602.    then move to the next record or something. VB will then store your
  2603.    picture in Access in a form in which it can be retrieved by VB in
  2604.    the future.
  2605.    
  2606.    If you store the pictures in Access directly (using Access), VB
  2607.    won't be able to read them (using VB 3.0 and Access 1.1).
  2608.    
  2609.    You can also store the picture's filename as a text field in the
  2610.    database and use LoadPicture() to load that file into the VB
  2611.    PictureBox.
  2612.    [Tim Shea (shea@marcam.com)]
  2613.  
  2614. 12.  What is "Reserved Error -1209"?
  2615.    
  2616.    You will get a Reserved Error [-1209] ("There is no message for
  2617.    this error")
  2618.    when your database is corrupted. Try opening the database using MS
  2619.    Access;
  2620.    if it's corrupted you should get the option to repair it.
  2621.    [Joe Abley (joe_abley@originuk.demon.co.uk)]
  2622.    
  2623.    You should also compact it, after repair. I recommend you add the
  2624.    following to your File menu on your main form:
  2625.    
  2626.      Case ...
  2627.      
  2628.        RepairDatabase Curentdatabasename
  2629.      
  2630.      Case ....
  2631.      
  2632.        On Error resume next
  2633.        Kill "temp.MDB"
  2634.        Name  curentdatabasename as "temp.mdb"
  2635.        on error goto errcompact
  2636.        compactdatabase "temp.mdb", Currentdatabasename
  2637.        kill "temp.mbd"
  2638.        exit sub
  2639.      
  2640.      errcompact:
  2641.        msgbox "compaction failed"
  2642.        name "temp.mdb" as Currentdatabasename
  2643.      
  2644.      Case ...
  2645.    
  2646.    [Ayn Shipley (ashipley@hookup.net) , Kym Wilson]
  2647.  
  2648. 13.  "Cannot perform operation. illegal.." with Paradox 3.5 table(s)
  2649.    
  2650.    Your Paradox table must have a primary key, or it will be read-
  2651.    only no matter    what you set its properties to.
  2652.    [Ayn Shipley (ashipley@hookup.net)]
  2653.  
  2654. 14.  I'm getting error message "Reserved Error [-nnnn] ("There is no
  2655.    message for this error")" from Jet Engine 2.0. Huh?
  2656.    
  2657.    See the Knowledge Base article Q117900 "Reserved Error Numbers
  2658.    Returned by
  2659.    the Jet 2.0 Engine" for a complete list of the new error messages.
  2660.    
  2661.    Extract:
  2662.    "Jet_Error/Message_String
  2663.       -1010 Invalid database ID.
  2664.       -1016 Can't have more than 10 fields in an index.
  2665.       -1029 Database engine hasn't been initialized.
  2666.       -1030 Database engine has already been initialized.
  2667.       -1034 Query support unavailable."
  2668.    [Ayn Shipley (ashipley@hookup.net)]
  2669.  
  2670. 15.  Why do I get "object not an array" when I try reference the
  2671.    fields of a global object variable which I have set to a table?
  2672.    
  2673.    VB has a parser bug which makes it difficult to use database
  2674.    objects        declared in a module from within a form.
  2675.    
  2676.    WORKAROUND: Just perform some _method_ on the table object
  2677.    somewhere _before_ you try to reference fields. Say in a form-
  2678.    based subroutine AAAA_IllBeFirst you have a Tbl.MoveFirst, which
  2679.    is never even executed. Then VB suddenly realises what the object
  2680.    is and all is forgiven.
  2681.    
  2682.    Credit to Luke Webber and "Joe Foster of Borg".
  2683.    [Ayn Shipley (ashipley@hookup.net)]
  2684.  
  2685. 16.  Steps for securing an Access 2.0 database [**]
  2686.    
  2687.    What I started with:
  2688.      A database that I wanted to make secure.
  2689.      Access 2.0 installed on my hard drive.
  2690.      No Access permissions or accounts ever played with under Access.
  2691.    
  2692.    1)  I ran MS Access Workgroup Administrator and created a new
  2693.        SYSTEM.MDA and assigned a unique workgroup id.
  2694.    
  2695.    2)  Ran Access and created a new database, DB1.MDB.
  2696.    
  2697.    3)  Changed the password for the Admin user using Change Password
  2698.    under
  2699.         the Security menu.  Changed the password from nothing to
  2700.    "PASSWORD".
  2701.    
  2702.    4)  Clicked on Users under Security.  Added a new user, "JOEUSER"
  2703.    and made
  2704.        it a member of the Admins and Users groups.
  2705.    
  2706.    5)  Closed Access, deleted the new database I had just created,
  2707.    DB1.MDB,
  2708.        and restarted Access.  Logged in as the new user, "JOEUSER".
  2709.    Created
  2710.        a new database named DB1.MDB.  Changed the password from
  2711.    nothing to=7F
  2712.        "PASSWORD".
  2713.    
  2714.    6)  From the File menu, clicked Add-ins and then Import Database.
  2715.    Imported
  2716.        my database, REAL.MDB, that I wanted to make secure.
  2717.    
  2718.    7)  Went to Permissions under the Security menu and turned off all
  2719.        permissions for all Groups and all Users for the database, all
  2720.    tables,
  2721.        forms, macros, etc.  The only permissions I left on was full
  2722.    permissions
  2723.        for all objects for the new user, "JOEUSER".  After changing
  2724.    the
  2725.        permissions, I closed Access (note that the database I just
  2726.    used was
  2727.        DB1.MDB).
  2728.    
  2729.    8)  I made a backup of my database REAL.MDB and renamed DB1.MDB to
  2730.    REAL.MDB.
  2731.    
  2732.    9)  Opened my VB code and added the line:
  2733.    
  2734.                 SetDefaultWorkspace "JOEUSER", "PASSWORD"
  2735.    
  2736.        right before the line where I open the database.
  2737.    
  2738.    10) Copied the SYSTEM.MDA from my C:\ACCESS directory to the
  2739.    directory
  2740.        where my VB code is.  (Note, I do not have an INI file for my
  2741.    program).
  2742.    
  2743.    11) Ran my VB program and my database can be opened by my program
  2744.    and nobody
  2745.        else.  The SYSTEM.MDA has to be delivered with my program
  2746.    however.
  2747.    
  2748.    See SetDefaultWorkspace and SetDataAccessOption in VB help for
  2749.    more information on how to set up the data access paramaters in an
  2750.    INI file.  Make sure you add error handling for a missing or
  2751.    messed up SYSTEM.MDA file.
  2752.    
  2753.    I think this is a good basic way to prevent people from
  2754.    looking/changing your database.  Possible flaws are looking at a
  2755.    dump of the .EXE file and finding the name and password used to
  2756.    open the database (there are various workarounds for this) and
  2757.    also running a program to look at parameters passed when opening
  2758.    the database (don't know if this is possible and can't think of a
  2759.    workaround if it is).
  2760.    [Justin F. Smith (jsw117@psu.edu)]
  2761.  
  2762.  
  2763. G.   DISTRIBUTING VISUAL BASIC APPLICATIONS
  2764.   
  2765.  
  2766. 1.   What are some tips for using Setup Wizard?
  2767.    
  2768.    There were loads of bugs in the setup utilities supplied with VB3.
  2769.    Be sure to get the newest version of SETUPKIT (usually called
  2770.    SETUPK.EXE or -.ZIP). It is available from the sources listed in
  2771.    the beginning of this document, and in the General FAQ.
  2772.    
  2773.    Alternatively, if you have the older versions, you may have to
  2774.    manually remove the line referring to OLE2UI.DLL in the file
  2775.    SETUPWIZ.INI. See later in this document for dates of newest files
  2776.    on ftp.microsoft.com.
  2777.    
  2778.    Follow the instructions in SETUPK.TXT exactly. The files actually
  2779.    belong in two separate directories. Not placing them correctly can
  2780.    create strange and unusual side effects -- none of them good(!)
  2781.    
  2782.    Set all involved EXE, DLL and VBX files to Read-Only so that the
  2783.    setup program doesn't modify them.
  2784.    [Charles F. Mulks (21667cfm@msu.edu)]
  2785.    
  2786.    A *very* good tip. Actually, make all executables on your system
  2787.    read-only. If not, you can get a sharing violation if you try to
  2788.    run the same DOS executable twice at the same time.
  2789.    
  2790.    Also, the source code for a SETUP program is *included* with VB3
  2791.    Pro. It is quite trivial to tailor it to your specific needs.
  2792.    
  2793.    The question remains: Is SetupWiz good? No! Good enough? Perhaps.
  2794.  
  2795. 2.   Are there restrictions on what I can distribute with my VB
  2796.    program?
  2797.    
  2798.    The documentation tells what parts of the Visual Basic kit you can
  2799.    freely distribute: the VBX files, some DLL's and what the SetupKit
  2800.    includes on your distribution diskettes. Reading software license
  2801.    agreements may be more boring than asking the newsgroup, but is
  2802.    nevertheless a good idea. 8^)
  2803.    
  2804.    There have been some rumours on the newsgroup that you can't
  2805.    redistribute programs written with VB freely. This is nonsense.
  2806.    All applications created with VB can be redistributed freely
  2807.    without royalties (as long as you don't distribute proprietary
  2808.    external files).
  2809.    
  2810.    The rumours probably originated when Microsoft announced that they
  2811.    will not sell kits allowing third-party software to include the
  2812.    Visual Basic for Applications (VBA) system.
  2813.  
  2814. 3.   What alternatives to setup wizard do I have?
  2815.    
  2816.    Perhaps the best one is to simply modify the setup app which is
  2817.    supplied with VB.  Look in your VB directory for the setupkit\
  2818.    setup1 directory.  There you will find everything you need to do a
  2819.    complete setup program.  This sample setup is coded to install a
  2820.    few sample app files and create a program group.  You can comment
  2821.    out those lines and change to your files and program mgr. group.
  2822.    There are also a few global variables you will want to change.
  2823.    All of this is contained in the comments in the code.
  2824.    
  2825.    Using this, and the distribution information in the manual telling
  2826.    you about which files to distribute with your app will make things
  2827.    much easier than using the setup wizard (IMNSHO).
  2828.    
  2829.    There are also several third party setup products available.
  2830.    [George Tatge (gat@csn.org)]
  2831.  
  2832. 4.   Do I need to worry about users who have Progman replacements such
  2833.    as Norton Desktop and PC Tools?
  2834.    
  2835.    Earlier versions of those products and some others do not respond
  2836.    properly to the DLL commands to create groups and items.  More
  2837.    recent versions do.  All you can do in this case is to include
  2838.    some information in your readme.txt file that instructs users of
  2839.    those products to shut them down and start up program manager
  2840.    before installing.
  2841.    [George Tatge (gat@csn.org)]
  2842.  
  2843. 5.   Can I distribute my app without vbrunXXX.dll?
  2844.    
  2845.    If you are sure that your users have it or can get it, you can
  2846.    easily distribute your app without vbrunXXX.dll.  Simply remove
  2847.    the file from your distribution disk or zip file and and ALSO
  2848.    remove it from the setup.lst file.
  2849.    [George Tatge (gat@csn.org)]
  2850.  
  2851. 6.   Why won't my setup program install commdlg.dll et. al.?
  2852.    
  2853.    There are a couple of DLLs that are almost always in use by
  2854.    windows.  Commdlg.dll is the most common example.  When faced with
  2855.    this problem, there is no easy way out.  The full explanation is
  2856.    several pages long and beyond the scope of this FAQ.  The general
  2857.    idea is as follows:
  2858.    
  2859.    Your setup program will need to create a .BAT file to expand and
  2860.    then copy these files.  Then, it will need to shutdown Windows
  2861.    (see ExitWindowsExec API call) and run the .BAT file.  Then it
  2862.    will need to restart windows and continue your setup program.
  2863.    Your setup program should delete the temporary .BAT file that is
  2864.    no longer needed.
  2865.    [George Tatge (gat@csn.org)]
  2866.  
  2867. 7.   Where do I install VBXs and DLLs?
  2868.    
  2869.    PLEASE- this is one place where everybody's life is much easier if
  2870.    you will follow Microsoft's recommendations.  All PUBLIC VBXs and
  2871.    DLLs should be installed in the windows/system directory!  A
  2872.    "PUBLIC" DLL or VBX is any which can be purchased on the open
  2873.    market.  In other words, if another VB programmer might possibly
  2874.    use the same VBX or DLL, install it in the
  2875.    system directory.
  2876.    
  2877.    If you have written private VBXs or DLLs that will never be used
  2878.    by any program but yours, you can install them in the same
  2879.    directory where you install your application files.
  2880.    
  2881.    There are lots of good reasons for doing this, but it makes a
  2882.    short novel to rehearse them all.
  2883.    [George Tatge (gat@csn.org)]
  2884.  
  2885.  
  2886. H.   MISCELLANEOUS TIPS AND INFORMATION
  2887.   
  2888.  
  2889. 1.   Multiple identifiers after the DIM statement can be confusing
  2890.    
  2891.    Some programmers with background from Pascal can try the following
  2892.    
  2893.      Dim iA, iB, iC as Integer
  2894.      
  2895.    and think that all these 3 variables end up as Integer. In fact,
  2896.    the first two end up as default data type, normally Variant.
  2897.    
  2898.    Instead you should do
  2899.    
  2900.      Dim iA as Integer
  2901.      Dim iB as Integer
  2902.      Dim iC as Integer
  2903.      
  2904.    which takes up more space, but gives you room to comment your
  2905.    variables (hint, hint); *or*
  2906.    
  2907.      Dim iA%, iB%, iC%
  2908.      
  2909.    which does the whole job.
  2910.  
  2911. 2.   "Clean up" your project before final EXE compilation.
  2912.    
  2913.    When you are ready to compile your VB project into your 'finished'
  2914.    EXE, be sure to save the project files, exit VB, restart Windows,
  2915.    run VB, load your project and go straight to compiling. Otherwise,
  2916.    your EXE may be larger in file size than necessary due to
  2917.    'garbage' getting included in the EXE. For some reason, VB does
  2918.    not fully clean up all of the previously used variables or objects
  2919.    that you may have been playing with while developing your program
  2920.    so these get included in your EXE even though they aren't used.
  2921.    Other VB users have even advocated saving all the project files as
  2922.    ASCII, then loading the ASCII files before compiling to further
  2923.    "clean up" the resulting EXE file.
  2924.  
  2925. 3.   Multiple END statements can be dangerous; or, The program that
  2926.    refused to terminate.
  2927.    
  2928.    Suggestion: put the END statement used to exit your program *only*
  2929.    in the Form_Unload event of the main form. Whenever you want to
  2930.    end the program, just tell the main form to unload.
  2931.    
  2932.    Some have reported that after their program have (supposedly)
  2933.    terminated, it still appears in the task list. This can happen if
  2934.    you only hide secondary forms and forget to unload them when you
  2935.    end/unload the main form.
  2936.    
  2937.    Also note that the Stop-button on the button-bar of the integrated
  2938.    development environment doesn't really unload anything. It *nukes*
  2939.    the program, which generally is a good idea since it could be a
  2940.    bug in it that caused it to be stuck in an eternal loop or
  2941.    something.
  2942.  
  2943. 4.   What are the latest versions of the various files used by VB?
  2944.    
  2945.    Date       File to download  Updates files   Description
  2946.    3/7/94     BTR110.EXE        BTRV110.DLL     Btrieve IISAM Driver
  2947.    3/7/94     DATAINDX.EXE      DATAINDX.DOC    "Data Access Guide"
  2948.                                                 Index
  2949.    3/7/94     GENERIC.EXE       \VB\CDK\GENERIC Sample custom control
  2950.                                                 source
  2951.    3/7/94     VBGRID.EXE        GRID.VBX        Grid control
  2952.    3/7/94     VBHC505.EXE       HC.EXE, HCP.EXE WinHelp compiler
  2953.    3/7/94     MSAJT.EXE         MSAJT110.DLL    Access Database Engine
  2954.    3/8/94     MSCOMM.EXE        MSCOMM.VBX      Serial
  2955.                                                 Communications\control
  2956.    3/7/94     ORA110.EXE        ORACLE.TXT      Updated ORACLE.TXT file
  2957.    6/27/94    SETUPK.EXE        SETUP.EXE       Setup Toolkit
  2958.    3/7/94     VBRUN300.EXE      VBRUN300.DLL    Visual Basic Runtime
  2959.                                                 Library
  2960.    3/7/94     XBS110.EXE        XBS110.DLL      XBase IISAM Driver
  2961.    
  2962.    There is an article in the Microsoft Knowledge Base that points to
  2963.    each of these files and provides more detailed information about
  2964.    the update. To find these articles, query the Microsoft Knowledge
  2965.    Base using the file name and the word "update3.00".
  2966.    
  2967.    Note the NEW SETUPKIT update!
  2968.    [Thanks to Marks Harrop <harrop@werple.apana.org.au>]
  2969.    
  2970.    Please inform the FAQ maintainer about newer versions.
  2971.  
  2972.  
  2973. I.   VISUAL BASIC FOR APPLICATIONS (VBA)
  2974.   
  2975.  
  2976. 1.   Any tips for VB/Win 3 programmers moving to VBA?
  2977.    
  2978.    You are in for some surprises. VBA is more unlike VB 3 than most
  2979.    people thought. Especially the development environment is very
  2980.    different, and the language puts more emphasis on objects. The
  2981.    latter is a trend you can get used to for VB also.
  2982.    
  2983.    For Excel 5 VBA, be aware that the environment is based on the
  2984.    "workbook" idea Microsoft stole from Borland. Your controls will
  2985.    be placed in one sheet, and the code will be in another.
  2986.    Doubleclicking on the control to open the code window doesn't
  2987.    help. You have to use the "Tools|Assign Macro" menu option.
  2988.    
  2989.    Also, be aware that the list of events is nowhere close to what
  2990.    VB3 supports! No GotFocus, no MouseMove, no nothing. You'll be
  2991.    very confused if you try to look for "events" in the VBA docs!
  2992.  
  2993. 2.   Does VBA support VBXs?
  2994.    
  2995.    No. If Microsoft have its way, VBX is a dead end. There will never
  2996.    be 32-bit VBXs, but OCXs using OLE 2. VBA is more a subset of VB 4
  2997.    than VB 3, but it does not fully support OCX yet. It will, though.
  2998.  
  2999. 3.   How do I access properties on my dialog boxes in VBA?
  3000.    
  3001.    As noted above, VBA is a culture chock to VB programmers. If you
  3002.    create a textbox in VBA, call it txName and try to
  3003.      
  3004.      cMyVar=txName.Text
  3005.    
  3006.    the impolite interpreter will give you a "variable not defined"
  3007.    error.
  3008.    
  3009.    The magic is objects. You have to
  3010.      
  3011.      Dim txName as Object
  3012.      Set txName = DialogSheets("NameDialog".EditBoxes("txName"))
  3013.    
  3014.    And then you can access your properties like you used to in good
  3015.    ol' VB 3. (Anyone volunteer to beat senseless the guy who thought
  3016.    out this?)
  3017.  
  3018. 4.   How do I use database routines from Excel VBA?
  3019.    
  3020.    The documentation is somewhere between sparse and inexistant on
  3021.    this topic. Any info on VBA and SQL would be much appreciated.
  3022.    
  3023.    Here Microsoft breaks the tradition and you *can't* use database
  3024.    objects, at least not the way you do in VB. Also, forget dynasets.
  3025.    
  3026.    I know nothing about databases in VBA. I just bring on the
  3027.    following tips from various magazines:
  3028.    
  3029.    Both SQLOpen and QueryGetData require a 'connection string'.
  3030.    That's about what the doc's say about the parameter. What is it?
  3031.    The doc is also tragically void of useful examples. Someone dug up
  3032.    the following example:
  3033.    
  3034.      "DSN=My data file;DBQ=c:\access\data.mdb;FIL=RedISAM;"
  3035.    
  3036.    which is about as understandable as it looks. If you use an empty
  3037.    string, you get a dialog which also can give you the string into a
  3038.    spreadsheet cell.
  3039.    
  3040.    Also, search for SQLREQUEST in the *main* help file for Excel 5
  3041.    (not the VBA help!) for these examples of connection_string's:
  3042.    
  3043.    dBASE             DSN=NWind;PWD=test
  3044.    SQL Server        DSN=MyServer;UID=dbayer;PWE=123;Database=Pubs
  3045.    ORACLE            DNS=My Oracle Data Source;DBQ=MYSER VER;
  3046.                      |UID=JohnS;PWD=Sesame
  3047.    
  3048.    There's a KnowledgeBase on Excel 5 on ftp.microsoft.com. Last time
  3049.    I looked, it was void of database stuff. Still, it may be a good
  3050.    idea to download it as the situation may have changed now.
  3051.    
  3052.    
  3053.    *** END OF VB/WIN FAQ DOCUMENT ***
  3054.  
  3055. -- 
  3056. Kris Nosack      knosack@park.uvsc.edu
  3057.  
  3058. >>>--->  Be strange, but not a stranger!  <---<<<
  3059.