home *** CD-ROM | disk | FTP | other *** search
- 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
- From: knosack@park.uvsc.edu (Kris Nosack)
- Newsgroups: comp.lang.basic.visual.misc,comp.answers,news.answers
- Subject: FAQ: (8/95) comp.lang.basic.visual.* VB/Win Frequently Asked Questions
- Supersedes: <visual-basic-faq-windows-1-860253040@uib.no>
- Followup-To: comp.lang.basic.visual.misc
- Date: 5 May 1997 14:10:50 -0000
- Organization: Visual Basic FAQ Maintainers
- Lines: 3036
- Approved: news-answers-request@MIT.Edu
- Distribution: world
- Expires: 07 Jun 1997 14:10:45 (Z)
- Message-ID: <visual-basic-faq-windows-1-862841445@uib.no>
- Reply-To: Jan.Haugland@uib.no (Jan Steinar Haugland)
- NNTP-Posting-Host: park.uvsc.edu
- Summary: Frequently asked questions concerning Visual Basic for Windows.
- Keywords: FAQ VISUAL BASIC WINDOWS
- X-Posting-Frequency: Posted on the 5th of each month.
- X-Content-Currency: This FAQ changes regularly. When a saved or printed copy
- is over 6 months old, please obtain a new one.
- Xref: senator-bedfellow.mit.edu comp.lang.basic.visual.misc:158348 comp.answers:25843 news.answers:101825
-
- Posted-By: auto-faq 3.1.1.2
- Archive-name: visual-basic-faq/windows
-
- Last-modified: 22-Aug-95
-
- Covers VB 4.0 (briefly)
-
- *** ATTENTION ***
- A greatly expanded and updated version of this FAQ can now be found on the
- WWW at http://home.sol.no/jansh/vb/default.htm - you are strongly encouraged
- to refer to the WWW version. The WWW version may be "ported" to text and
- posted to the VB newsgroups, but there are no definate plans to do this at
- this time.
-
- Please send all feedback on this document to jansh@online.no (Jan S. Haugland)
- Please don't send VB questions to the FAQ maintainers' private email account.
-
-
- VISUAL BASIC FOR WINDOWS (VB/Win)
- Frequently asked Questions & Answers
- Section IX - B
-
-
- The following symbols indicates new & updated topics:
-
- [++] means topic is updated in this issue
- [**] means topic is new in this issue
-
- Hope this makes it easier for Our Regular Readers ;-)
-
-
-
- TABLE OF CONTENTS:
- ******************
-
- A. PREFACE
- 1. About this document
- 2. Where to get the VB/Win FAQ [++]
- 3. Kudos & comments
-
- B. GENERAL VISUAL BASIC QUESTIONS
- 1. Does VB/Win make standalone .EXE files?
- 2. What is the current version of Visual Basic for Windows? [++]
- 3. Where can I get updated VB and other Microsoft files?
- 4. Help! I am lost on ftp.microsoft.com.
- 5. Where can I get good up-to-date information about VB? [++]
- 6. WWW pages for VB! [**]
- 7. Are there any examples of commercial applications built using
- Visual Basic?
- 8. Limits of VB?
-
- C. COMMON VISUAL BASIC PROGRAMMING QUESTIONS
- 1. What's the difference between MODAL and MODELESS forms? [++]
- 2. When/Why should I use Option Explicit?
- 3. Why does everybody say I should save in TEXT not BINARY?
- 4. Is the Variant type slower than using other variable types?
- 5. How do I make a text box not beep but do something else when I
- hit the Enter key?
- 6. How do I implement an incremental search in list/dir/combo/file
- boxes?
- 7. How do I get the Tab key to be treated like a normal character?
- 8. How do I make an animated icon for my program?
- 9. What is passing by reference?
- 10. I get a "file not found" error on the IIF function when I
- distribute by program. Uh?
- 11. Is there any way to pass a variable to a form apart from using
- global variables?
- 12. How should dates be implemented so they work with other
- language and country formats?
- 13. Can a VB application be an OLE server?
- 14. How do I dial a phone number without using the MSCOMM VBX?
- 15. I have [several] megabytes of memory. Why do I get an "out of
- memory" error? [++]
- 16. How do I mimic a toggle button? [++]
- 17. How do I get my application on top?
- 18. Is there a way to break long lines in VB code?
- 19. How do I remove/change the picture property of a control at
- design time?
- 20. Is a [foo] VBX/DLL available as shareware/freeware?
- 21. How do I make my applications screen-resolution independent?
- 22. How do I do Peek and Poke and other low-level stuff? [++]
- 23. Why doesn't "my string" & Chr$(13) do what I want?
- 24. How do I prevent multiple instances of my program?
- 25. How do I implement an accelerator key for a text box?
- 26. How do I force a file dialogue box to reread the currect disk?
- 27. How do I get the number of free bytes on a disk? [++]
- 28. Data Control missing from toolbox when I use VB under NT 3.5.
- Huh?
-
- D. ADVANCED VISUAL BASIC PROGRAMMING ISSUES
- 1. How do I tell when an application executed using the SHELL
- command is finished?
- 2. How do I access C style strings?
- 3. How can I change the printer Windows uses in code without using
- the print common dialog? How can I change orientation?
- 4. Any tips for speeding up VB?
- 5. How do I speed up control property access?
- 6. How much gain in performance will I get if I write my number
- crunching routines in C instead of Visual Basic?
- 7. How do you make a TEXTBOX read only? Or, how do I prevent the
- user from changing the text in a TEXTBOX?
- 8. How can I create a VBX?
- 9. How do you change the system menu (on the Control-Menu Box)?
- 10. How do I play MID, WAV or other multimedia files?
- 11. How can I call a 'hidden' DOS program from VB?
- 12. How do I do drag & drop between applications?
- 13. How do I use GetPrivateProfileString to read from INI files?
- 14. How do I implement Undo?
- 15. How do I create a window with a small title bar as in a
- floating toolbar?
- 16. What is Pseudocode?
- 17. Does VB support pointers to functions?
- 18. How do I program the Novell NetWare API from VB?
- 19. Visual Basic 4 news [**]
- 20. How do you change the icon and otherwise manipulate the DOS
- box?
- 21. How do I make the mouse cursor invisible/visible?
- 22. How do I create controls dynamically (at run-time)?
- 23. How do I set the Windows wallpaper at runtime?
- 24. How do I call help files from a VB program? [**]
-
- E. CALLING THE WINDOWS API AND DLLs IN GENERAL
- 1. What is the Windows API?
- 2. How do I call a DLL?
- 3. What about DLL calls that require callbacks?
- 4. Tips for calling DLLs (such as the Windows API)
-
- F. VISUAL BASIC AND DATABASES
- 1. Why can't I use an index with my VB accessed database?
- 2. "Can't find installable ISAM" or Why does my compiled VB
- database app generate an error when it ran just fine in the
- design environment?
- 3. Is the Access Engine and Visual Basic Pro good enough for
- database work?
- 4. How do you avoid the "Invalid use of null" error when reading
- null values from a database?
- 5. What is "NULL"?
- 6. How can I access a record by record number?
- 7. How about Access 2.0 compatibility?
- 8. Tips for VB database programming:
- 9. How come I get a "No Current Record" error when I use a a Data
- Control on an empty table?
- 10. How can I speed up my VB database application?
- 11. How do I get a bitmap picture in a field in an Access
- database?
- 12. What is "Reserved Error -1209"?
- 13. "Cannot perform operation. illegal.." with Paradox 3.5
- table(s)
- 14. I'm getting error message "Reserved Error [-nnnn] ("There is
- no message for this error")" from Jet Engine 2.0. Huh?
- 15. Why do I get "object not an array" when I try reference the
- fields of a global object variable which I have set to a table?
- 16. Steps for securing an Access 2.0 database [**]
-
- G. DISTRIBUTING VISUAL BASIC APPLICATIONS
- 1. What are some tips for using Setup Wizard?
- 2. Are there restrictions on what I can distribute with my VB
- program?
- 3. What alternatives to setup wizard do I have?
- 4. Do I need to worry about users who have Progman replacements
- such as Norton Desktop and PC Tools?
- 5. Can I distribute my app without vbrunXXX.dll?
- 6. Why won't my setup program install commdlg.dll et. al.?
- 7. Where do I install VBXs and DLLs?
-
- H. MISCELLANEOUS TIPS AND INFORMATION
- 1. Multiple identifiers after the DIM statement can be confusing
- 2. "Clean up" your project before final EXE compilation.
- 3. Multiple END statements can be dangerous; or, The program that
- refused to terminate.
- 4. What are the latest versions of the various files used by VB?
-
- I. VISUAL BASIC FOR APPLICATIONS (VBA)
- 1. Any tips for VB/Win 3 programmers moving to VBA?
- 2. Does VBA support VBXs?
- 3. How do I access properties on my dialog boxes in VBA?
- 4. How do I use database routines from Excel VBA?
-
-
-
- A. PREFACE
-
- 1. About this document
-
- This document is a compilation of frequently asked questions and
- their answers about Visual Basic for Windows and Visual Basic for
- Applications which have been gathered from posts to the
- comp.lang.basic.visual.* newsgroups. Although efforts have been
- made to find obvious errors, there is no guarantee that the
- information in this document is error-free. Neither the FAQ
- maintainer nor anyone else associated with this document assume
- ANY liability for the content or use of this document. If you find
- any errors, please report them to the address given below.
-
- This FAQ document is protected by international copyright
- regulations. Permission is granted to distribute it freely, both
- in electronic and written format, provided no charge is made.
- Also, do not make changes to this document without the consent of
- the maintainer. Usenet netiquette applies.
-
- 2. Where to get the VB/Win FAQ [++]
-
- Most FAQs (including this one) are available at the anonymous ftp
- archive site "rtfm.mit.edu". All parts of the VB FAQ may be found
- here:
-
- ftp://rtfm.mit.edu/pub/usenet/comp.lang.basic.visual.misc/
-
- **Alternative FTP Sites**:
- The following are alternative sites to rtfm:
-
- North America: ftp.uu.net /usenet/news.answers
- Europe: ftp.uni-paderborn.de /pub/FAQ
- ftp.Germany.EU.net /pub/newsarchive/news.answers
- grasp1.univ-lyon1.fr /pub/faq
- ftp.win.tue.nl /pub/usenet/news.answers
- ftp.sunet.se /pub/usenet
- Asia: nctuccca.edu.tw /USENET/FAQ
- hwarang.postech.ac.kr /pub/usenet/news.answers
-
- (FYI: "rtfm" stands for "Read The ******* Manual". I kid you
- not!)
- [Andre van Meulebrouck (vanmeule@ils.nwu.edu)]
-
- You can also have the VB FAQs e-mailed to you by sending a message
- to
- "mail-server@rtfm.mit.edu" with ONLY the text
-
- send usenet/comp.lang.basic.visual.misc/*
-
- in the BODY of the message.
-
- Alternative mailservers for those who have no ftp access
- ftpmail@decwrl.dec.com or ftpmail@cs.uow.edu.au
- bitftp@pucc.princeton.edu or ftpmail@lth.se
- bitftp@dearn or to bitftp@vm.gmd.de (Europe only)
- ftpmail@ftp.uni-stuttgart.de
- ftpmail@grasp.insa-lyon.fr or ftpmail@ieunet.ie
- bitftp@plearn.edu.pl or bitftp@plearn (Europe)
- ftpmail@doc.ic.ac.uk or ftpmail@sunsite.unc.edu
- [thanks to Jakob Faarvang (jakobf@apexsc.com)]
-
- For all mailservers:
- Use the "index" command to get a list of files available at the
- site.
- Use the "help" command to get more detailed instructions.
- (NOTE: commands are in BODY of mail message!)
-
- Note that a Web-browser like Netscape or Microsoft Internet
- Explorer easily can access an ftp site, view and download files.
- The ftp address on the top of this point (ftp://...) is formatted
- for these browsers; just copy and paste the text directly into the
- "URL" line.
-
- There is currently work going on to make these available in HTML
- format (for Web-browsers). This work is done by Peter Millard
- <millard@buffnet.net>. Look at:
-
- http://www.buffnet.net/~millard/vblinks.htm
-
- or go directly to the copies of his HTML FAQ's (when finished!):
-
- http://www.buffnet.net/~millard/vbgenfaq.htm
- http://www.buffnet.net/~millard/vbdosfaq.htm
-
-
- 3. Kudos & comments
-
- In this document, whenever a long line of code must be split into
- two or more lines of text in the code examples, a | symbol will
- precede each line which should be appended to the line above it.
-
- As the FAQ maintainer, I don't have time to explore all of the
- aspects of Visual Basic. Neither have I time or knowhow to
- personally answer direct technical questions thoroughly. I rely on
- your submissions to improve the quality and inclusiveness of this
- document. If you have found a VB hint, tip, trick, work-around,
- etc., please write it up and send it to me!
-
- Jan Steinar Haugland (jansh@online.no), VB/Win FAQ maintainer
-
- Please note that my first language is not English. You can safely
- ignore all typos, but if you find an error that is so embarrassing
- you can't help pulling your hair and screaming loud, just send me
- a note and I'll correct it quietly. OK?
-
- This document is a collective effort! I would like to thank all
- contributers, and also all those who have given constructive
- feedback. This FAQ is now widely distributed in the net community.
-
- Special thanks to the following people who have made many and
- invaluable contributions to the VB/Win FAQ: Kris Nosack (the
- previous maintainer), Peter Millard, Nic Gibson, Mr. "D" (the
- anonymous contributor), George Tatge (gat@csn.org), Andy Dingley
- (dingbat@codesmth.demon.co.uk), Ayn Shipley (ashipley@hookup.net)
- and those I may have forgotten (sorry).
-
- John McGuire (jmcguire@jax.jaxnet.com), a longtime VB user,
- recently went through the FAQ and found lots of things worth his
- comments. Many of his corrections and suggestions are implemented
- throughout. Thanks!
-
- Everybody: Your help is GREATLY appreciated!
-
- B. GENERAL VISUAL BASIC QUESTIONS
-
-
- 1. Does VB/Win make standalone .EXE files?
-
- VB/Win produces .exe files, but they are not standalone. All
- VB/Win programs must be distributed with the VBRUNx00.DLL file
- (where x is the major version number). This DLL must accompany all
- VB/Win programs, but only one such file should reside on every
- system where VB programs are used.
-
- 2. What is the current version of Visual Basic for Windows? [++]
-
- VB/Win is just between version 3.0 and 4.0 as of writing this. 4.0
- is about to be released around the same time as Windows 95. This
- will contain both a 16-bit and a 32-bit (for NT and Win95) version
- of the developing environment and the intergrated compiler.
-
- 3. Where can I get updated VB and other Microsoft files?
-
- Microsoft Software Library (MSL) is accessible from the following
- services:
-
- - Compu$erve
-
- GO MSL
- Search for <filename.EXE>
-
- - Microsoft Download Service (MSDL)
- Dial (206) 936-6735 to connect to MSDL
-
- - Internet (anonymous FTP)
- ftp ftp.microsoft.com
- Change to the \softlib\mslfiles directory
- (There are a LOT of files in this directory! It is not
- advisable to list all the files unless you have good time.
- See map below.)
-
- 4. Help! I am lost on ftp.microsoft.com.
-
- You no longer have to be! The site have been reorganised, and
- you'll find the file DIRMAP.TXT in root (or whatever it's called
- on a 3.5 NT server).
-
- NOTE: Directory and file names at ftp.microsoft.com are NOT case
- sensitive.
-
- Thanks to Richard Mason (richard@whitney.demon.co.uk) for the map
- he made for us before this long overdue reorganisation, and thanks
- for bringing this to my attention.
-
- 5. Where can I get good up-to-date information about VB? [++]
-
- If you do any VB programming at all, you really should get the
- latest copy of the Microsoft Knowledge Base from one of the
- sources listed above! The filename is VBKB.EXE or VBKB_FT.EXE for
- the version with full text searching. The Knowledge Base is a
- Windows help formatted document that is updated almost monthly.
- (Beware: The files are huge!)
-
- The EXE files on ftp.microsoft.com (and other places) are simple
- self-extracting files. They don't do any automatic updating of
- your system, just dump the file(s) inside them in the current
- directory on your disk, uncompressed and ready for use. Just
- replace the old files on your system with the new files (same
- name, usually).
-
- This FAQ (ahem) is a pretty good source as a digest of many of the
- VB issues that are discussed in the comp.lang.basic.visual.*
- newsgroups, but as such the information contained in this FAQ may
- not have been thoroughly tested or verified.
-
- For easier access to and use of this FAQ document, get the Windows
- Help file format FAQ doc by anonymous ftp to quasar.sba.dal.ca and
- look under /www/hlp. The .HLP version is made by Tim Roberts
- (TJR@SBACOOP.SBA.DAL.CA). This is HIGHLY RECOMMENDED.
-
- Dave McCarter puts out a nice Windows help formatted document
- called "Visual Basic Tips and Tricks". A good resource with
- information that isn't found in the Knowledge Base. It can be
- found by anonymous ftp to ftp.cica.indiana.edu
- /pub/pc/win3/programr/vbasic/ as VBTIPS??.ZIP, where '??' is the
- version number (yes, get the one with the highest number).
-
- [[ Mark Schoonover has started a monthly magazine called _VBWin
- Programmer's Magazine_ that is compiled around the Discussion of
- Microsoft Visual Basic and Related Issues mailing list. This
- magazine is available at the usual ftp sites like cica and at his
- BBS (619) 571-2846. Mark can be contacted at schoon@cts.com. It
- also has its own anonymous ftp site: ftp.cts.com in the
- /pub/schoon/VBWM.Issues directory. - ED: this appears to be down,
- alas. ]]
-
- Jakob Faarvang (jakobf@apexsc.com) maintains the useful CLBV
- Digest:
-
- http://www.apexsc.com/vb/clbv-digest/
-
- and
-
- ftp.apexsc.com:/pub/cgvb/clbv-digest/
-
- Address for him regarding CLBV Digest is clbv-digest-
- editor@apexsc.com
-
- There is presently an effort to put together a VB code library so
- that VB users can share their best - and trickiest - programming
- work. The code library project is being spear headed by Hein Ragas
- who has managed to get a directory on CICA for code snippets to be
- deposited. Stayed tuned to comp.lang.basic.visual.misc for more
- information.
-
- There's a VISBAS-L mailing list for Visual Basic (Thanks to David
- Liden (DL9U@Virginia.EDU) for tracking it down for me when it
- moved). You can subscribe to this mailing list by sending an email
- to
-
- listserv@listserv.tamu.edu
-
- Place the following text in the *body* of the message (no, not the
- subject line):
-
- SUB VISBAS-L Real Name
-
- Where Real Name is just that, *your full real name* not your email
- address. Note that the traffic on this list may overflow your
- mailbox if you have a limited mail buffer. Expect around 40-50
- messages every weekday, a bit less during weekends. Also, to
- unsubscribe, do as above but with "UNSUB" in the body of the
- message to the LISTSERV address, *not* to the VISBAS-L list
- address itself (Believe it or not, we usually receive 2-3
- sub/unsub mails evur day on the list, and we're really fed up!)
- Also, this mail server was split and a new list called VBDATA-L
- was made for Vb database (Jet) related topics. Same procedure for
- registering (SUB VBDATA-L Real Name).
-
- The address for the MS ACCESS listserver is
- listserv@indycms.bitnet or listserv@indycms.iupui.edu The list
- name is ACCESS-L. To subscribe, you follow the same procedure as
- for the other lists.
-
- Sorry, I know no mailservers or other Internet resources dedicated
- to VBA specifically. Send me any information you may have, and
- I'll bring it on.
-
- There are several Usenet newsgroups dedicated to MS Windows
- programming and use. In fact, far too many to list here :-)
-
- NOTE: PLEASE don't post VB stuff to comp.lang.visual. This group
- has *nothing* to do with Visual Basic, and the academics
- discussing "real" visual programming there are very, very annoyed
- at what they call "quasi-visual" stuff and postings about those
- languages to their group.
-
- If you have a Compu$erve account, you will find a forum for Visual
- Basic there, including some support from Microsoft:
-
- MS BASIC Forum (GO MSBASIC)
-
- Message Sections Available: Libraries Available:
- 1 Forum News/Info 1 MS Info and Index
- 2 Setup Wizard/Kit 2 Setup Wizard/Kit
- 3 Data Access Objects 3 Data Access Objects
- 4 The Data Control 4 The Data Control
- 5 Programming Issues 5 Programming Issues
- 6 ODBC Connectivity 6 ODBC Connectivity
- 7 SQL Queries 7 SQL Queries
- 8 ProEdition Controls 8 ProEdition Controls
- 9 Calling API's/DLL's 9 Calling API's/DLL's
- 10 Using OLE/DDE 10 VBWIN-ODBC/Database
- 11 MSCOMM control 11 MSCOMM control
- 12 MCI/MAPI controls 12 MCI/MAPI controls
- 13 DOS Visual Basic 13 DOS Visual Basic
- 14 DOS and Mac Basic 14 DOS and Mac Basic
- 15 Suggestions/Mktg. 15 Suggestions/Mktg.
- 16 CDK 16 CDK
- 17 3rd Party Products 17 3rd Party Products
-
- There are magazines dedicated to VB. The best known is Fawcett
- Technical Publications' _Visual Basic Programmer's Journal_
- (VSPJ). Phone 800-848-5523 (for US credit card orders) or 303-541-
- 0610 (int'l and US other orders), Email 74003.224@compuserve.com
- to Shirley Modric for subscription info. Address is 280 Second
- Street, Suite 200, Los Altos, CA 94022-3603 USA.
-
- From Randy Coates (rcoates@telerama.lm.com):
- I currently subscribe to "Inside Visual BASIC for Windows" from
- the Cobb Group. Although it is a helpful monthly paper (about 14
- pages per publication), I find it to be overpriced when compared
- to VB Programmers Journal. Here is the information anyway:
- Domestic $59/yr ($7.00 each); Outside US $79/yr ($8.50 each)
- Phone: Toll Free: 800-223-8720), Local: 502-491-1900, Customer
- Relations Fax: 502-491-8050, Editorial Department Fax: 502-491-
- 4200. Address: _Inside Visual BASIC for Windows_, 9420 Bunsen
- Parkway, Suite 300, Louisville, KY 40220.
-
- (Note: for completeness other VB magazines should be listed, and I
- would like to receive info on those!)
-
-
- 6. WWW pages for VB! [**]
-
- Carl 'n Gary's Visual Basic HomePage is a good place to start:
-
- http://www.apexsc.com/vb/
-
- This page has hotlinks to lots of goodies, including the FAQs,
- clbv.* archives (with search tool), etc. Send any e-mail inquiries
- (about the page!) to:
-
- vb-admin@apexsc.com
-
- [Gary Wisniewski (gary@apexsc.com)]
-
- 7. Are there any examples of commercial applications built using
- Visual Basic?
-
- Profit by Microsoft was written mostly in Visual Basic. In fact,
- Profit was one of three programs selected as PC Magazine's
- Editor's Choice among Windows small business accounting packages.
- Most of the current version of Quicken was written in VB2. The
- viewer/launcher/installer in the oh-so-popular Way Cool [Topic]
- for Windows series of CD-ROMs was written in VB3.
-
- Microsoft uses VB extensively for smaller utilities. 3 of the
- small apps in the Windows and Windows for Workgroups Resource
- Toolkits are written in VB. Also, if you have the Microsoft
- Bookshelf CD-ROM, you will notice that the MVOPTION.EXE program,
- which is an "options" program for MS Viewer, is created in VB.
-
- Note: The existence of VBX files in a package doesn't ecessarily
- mean that it was written in VB. The most popular C++ compilers
- also support VBXes.
-
- 8. Limits of VB?
-
- Are you kidding? VB have *no* limitations... Uh, yeah ;-)
-
- For starters:
-
- * It's not a true compiler, hence it's slow for non-interface
- stuff (it's of
- course slow for interface stuff as well, but that's *Windows*
- not VB)
-
- * It's not really object-oriented (Try looking for the parent of
- ie. a line
- control, and you'll wonder why it has no hWnd - SpyWorks is an
- add-on you
- may need if this is annoying)
-
- * A statement must be on a single line! (Note: Fixed in VB4!!!!)
-
- * No arrays of constants.
-
- * Your Complaint Here!
-
- An enormous amount of contributers to this topic! Can you guess
- why?
- [Entry suggested by Andre van Meulebrouck (vanmeule@netcom.com)]
-
-
- C. COMMON VISUAL BASIC PROGRAMMING QUESTIONS
-
-
- 1. What's the difference between MODAL and MODELESS forms? [++]
-
- MODAL forms are forms which require user input before any other
- actions can be taken place. In other words, a modal form has
- exclusive focus in that application until it is dismissed. When
- showing a modal form, the controls outside this modal form will
- not take user interaction until the form is closed. The internal
- MsgBox and InputBox forms are examples of modal forms. To show a
- form modally, use the syntax:
-
- MyForm.SHOW 1
-
- MODELESS forms are those which are shown but do not require
- immediate user input. MDI child forms are always modeless. To show
- a form modeless, use the syntax:
-
- MyForm.SHOW
-
- (Thanks to John M. Calvert (calvertj@magi.com) for correcting a
- slightly embarrassing mistake in previous versions of this topic)
-
- 2. When/Why should I use Option Explicit?
-
- Option Explicit forces you to declare all variables before using
- them. Opinions vary greatly on this subject. The main reason to
- use the OPTION EXPLICIT statement at the top of all modules is to
- minimize the amount of bugs introduced into your code by
- misspelling a variable name. Most variants of BASIC (including VB)
- have the capability to create variables 'on the fly' (without any
- declarations). This capability can be a double edged sword.
-
- At the minimum, some suggest using the DEFINT A-Z statement in leu
- of OPTION EXPLICIT. This statement will cause any variables which
- are created on the fly to be created as integers as opposed to
- variant (VB 3.0) or single precision (VB 1.0 and 2.0). (Integers
- take up less memory).
-
- The OPTION EXPLICIT statement causes VB to 'disable' its ability
- to create variables on the fly. Thus, all variables must be
- declared using a DIM or REDIM statement. All variables not
- declared will cause an error when the OPTION EXPLICIT statement is
- used. This will eliminate bugs caused by a misspelled variable.
- The option works module-wide, so you can have some modules with
- and some without this option in your project.
-
- 3. Why does everybody say I should save in TEXT not BINARY?
-
- Actually, saving in binary mode is a bit faster, so why do we
- recommend you to save in text?
-
- If you save the source and the project as text, it becomes ASCII
- (or really, ANSI) code that you can edit with any text editor or
- (if you are careful when you save) word processor. If you save in
- binary, only the VB development environment, current or later
- versions, will understand the code. The Setup Wizard can not scan
- binary projects. Also, source documenters and other programming
- tools usually require text mode. If you use text, you can use a
- simple text editor (ie. notepad) to cut and paste code from other
- source/form modules into your current project. Some 'tricks' (like
- making an array of 1 control into a single non-array control
- again) is easily done with an editor but not that easy in the
- environment. If you want to print your project to paper the
- file|print option in the VB environment is often not good enough;
- you may want to import the text files into your word processor.
- And, finally, if something goes wrong (only one byte is changed!)
- you may be out of luck in binary mode. In text mode you will more
- easily be able to fix it.
-
- 4. Is the Variant type slower than using other variable types?
-
- Generally, yes, if we are talking numeric variable types. The
- Variant type also increases memory overhead. To test the speed
- difference, try the following piece of code in something like a
- button_click event and keep the debug window on the screen:
-
- Dim Va As Variant
- Dim In As Integer
- T1! = Timer
- For i% = 1 To 32766
- Va = i%
- Next i%
- T2! = Timer
- Debug.Print "With variant: "; Format$((T2! - T1!), "0.0000")
- T1! = Timer
- For i% = 1 To 32766
- In = i%
- Next i%
- T2! = Timer
- Debug.Print "With integer: "; Format$((T2! - T1!),"0.0000")
-
- This test shows (on our test system) that integers are ~60%
- faster! However, for strings there where no real difference, or in
- some instances, variants were faster than strings for routines
- with heavy conversion usage. For the best result in your
- application, test your routines directly.
-
- 5. How do I make a text box not beep but do something else when I
- hit the Enter key?
-
- Put "something else" in your _KeyPress event, depending on what
- you really want. This code example makes *nothing* happen, for an
- extended period of time:
-
- Sub Text1_KeyPress (KeyAscii As Integer)
- If KeyAscii = 13 Then '13 is Key_Return
- KeyAscii = 0
- End If
- End Sub
-
- This might not be a very nice thing to do, since your users
- usually have some intention when they press Enter. Often they will
- want to jump to the next control, like the Tab key does. To have
- the Enter key emulate the Tab key action, you will need to add the
- line 'SendKeys "{tab}"' above 'KeyAscii=0' in the example above
- (Yes, I thought KeyAscii=9 works but it doesn't! Tab is obviously
- handled by Windows on a lower level).
-
- By the way, you'll also find this in the Microsoft VB Knowledge
- Base (see KB Q78305 and Q85562).
-
- Note: If MultiLine=True you will *not* want to disable the normal
- behaviour of the Enter key.
-
- 6. How do I implement an incremental search in list/dir/combo/file
- boxes?
-
- This is your lucky day. Dan Champagne (Dan_Champagne@dell.com)
- made some VB code (no DLLs are necessary!) which easily provides
- this feature for your applications:
-
- ' Code by Dan Champagne
- ' 4/18/94
-
- ' This code can be used to do an incremental search in either a
- ' list box, dir, combo, or a file box. The following code is set
- ' for a file box called FILE1. To make it work with a list box, or
- ' a file box with a different name, change all occurences of FILE1
- ' with whatever you or VB has named your list, combo, dir, or file box.
- ' There are two places where you will need to change these. They are
- ' on the last couple of lines in the KeyPress code.
- ' Also, thanks to John Tarr for helping debug the code.
-
- 'In a .BAS file, add the following:
- 'searchme$ is a global vaiable that will keep track of what the
- 'user has typed so far.
- Global searchme$
-
- 'The following needs to be on one line.
- Declare Function SendMessageBystring& Lib "User" ALIAS
- |"SendMessage" (ByVal hWnd%, ByVal wMsg%, ByVal
- |wParam%, ByVal lParam$)
-
- Global Const WM_USER = &H400
- Global Const LB_SELECTSTRING = (WM_USER + 13)
- Global Const LB_FINDSTRING = (WM_USER + 16)
-
- 'In File1 under keydown, add the following:
- 'This checks if the user has pressed the up or down arrow.
- 'If they have, reset searchme$ to "".
- If KeyCode = 40 Or KeyCode = 38 Then
- searchme$ = ""
- End If
-
- 'In File1 under lostfocus, pathchange, patternchange, and click add:
-
- 'If the user has done any of the above, reset the searchme$
- 'string.
- searchme$ = ""
-
- 'In File1 under keypress add:
-
- Dim result&
-
- Select Case KeyAscii
- Case 8 'Backspace
- If searchme$ <> "" Then
- searchme$ = Left$(searchme$, Len(searchme$) - 1)
- Else
- File1.ListIndex = 0
- End If
- KeyAscii = 0
- Exit Sub
- Case 27 'Escape
- searchme$ = ""
- KeyAscii = 0
- Exit Sub
- Case 13 'Enter
- searchme$ = ""
- KeyAscii = 0
- Exit Sub
- Case Asc("a") To Asc("z"), Asc("A") To Asc("Z"), Asc("'"),
- |Asc("."), Asc(" "), Asc("0") To Asc("9")
- searchme$ = searchme$ & Chr$(KeyAscii)
- KeyAscii = 0
- End Select
-
- result& = SendMessageBystring(FILE1.hWnd, LB_FINDSTRING,
- |0, searchme$)
-
- If result& = -1 Then
- searchme$ = Left$(searchme$, Len(searchme$) - 1)
- Else
- result& = SendMessageBystring(FILE1.hWnd, LB_SELECTSTRING,
- |-1, searchme$)
- End If
-
- 7. How do I get the Tab key to be treated like a normal character?
-
- You must set TabStop = False for ALL controls on the active form.
- Then you will be able to insert "tab" (chr 9) characters in
- controls like the text box.
-
- If you feel you need the Tab key to behave "normal" (ie. jump to
- next control) outside this specific control, it is trivial to
- emulate its functionality in code:
-
- Sub Command1_KeyDown (KeyCode As Integer, Shift As Integer)
- If KeyCode = 9 Then
- If Shift = 0 Then
- Command2.SetFocus 'Tab=Next control
- ElseIf Shift = 1 Then
- Command3.SetFocus 'Shift-Tab=Prev.ctrl.
- End If
- End If
- End Sub
-
- ...etc.
-
- 8. How do I make an animated icon for my program?
-
- For an example on how you change the icon for your application as
- it is displayed when it is minimized, see the example REDTOP in
- the \samples\picclip directory for VB/Win 3 Pro. This demonstrates
- a fancy animated icon.
-
- 9. What is passing by reference?
-
- Arguments are either passed by reference or by value. When they
- are passed by value, they cannot be changed by the procedure or
- function they are passed to. They *can* be altered when passed by
- reference, since passing by reference is just passing the address.
-
- Note that procedures are less strict about variable types when you
- use BYVAL. If you declare that your Sub takes a Variant, VB takes
- that seriously and gives a nasty "mismatch error" if you try to
- pass ie. a string to it. Make it ByVal (at the cost of some speed)
- and your sub will be more tolerant.
-
- Also note the following nasty trap: Arguments are passed by
- reference unless enclosed by parentheses or declared using the
- ByVal keyword. [VBWin Language Ref., p. 55]
-
- 10. I get a "file not found" error on the IIF function when I
- distribute by program. Uh?
-
- There's a documentation error, since the manual does not tell you
- that the IIF function requires the file MSAFINX.DLL to be
- distributed with your application. No, IIF is not financial (I
- should know, I study finance right now, or at least I should be
- doing that ;-] ).
-
- 11. Is there any way to pass a variable to a form apart from using
- global variables?
-
- The standard workaround is to put an invisible text box (or
- caption or any other control that suits your use.) on the target
- form and access it by Form.textbox = "value". Then you can use the
- Change event of that control to do anything you want in that form.
- Also, check out the .Tag property which is a "what-you-want"
- property where you can hook any string you want onto a control.
- This property can also be accessed from other modules.
- [Dave Mitton (mitton@dave.enet.dec.com)]
-
- Perhaps a more elegant and flexible way is to implement a stack
- with similar routines. I've done this for a math project, but this
- stack was rather complicated and special purpose (and inspired by
- HP calculators, of whihc I'm a great fan).
-
- Jan G.P. Sijm (jan.sijm@intouch.nl) have implemented some routines
- for general stacks:
-
- '-----------------------------------------------------------------
- ---
- Option Explicit 'Variable declarations
- required
- Dim m_vStack() As Variant 'Stack of variant types
-
- '*-------------
- '* This function will pop a value of a stack of variant
- '* values. The value to be popped (e.g. the variable it
- '* is assigned to) must have one of the basic variable
- '* types that Visual Basic supports. The type of the
- '* return value is determined by the type of the variable
- '* it is assigned to.
- '*
- '* Input : None
- '* Modifies : m_vStack, Stack of variant's
- '* Return : Value of last pushed variant
- '*-------------
- Function stkPop () As Variant
- Dim iM As Integer
- iM = UBound(m_vStack) 'Get current stack size
- stkPop = m_vStack(iM) 'Pop value from stack
- iM = iM - 1 'Decrement number of
- elements
- ReDim Preserve m_vStack(iM) As Variant
- End Function
-
- '*-------------
- '* This function will push a value onto a stack of
- '* variant values. The value to be pushed must have one
- '* of the basic variable types that Visual Basic supports
- '*
- '* Input : vValue, Value to be pushed
- '* Modifies : m_vStack, Stack of variant's
- '*-------------
- Sub stkPush (ByVal vValue As Variant)
- Dim iM As Integer
- On Error Resume Next 'Trap for undimensioned
- array
- iM = UBound(m_vStack) 'Get current array size
- iM = iM + 1 'Increment number of
- elements
- ReDim Preserve m_vStack(iM) As Variant
- m_vStack(iM) = vValue 'Push value on stack
- End Sub
-
- 'This is a short example of how the stack routines can be used in
- a
- 'Visual Basic program. This example will push three parameters
- onto
- 'the stack. A modal dialog is displayed. The dialog will pop the
- 'parameters from the stack and set edit controls with the values.
-
- Sub ShowDialog()
- '
- ' Push the parameters for the dialog
- ' onto the stack and display the dialog
- '
- stkPush sName
- stkPush sStreet
- stkPush sCity
- dlgPerson.Show MODAL
- End Sub
-
- Form_Load()
- '
- ' Pop the parameters of this dialog from the
- ' stack in REVERSED ORDER and place the values
- ' in the appropriate edit controls.
- '
- dfCity.Text = stkPop()
- dfStreet.Text = stkPop()
- dfName.Text = stkPop()
- End Sub
- '-----------------------------------------------------------------
- ---
-
- 12. How should dates be implemented so they work with other language
- and country formats?
-
- If you use ie. MM/DD/YY format dates in a program, you will get
- either a runtime-error (ie. month>12) or the wrong date (ie. March
- 12 instead of December 3) when your program is used in Europe. And
- vice versa, of course. Even Microsoft's own example programs (like
- the MAPI sample) make this stupid mistake and fail miserably. Use
- the Format command to make sure you get the date you want. For
- example:
-
- strTodaysDate = Format[$](Now, "Short Date")
-
- As a side note, Microsoft has taken much heat on the newsgroup for
- VB's bad support for internationalization! Just try to make a date
- literal in source code that works everywhere as a little exercise.
- Answer elsewhere in this document. No prizes :-)
-
- 13. Can a VB application be an OLE server?
-
- No. You'll have to use an external DLL/VBX. If you see any
- examples, please tell the newsgroup.
-
- 14. How do I dial a phone number without using the MSCOMM VBX?
-
- The MSCOMM VBX that comes with VB/Pro is great for creating
- communication programs, but it's overkill for dialing a phone
- number. Try the following code:
-
- PhoneNumber$ = "(123)456-7890"
- Open "COM2:" For Output As #1 'or COM1
- Print #1, "ATDT" & PhoneNumber$ & Chr$(13)
- Close #1
-
- Ian Storrs <exuian@exu.ericsson.se> informed me that he had
- experienced problems with this when the VB program was run from a
- network drive. A file named "COM1" was created on the disk! Jeff
- Rife <jrife@health.org> put in the ":" after COM2 to solve that
- problem!
-
- This trick is probably not a good idea for bigger applications,
- but it's nice for small personal utilities.
-
- 15. I have [several] megabytes of memory. Why do I get an "out of
- memory" error? [++]
-
- This problem and its solution(s) should not be applicable to
- Windows 95.
-
- Unfortunately, Microsoft has been more famous for memory barriers
- than anything else. This is a late descendant of the infamous 640K
- barrier that has been plaguing us for years. Although Windows
- allows the user to access several megabytes of memory, it uses two
- limited (64K) memory areas called User Heap and GDI Heap for some
- specific data structures. Go to the Help|About box in Program
- Manager to see the percentage of free resources in the *most*
- exhausted heap. If these areas are exhausted, you are out of luck.
- VB programs are unfortunately rather greedy on these structures.
- Windows 4 is supposed to free us from this limitation...
-
- Note that every visible control (ie every button) is a window to
- Windows. Every new control takes up some bytes in the precious
- User heap.
-
- Also, there is another way to run out of memory in Windows, not
- related to VB. Windows requires free Upper Memory Area (UMA, also
- called Upper Memory Blocks, not to be confused with High RAM,
- which is the first 64K of extended memory) to do certain tasks. If
- you use QEMM or DOS 6+ MemMaker and you have many device drivers
- (network, etc) this area may have been filled up before you launch
- Windows. You will then be unable to start applications, even
- though you have plenty of free RAM. The problem can be solved with
- careful memory setup, but this is far beyond the scope of this
- FAQ.
-
- On a completely unrelated problem: When you run a program with an
- outline control with some ATI graphics cards, it may crash with
- just that error message. (see Knowledge Base Q100194 PRB: "Some
- ATI Video Drivers Hang When Using MSOUTLIN.VBX")
-
- 16. How do I mimic a toggle button? [++]
-
- The only "fix" we know for this problem is to use a picture or
- image control to mimic the action of a button or button3d control.
- You need two bitmaps, one for buttonup and one for buttondown (and
- perhaps one more for inactive state). This is a kluge, we know.
- Look at the button bar used in the MDINOTE sample program supplied
- with VB for an example of this.
-
- 17. How do I get my application on top?
-
- To force a form to the front of the screen, do the following
- command:
-
- Form1.ZOrder
-
- To make the application *stay* on top, put the Zorder command in a
- Timer event repeatedly called, say, every 1000 msecs. This makes a
- "softer" on-top than other methods, and allows the user to make a
- short peek below the form.
-
- There are two different "Zorder"'s of forms in Windows, both
- implemented internally as linked lists. One is for "normal"
- windows, the other for real "topmost" windows (like the Clock
- application which is distributed with MS Windows). The Zorder
- command above simply moves your window to the top of the "normal"
- window stack. To make your window truly topmost, use the
- SetWindowPos API call like this:
-
- 'Make these declares:
- Declare Function SetWindowPos Lib "user" (ByVal h%,
- |ByVal hb%, ByVal x%, ByVal y%, ByVal cx%, ByVal cy%,
- |ByVal f%) As Integer
- Global Const SWP_NOMOVE = 2
- Global Const SWP_NOSIZE = 1
- Global Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE
- Global Const HWND_TOPMOST = -1
- Global Const HWND_NOTOPMOST = -2
-
- 'To set Form1 as a TopMost form, do the following:
- res% = SetWindowPos (Form1.hWnd, HWND_TOPMOST, 0, 0,
- |0, 0, FLAGS)
- 'if res%=0, there is an error
-
- 'To turn off topmost (make the form act normal again):
- res% = SetWindowPos (Form1.hWnd, HWND_NOTOPMOST, 0, 0,
- |0, 0, FLAGS)
-
- 18. Is there a way to break long lines in VB code?
-
- There is unfortunately no line continuation character in VB/Win
- 3.0. Excel 5 VBA does, however, use Space+Underscore (" _") as a
- line continuation character, and we hope this will be included in
- the next version of VB.
-
- There are a few tricks you can use to reduce line length, but
- unfortunately there is very little to do with DECLARE statements
- which can get very long.
-
- Print your source in landscape :-/
-
- 19. How do I remove/change the picture property of a control at
- design time?
-
- Mark the (bitmap) or (icon) text in the property window and press
- Del or Backspace. "No!" I hear you cry, "It doesn't work". Well,
- it does if you first select the object from the combo box at the
- top of the Properties Window, and then immediately afterwards
- doubleclick (or paint over) the "(bitmap)" text and press Del.
- Alternatively, just click on another control, then click back to
- the first control. Now Del works. Who said "bug"?
-
- If you want to paste your picture directly into the VB program by
- pressing Ctrl-V when you are editing the picture property, you
- will have to use a semilar procedure: select the control, select
- the property, press Ctrl-V. If you try it again without
- deselecting the control first (or selecting it from the combo
- box), it doesn't work.
-
- 20. Is a [foo] VBX/DLL available as shareware/freeware?
-
- Part 4 of the FAQ is Adam Harris' excellent "Shareware Custom
- Controls List". Please consult this list before you post this
- question.
-
- The following type of controls are NOT known to be available as
- sw/pd/fw for Visual Basic, only as commercial toolboxes (If you
- feel like making any of these for VB and sharing it for a modest
- fee, you will become very popular!):
-
- a. ZModem communication control/source
-
- b. Rich Text Format-control or other mixed font/word processor
- control (rumours indicate that this will be in the Windows 4 API, and
- therefor available from VB)
-
- c. Matrix math
-
- If any of these should be available, please tell us.
-
- 21. How do I make my applications screen-resolution independent?
-
- There are two methods: Either get a custom control that does the
- job for you, or you write lots of complicated code in the Load and
- Resize events.
-
- For the first option, check out VideoSoft's $hareware VSVBX.VBX
- (download VSVBX.ZIP from Cica or mirrors). It has a will of its
- own, as you will experience, but it's generally better than trying
- what is described below.
-
- For the brave (or stupid), try to write "screen resolution-smart
- code" in the form's Load event. If the form is resizable (normally
- it should be), you'll have to put some magic into the Resize event
- as well. There are 4 rules of thumb:
-
- a. Do not trust the form's height and width properties. These
- measure the entire form, not the client area where your controls are.
- To see this in action, create a simple applet with the only code being
- in the resize event which resets a line control from 0,0 to the form's
- width,height properties. The top left corner is in the client area,
- the bottom right corner disappears. The API call GetClientRect will
- return the size of the client area in pixels. You can use the screen
- object's TwipsPerPixelX and TwipsPerPixelY properties to convert from
- pixels to twips. If that's not enough, GetWindowRect will return the
- actual size of the entire form, client and non-client areas combined.
- GetSystemMetrics will return individual pieces of things like border
- width/hight, caption height, etc.
-
- b. Use the TextWidth and TextHeight properties. You can use them
- off the form if all your controls share the same font, otherwise use
- them off of the given control. I typically do a TextWidth("X") and
- TextHeight("X") to get a value which I use as a margin between
- controls. I grab these values on startup, and multiply it by 2, 1.5,
- .75, .5, .25 to get varying margin sizes, depending on how close or
- far apart I want to space things. If your control has an autosize
- property, you may want to use it, and then calculate the maximum width
- of a control in a given "column" of controls on your screen and
- position all of them accordingly.
-
- c. Try not to resize your controls in the resize event. You will
- spawn another resize event in the process. Of course, you can use a
- flag to determine whether the resize event is the original event or
- the spawned one. Using the load event, and setting the forms borders
- to fixed minimizes the amount of work you have to do.
-
- d. Make sure you use a consistant scale. I don't even bother with
- the scale properties, but instead just convert pixels (from API calls)
- into twips and be done with it. If you do use scale properties, be
- sure you convert your numbers correctly. I had no end of difficulty
- when I failed to convert into twips with one number that was used in a
- series of calculations to position controls. Also be sure all your
- controls share the same SCALE -- another nasty problem I had before I
- gave up on them completely.
- [Thanks to our generous anonymous source "D"]
-
- 22. How do I do Peek and Poke and other low-level stuff? [++]
-
- VB provides no mechanism for this. There are several 3rd party
- pkgs. which provide this. Also, this often comes up in regards to
- the comm ports and you can many times do what you want with the
- mscomm.vbx.
- [George Tatge (gat@csn.org)]
-
- On The Developer Network Library CD, you'll find the following:
-
- VBASM is a Microsoft(R) Visual Basic(R) dynamic-link library (DLL)
- that
- helps Visual Basic programmers accomplish tasks that are difficult
- or
- impossible using Visual Basic alone. This sample application
- includes
- two programs, SNOOPER and TXTALIGN, that demonstrate the DLL's
- use.
- The DLL contains many low-level routines such as access to real
- and
- protected mode interrupts, port input/output (I/O), peek/poke,
- control
- manipulation, and so on. These routines and their associated
- functions
- include:
-
- * Control Manipulation
- vbGetCtrlHwnd, vbGetCtrlModel, vbGetCtrlName, vbRecreateCtrl
-
- * Pointer and Memory
- vbGetData, vbGetLongPtr, vbPeek, vbPeekw, vbPoke, vbPokew, vbSAdd,
- vbSetData, vbSSeg, vbVarPtr, vbVarSeg
-
- * Byte/Word/Long Manipulation
- vbHiByte, vbHiWord, vbLoByte, vbLoWord, vbMakeLong, vbMakeWord
-
- * I/O Access
- vbInp, vbInpw, vbOut, vbOutw
-
- * Interrupts
- vbInterrupt, vbInterruptX, vbRealModeIntX
-
- * Others
- vbGetDriveType, vbShiftLeft, vbShiftRight
- [Deane Gardner <deaneg@ix.netcom.com> quotes Microsoft]
-
- There's a shareware package for in/out routines, btw.
-
- 23. Why doesn't "my string" & Chr$(13) do what I want?
-
- You need to also add a Chr$(10): "my string" & Chr$(13) &
- Chr$(10) will give you a CR and LF.
- [George Tatge (gat@csn.org)]
-
- 24. How do I prevent multiple instances of my program?
-
- In VB 3, the property App.PrevInstance is set to True if an older
- instance of the program already exist.
-
- The following piece of code, stolen from MS KB article Q102480,
- will activate the old instance and then terminate itself:
-
- Sub Form_Load ()
- If App.PrevInstance Then
- SaveTitle$ = App.Title
- App.Title = "... duplicate instance." 'Pretty, eh?
- Form1.Caption = "... duplicate instance."
- AppActivate SaveTitle$
- SendKeys "% R", True
- End
- End If
- End Sub
-
- As Robert Knienider(rknienid@email.tuwien.ac.at) informed me, this
- piece of code WILL NOT work for non-English versions of MS Windows
- where the word for "Restore" does not have "R" as the underlined
- word. Replace the "R" in the SendKeys line above with "{ENTER}" or
- "~".
-
- Note that you shouldn't prevent multiple instances of your
- application unless you have a good reason to do so, since this is
- a very useful feature in MS Windows. Windows will only load the
- code and dynamic link code *once*, so it (normally) uses much less
- memory for the later instances than the first.
-
- 25. How do I implement an accelerator key for a text box?
-
- You want to use a label caption to identify a text box and to act
- as if it were the text box caption:
-
- Example:
-
- &Label1 [text1 ]
-
- How should I do to set the focus to text1, by typing <ALT>L
-
- Make sure that the TabIndex property for the text box is 1 greater
- than the
- label's TabIndex. Since a label can't have the focus, the focus
- will go to the next item in the tab order, which would be the text
- box.
-
- Here's any easy way to set the TabIndex for a busy form. Select
- the object that should be last in the tab order and then select
- the TabIndex property. Press 0 (zero), click on the next to last
- object, press 0, click on the the next object back, press 0, etc.
- When you're done, all of the TabIndexes will be in order, because
- VB increments all of the higher TabIndexes when you put in a lower
- number.
-
- Many thanks to Jonathan Kinnick and Gary Weinfurther that provided
- the answer
- on the FIDO net echo VISUAL_BASIC.
- [Tiago Leal (Tiago.Leal@p25.f1.n283.z2.gds.nl)]
-
- 26. How do I force a file dialogue box to reread the currect disk?
-
- If you make a simple dialogue box modelled after common dialogue
- (normally you should *use* the common dialogue VBX!), you will
- notice that reselecting the diskette drive will not really rescan
- the disk. Very annoying to change to C:, and to reselect A: just
- to make it read the directory of a new diskette.
-
- To solve this problem, put
-
- drive1.refresh
- dir1.refresh
- file1.refresh
-
- in the code for the "Rescan" button (or whatever).
-
- 27. How do I get the number of free bytes on a disk? [++]
-
- As far as I know, there is three possibilities:
- 1. SETUPKIT.DLL as mentioned above
- 2. Arjen Broeze's VBIO.VBX or something like that, with a lot of
- options.
- 3. Make your own DISKINFO.DLL from the example code in VBKB
- article Q106553.
-
- See Article Q113590 (or Q106553) in Microsoft's VB KnowledgeBase.
- A short extract follows:
-
- Declare Function DiskSpaceFree Lib "SETUPKIT.DLL" () As Long
-
- Dim free_space& ' Holds number of bytes returned from
- DiskSpaceFree().
- ChDrive "c:" ' Change to the drive you want to test.
- free_space& = DiskSpaceFree()
- [Geir Tutturen(itfgt@nlh10.nlh.no)]
-
- 28. Data Control missing from toolbox when I use VB under NT 3.5.
- Huh?
-
- Open the VB.INI file and add these lines under the [Visual Basic]
- heading:
-
- ReportDesign=1
- DataAccess=1
- [Danny Ames (dames@pic.net)]
-
-
- D. ADVANCED VISUAL BASIC PROGRAMMING ISSUES
-
-
- 1. How do I tell when an application executed using the SHELL
- command is finished?
-
- Shell() doesn't really return a task handle, it returns an
- instance handle. Any documentation that says otherwise is wrong.
- But never mind that; the answer to your question is to use the API
- call GetModuleUsage.
-
- 'Put this in the general declarations of your form/module
- Declare Function GetModuleUsage Lib "Kernel" (ByVal
- |hModule As Integer) As Integer
-
- 'Here's where you shell out to the other program
- intHandle = Shell("PROGRAM.EXE")
- Do While GetModuleUsage(intHandle) > 0
- DoEvents
- Loop
- [Kenn Nesbitt, Microsoft Consulting Services (kennn@netcom.com)]
-
- The FindWindow command can also be used (search the Tips help file
- for "How VB Can Determine if a Specific Windows Program Is
- Running"). I have had to use this when the program I shelled to
- unloaded itself and ran a different EXE. My program thought the
- shell was done (since the shelled EXE ended), but it really had
- just "moved on" to another EXE. Generally, the code in cases like
- this must be customized to fit the situation.
- [John McGuire (jmcguire@jax.jaxnet.com)]
-
- 2. How do I access C style strings?
-
- Use the 'lstrlen' and 'lstrcpy' calls found in the Kernel DLL.
-
- 3. How can I change the printer Windows uses in code without using
- the print common dialog? How can I change orientation?
-
- You can change the printer the VB 3.0 Printer object is pointing
- to programmatically (without using the common dialogs). Just use
- the WriteProfileString API call and rewrite the [WINDOWS], DEVICE
- entry in the WIN.INI file! VB will instantly use the new printer,
- when the next Printer.Print command is issued. If you get the old
- printer string before you rewrite it (GetProfileString API call),
- you can set it back after using a specific printer. This technique
- is especially useful, when you want to use a FAX printer driver:
- Select the FAX driver, send your fax by printing to it and switch
- back to the normal default printer.
- [Hajo Schmidt (hajo@bwl.bwl.th-darmstadt.de)]
-
- It is recommended (and polite, as we're multitasking) to send a
- WM_WININCHANGE (&H1A) to all windows to tell them of the change.
- Also, under some circumstances the printer object won't notice
- that you have changed the default printer unless you do this.
-
- Declare Function SendMessage(ByVal hWnd As Integer,
- |ByVal wMsg As Integer, ByVal wParam As Integer,
- |lParam As Any) As Long
- Global Const WM_WININICHANGE = &H1A
- Global Const HWND_BROADCAST = &HFFFF
- ' Dummy means send to all top windows.
-
- ' Send name of changed section as lParam.
- lRes = SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0,
- |ByVal "Windows")
- [Nic Gibson (nic@skin.demon.co.uk)]
-
- To change between landscape and portrait orientation, search of
- VBKB_FT on "lands*" finds Article ID: Q80185 "How to Set Landscape
- or Portrait for Printer from VB App".
-
- This is an extract:
-
- Declare Function Escape% Lib "GDI" (ByVal hDC%, ByVal nEsc%, ByVal
- nLen%,
- |lpData As Any, lpOut As Any)
-
- Sub Command1_Click ()
- Const PORTRAIT = 1
- Const LANDSCAPE = 2
- Const GETSETPAPERORIENT = 30
- Dim Orient As OrientStructure
- Printer.Print ""
- Orient.Orientation = LANDSCAPE
- x% = Escape(Printer.hDC, GETSETPAPERORIENT, Len(Orient), "",
- Null)
- Print x%
- End Sub
- [Ayn Shipley (ashipley@hookup.net)]
-
- 4. Any tips for speeding up VB?
-
- Who said "code in C"???? ;-)
-
- a. When SHOWing a form with lots of bound controls, have a blank
- frame covering everything. Then, in the Form_Activate event, set the
- Frame.Visible = False. This greatly speeds the display of the form and
- hides ugly thrashing as the data controls initialize.
- [Christopher Biow (biow@cs.umd.edu)]
-
- b. Try to keep any Global definitions to a minimum. Massive numbers
- of global variables really seem to slow VB Windows down (besides
- chewing up memory). In other words, if you've pasted a lot of stuff
- from the globals.txt file, trim all definitions and variables you
- don't use in your application.
-
- c. Keep the total number of controls and forms used to a minimum
- (you've probably already guessed that).
-
- d. Keep fancy graphics to a minimum (another one you know).
-
- e. Try "pre-processing" in the background (using Do_Events).
- Doesn't really speed anything up, but often there is a lot of "idle"
- time while the user is selecting menu's, buttons and such - if you can
- do some calculations, image loading or whatever during this idle time
- your user perceives the application is faster than it really is.
-
- f. Hide often-used forms rather than unloading them. Unloading saves
- memory, but it takes longer to re-load a form than to simply "un-hide"
- it.
- [Tips b to f by Galen Raben (galenr@gr.hp.com)]
-
- The following tip is along the same lines, but with a code sample.
- They are provided by Andy Dingley (dingbat@codesmth.demon.co.uk):
-
- You're limited by the system as to how quickly you can go from
- calling frmMyForm.Show to being able to type into the controls,
- but you can make the form *appear* to display faster. One
- technique is to keep forms loaded, and just switch their
- visibility on and off. This is heavy on resource usage, and
- doesn't help for the first time they're shown.
-
- Most forms have some processing (eg. querying a table to fill a
- list box) that goes on when they're first opened, and this is what
- causes the most serious delay. It's possible to display the form,
- make its controls appear on screen, then do the slow processing
- before finally making the form "live". As the user can see things
- happening, the perceived delay is less obvious.
-
- Include the following code in your form:
-
- Option Explicit
- Dim FirstActivation as integer
-
- Sub Form_Activate
- DoEvents 'Allow the _Load event to be seen on screen
- If FirstActivation Then
-
- ' Do all the slow loading stuff here
- If FillComboBox <> 0 Then
- Unload Me 'If it all goes horribly wrong, then you
- 'can call Unload from an _Activate event
- '(Which you can't do from the _Load event)
- End If
- FirstActivation = False
- End If
- Screen.MousePointer = DEFAULT
- End Sub
-
- Sub Form_Load
- FirstActivation = True
- End Sub
-
- Show the form by using:
-
- Screen.MousePointer = HOURGLASS
- frmMyForm.Show MODAL
-
-
- Bruce Garrett (bruceg@access2.digex.net) had the following tips
- from his VBITS 93 notes:
-
- - Polling a control for its properties directly is 10 to 20
- times slower then placing the property values you need into
- variables and testing the value of the variables.
-
- - Swap tuning: Modules are not loaded until used; put related
- code in the same modules, reduce the number of intermodule
- calls and keep modules small.
-
- - Binary file I/O is faster then Text/Random.
-
- There was also a lot of discussion about "apparent" speed i.e: how
- it looks on the screen as opposed to how fast it's chugging
- internally. It was noted that the cute little flashing menu items
- and exploding windows in the Mac amounted to a little razzle-
- dazzle to distract you from how long it took to actually load
- something and get it on the screen. Keeping all your forms loaded
- but hidden until needed was suggested. Also the use of progress
- indicators and a simple quickly loaded and drawn startup form.
- Also preloading data you expect to need.
-
- 5. How do I speed up control property access?
-
- Instead of using a property in a loop, you will be better off
- using a normal variable in the loop and then assign the variable
- once to the property afterwards. Also, when reading a property,
- you should read it once into a variable instead of using it in a
- loop.
-
- Sometimes it is not possible to simply put contents of a property
- into a variable. For example, if you are using a list box or you
- need to conserve memory. In these cases you can send the
- WM_SetRedraw message to the control to prevent redrawing. You can
- typically increase the speed 6-10 times - or even more.
-
- 'Add the following declares:
- Declare Function SendMessage Lib "User" (ByVal hWnd As
- |Integer, ByVal wMsg As Integer, ByVal wParam As
- |Integer, lParam As Any) As Long
- Const WM_SetRedraw = &HB
-
- 'Add this to your code:
- Result% = SendMessage(Text1.hWnd, WM_SetRedraw, 0, 0)
- 'redraw off
- 'Do your stuff here!
- Result% = SendMessage(Text1.hWnd, WM_SetRedraw, 1, 0)
- 'redraw on
-
- This same method applies to list boxes and other controls.
-
- 6. How much gain in performance will I get if I write my number
- crunching routines in C instead of Visual Basic?
-
- Probably the best solution to the number crunching problem is to
- write the number crunching routines as a custom control or a DLL,
- and plug it into a VB app. VB interface handling is not
- significantly slower than, say C++, and most of the wait is
- associated with Windows.
-
- Some real world experience speaks volumes about this one:
-
- I wrote some time consuming code in VB to solve a combinatorical
- (does this word exist in English?) problem. The code consists of
- one main recursive function, which calls itself very often. It
- took a night to compute a certain problem. I was rather
- disappointed and then decided to write the central routine in C++.
- It was a 1:1 transcription. The routine was compiled with the MS
- C++-Compiler. It took only 22 Minutes for the same problem.
- Amazing, isn't it? The routine doesn't do any floating point
- arithmetic, only integer, and handles some arrays. The PC was a
- 33MHz 486. And the second amazing thing is, that a IBM RS6000
- (560)-Risc-machine needed 17 Min for the same code. I was the only
- one on the machine. I thought it should be much faster. The MS C++
- seems to make very fast, optimized code. The optimization was
- configured to make fast code.
- [Christoph Steinbeck (steinbeck@uni-bonn.de)]
-
- 7. How do you make a TEXTBOX read only? Or, how do I prevent the
- user from changing the text in a TEXTBOX?
-
- There's a lot of ideas on this one. You can grab the _KeyPress and
- _KeyDown events and set them to zero. However, the best idea is to
- use the Windows API SendMessage function to tell the control to
- become read-only:
-
- 'After making the following declarations...
- Global Const WM_USER = &H400
- Global Const EM_SETREADONLY = (WM_USER + 31)
- Declare Function SendMessage Lib "User" (ByVal hWnd As
- |Integer ByVal wMsg As Integer, ByVal wParam As
- |Integer, lParam As Any) As Long
-
- 'Then Try:
- SendMessage(Text1.hWnd, EM_SETREADONLY, 1, 0)
- [Pete Jones (pjones@csi.compuserve.com)]
-
- This will still allow the user to copy *from* the text box. If you
- need to disable this (why?), steal the Ctrl-C in the _KeyPress
- event.
-
- 8. How can I create a VBX?
-
- VBXs (Visual Basic eXtensions) are practically always written is C
- (Borland C++, but mainly MS VC++). You should refer to the
- _Control Development Guide_ (in VB Professional Features Vol. I)
- and any relevant documentation for your compiler. Followup
- questions should normally be directed to comp.os.ms-
- windows.programmer.* or comp.lang.c*.
-
- There are some example VBX's with C code supplied with VB3 Pro.
- You'll find them under the directory [VB]\CDK.
-
- 9. How do you change the system menu (on the Control-Menu Box)?
-
- You can turn off the minimize and maximize menu options by
- changing properties, but what if you need to remove the "close"
- option?
-
- 'Make the following declares.
- Declare Function GetSystemMenu Lib "User" (ByVal hWnd
- |As Integer, ByVal bRevert As Integer) As Integer
- Declare Function RemoveMenu Lib "User" (ByVal hMenu
- |As Integer, ByVal nPosition As Integer, ByVal wFlags As
- |Integer) As Integer
- Global Const MF_BYPOSITION=&H400
-
- 'Use the following code to remove the "close" option.
- SystemMenu% = GetSystemMenu (hWnd, 0)
- Res% = RemoveMenu(SystemMenu%,6, MF_BYPOSITION)
- '(also remove the separator line)
- Res% = RemoveMenu(SystemMenu%,6, MF_BYPOSITION)
-
- Adding menu items to the control menu is more complicated, since
- you need to respond to the events triggered when the user selects
- the new options. The newest Message Blaster (msgblast.vbx, see
- details in beginning of FAQ about how to get files) contains
- example code.
-
- 10. How do I play MID, WAV or other multimedia files?
-
- Use the MSMCI.VBX, provided with VB/Win Pro 3.0. You can also
- declare and call the MM-functions manually:
-
- Declare Function mciExecute Lib "MMSystem"
- |(ByVal FileName as String) As Integer
-
- Sub Form1_Click ()
- iResult = mciExecute("Play c:\windows\mkmyday.wav")
- End Sub
-
- Also:
-
- Playing a WAV file is covered in the VB Tips help file (there is a
- Windows call that is for this specificially; see below). The
- routine won't play MIDI files or other sound formats, however.
-
- Declare Function sndPlaySound Lib "MMSYSTEM.DLL"
- |(ByVal WavFile$, ByVal Flags%) As Integer
- Global Const SND_SYNC = &H0
- Global Const SND_ASYNC = &H1
- Global Const SND_NODEFAULT = &H2
- Global Const SND_LOOP = &H8
- Global Const SND_NOSTOP = &H10
- Global Const SND_USUAL = SND_ASYNC And SND_NODEFAULT
- [John McGuire (jmcguire@jax.jaxnet.com)]
-
- 11. How can I call a 'hidden' DOS program from VB?
-
- If you run a DOS program minimized using the SHELL command, it
- will never complete. This is because DOS tasks by default are NOT
- setup to run in the background. The easiest way to get around this
- is to make a PIF file for the program you need to run with the
- "Background" option checked. Then SHELL to the PIF file to run the
- DOS program and it will return control to your VB application when
- it terminates.
-
- Tip: If you edit or replace the _DEFAULT.PIF file in the Windows
- directory to allow execution in background, this will apply to all
- DOS boxes that is not run with it's own .pif!
-
- 12. How do I do drag & drop between applications?
-
- MSGBLAST.ZIP (the famous Message Blaster by Ed Staffin and Kyle
- Marsh) available on Cica and mirrors tell you *everything* you
- want to know about this and other advanced stuff. This is now
- (inexpensive) shareware, but the older freeware version is still
- supposed to be available. Get the file mentined above for more
- info.
-
- Short glossary for the confused ones :-)
- Drag & Drop Client: the form you drop objects to/on
- Drag & Drop Server: the form you drag object(s) from
-
- 13. How do I use GetPrivateProfileString to read from INI files?
-
- There's a good example of accessing *.INI files in the Knowledge
- Base, but here's the basic idea:
-
- 'You declare these API function as usual:
- Declare Function GetPrivateProfileString Lib "Kernel"
- |(ByVal lpApplicationName As String, ByVal lpKeyName
- |As Any, ByVal lpDefault As String, ByVal
- |lpReturnedString As String, ByVal nSize As Integer,
- |ByVal lpFileName As String) As Integer
-
- 'Then in your code you do like below:
- strIniFile = "WIN.INI"
- strSection = "MyProgram"
- strKey = "Language"
- strDefault = "English"
- iLength = 70
- strReturn = String$(iLength, " ") 'Pad the string first!
- iResult = GetPrivateProfileString(strSection, strKey,
- |strDefault, strReturn, iLength, strIniFile)
-
- WARNING: Be aware that there was an ERROR in the Windows 3.1 API
- documentation that came with VB. Here's the scoop:
-
- Knowledge Base article Q110826 (DOCERR: GetPrivateProfileString
- Declaration Incorrect in API) corrects a documentation error for
- the GetPrivateProfileString function call as described in the
- Windows version 3.1 API Reference help file that shipped with
- Microsoft Visual Basic version 3.0 for Windows. The CORRECT
- declaration is as follows:
-
- Declare Function GetPrivateProfileString Lib "Kernel"
- |(ByVal lpApplicationName As String, ByVal lpKeyName
- |As Any, ByVal lpDefault As String, ByVal
- |lpReturnedString As String, ByVal nSize As Integer,
- |ByVal lpFileName As String) As Integer
-
- Note that the "ByVal" keyword was omitted from the second
- parameter in the online reference. This means that the function is
- passing the second parameter (lpKeyName) by reference. It needs to
- be passed by value.
-
- The most common problem that occurs when using the incorrect
- declaration is that when the function is called, it returns a copy
- of "lpdefault" in the "lpReturnedString" parameter instead of the
- actual value referenced by KeyName.
-
- OOPS: As P. Wierenga (pwiereng@sol.UVic.CA) told me, the same doc
- error applies to Writeblablabla:
-
- DOCERR: WriteProfileString Declaration Incorrect in API Article
- ID: Q115328
-
- The correct declaration is as follows:
-
- Declare Function WritePrivateProfileString Lib "Kernel"
- (ByVal lpApplicationName As
- String,
- ByVal lpKeyName As Any,
- ByVal lpString As Any,
- ByVal lplFileName As String) As
- Integer
-
- (all on one line of course!)
-
-
- 14. How do I implement Undo?
-
- For most controls, you will have to keep track of changes
- yourself. There's no magic involved, just some coding. However, if
- you use the standard Text box or Combo box, Windows provides a
- "free" undo function for you!
-
- 'Do the following declares:
- Declare Function SendMessage Lib "User" (ByVal hWnd As
- |Integer, ByVal wMsg As Integer, ByVal wParam As
- |Integer, lParam As Any) As Long
- Global Const WM_USER = &h400
- Global Const EM_UNDO = WM_USER + 23
-
- 'And in your Undo Sub do the following:
- UndoResult = SendMessage(myControl.hWnd, EM_UNDO, 0, 0)
- 'UndoResult = -1 indicates an error.
-
- 15. How do I create a window with a small title bar as in a floating
- toolbar?
-
- Download the MSGBLAST VBX from ftp.microsoft.com (filename
- msgblast.zip) or (better) from ftp.cica.indiana.edu or mirrors.
- The example files provide an example of a form with a small title.
- When you see it, you'll understand why I haven't include a full
- explanation here!
-
- 16. What is Pseudocode?
-
- VB/Win does not generate machine code like most compilers do.
- Instead it creates what is called pseudocode (a real misnomer,
- IMO). A good explanation is given below:
-
- A bit of history: the original P-code was an instruction set for a
- "virtual Pascal" machine. This came with a portable Pascal
- compiler written at ETH in Zuerich. The portable compiler produced
- instructions for this phony machine which had an instruction set
- ideally suited to the stack and heap management of Pascal. To
- executed portable Pascal programs, you had two choices: either
- write an interpreter for P-code, or translate the small set of P-
- code instructions (there were about 80) into assembler; assemble
- it; and run it at native speed. Thus "P-code" originally stood
- for "Portable" or "Pascal" code. The broader meaning, "pseudo-
- code" came later. P-code was widely popularized by the UCSD Pascal
- system, a small workstation that was implemented entirely in Pcode
- and interpreted. It was sold for some years, and one company even
- re-did the microcode for a PDP-11 microchip to interpret P-code.
- The original Borland Turbo Pascal had obvious similarities to the
- UCSD system although it was not interpreted. The dialect was
- virtually identical. Today P-code is used extensively in
- Microsoft apps, for two reasons. First, it is much more compact
- than native code; so the apps are smaller. Second, having an
- interpreter at the core of an app makes it much easier to
- customize and extend. That is why VB is becoming the heart of the
- MS major apps. It is simply not true that P-code apps run much
- slower than native apps. The slowdown is determined by the
- granularity of the interpreted routines. If every little thing is
- an interpreted op, the slowdown might be as much as 3-to-1 for the
- 80x86 architecture, or about 2-to-1 for the Motorola 68000 family
- (which is better suited to writing interpreters). But in
- practice, modern P-code systems have large-scale instructions,
- each of which is executed by a big compiled subroutine. These subs
- run at native speed, so the overhead of the interpreter is
- occasional at worst.
- [Roger E. Ison (r_ison@csn.org)]
-
- It is also possible that since the code may not need recompilation
- to run on other platforms *if* the run-time interpreter is first
- ported, VB applications can become very portable. This depends on
- Microsoft's long-term plans.
-
- A note on the word "pseudocode": I wrote above that it is a
- misnomer, and I stand on that. Pseudocode is *really* the pascal-
- like (mostly) explanation of an algorithm that is intended for
- human readers, not computers. But since somehow the term
- pseudocode stuck to the psaudo-machine-code created by VB the word
- is used here.
-
- 17. Does VB support pointers to functions?
-
- No, it does not.
- [George Tatge (gat@csn.org)]
-
- 18. How do I program the Novell NetWare API from VB?
-
- Tom Tregilgas (Tom.Tregilgas@InfoB.unisg.ch) had a lot of
- information on this one. Normally I leave it to the other FAQ
- parts to list books & how-to-get-info's, but since this topic is
- very specific and more NetWare than VB I include all the stuff
- here for your convenience:
-
- If you are interested in seeing how Visual Basic can be used for
- NetWare programming, obtain the following files from your friendly
- neighboorhood Novell FTP Mirror site.
-
- Mirror sites are (according to ftp.novell.com):
-
- Novell Germany ftp.novell.de
- Netherlands ftp.rug.nl
- United Kingdom ftp.salford.ac.uk
- Logan, Utah netlab2.usu.edu
- New Zealand tui.lincoln.ac.nz
- Tuscaloosa, Alabama risc.ua.edu
- Ottowa, Ontario, CA novell.nrc.ca
- Boston, Mass bnug.proteon.com
-
- novlib\11\nivb.zip Netware Interface for Visual Basic
- novlib\11\nwtest.zip NetWare Test for Visual Basic
-
- There are also two Novell App Notes on the subject of using
- NetWare with Visual Basic (although this is _NOT_ supported by
- Novell...) which are:
-
- October 92 Interfacing Visual Basic for Windows and NetWare
- July 93 A NetWare Interface for Visual Basic
-
- The AppNotes can be obtained by contacting the Novell Research
- Order Desk, FAX: +1 303 294-0903, Voice 800 377-4136, +1 303 297-
- 2725. Address as follows:
-
- Novell Research Order Desk
- 1601 Park Avenue West
- Denver, CO 80216-5199
-
- AppNotes are $95/year ($135 outside US)
-
- Here are a few books which might help you out to figure the calls
- out:
-
- Windows Development on NetWare Systems, Lori Gauthier and Sue
- Whitehead (c) 1994, Windcrest, Blue Ridge Summit, PA 17294-0850
- (McGraw-Hill) $34.95 Comes with disk This book also tells you how
- to "upgrade" to the currently supported SDK calls
-
- NetWare System Interface Technical Overview, Novell (c) 1990,1989
- (Addison-Wesley), $32.95 (describes Novell's C Network Compiler
- API's)
-
- Visual Basic Programmer's Guide to the Windows API, Daniel
- Appleman Ziff-Davis Press, 5903 Christie Ave, Emeryville, CA
- 94608, $34.95 Comes with disk
-
- It should be mentioned that the APIs included with the NIVB are
- _not_ current, and for this purpose, you should get the Novell SDK
- kit. Also, Novell will not support NIVB, but you can sometimes get
- some helpfrom Compu$erve, or from others on the Infobahn <g>
-
- Good luck!
-
- p.s. It behooves you to become a member in the PDP (Professional
- Developer's Program) since you get the AppNotes (& Bullets!)
- for...free.
-
- p.p.s. Novell does NOT support the NIVB...
-
- p.p.p.s. Also, no docs come with it. You'll probably need the
- Client C SDK kit to be able to really _use_ the code.
-
- p.p.p.p.s. To make things even better, the calls in NIVB are
- fairly old, and not of the Client C SDK kit variety. However,
- there _are_ books which could help you out, e.g. "NetWare System
- Interface Technical Overview", by Novell. ISBN:0-201-57027-0,
- published by Addison-Wesley Publishing co, $32.95 US, $42.95 in
- Canada.
-
- Update:
-
- AppNotes are dead, however, Develper Notes live on. There is one
- article about NetWare programming with Visual Basic here:
-
- July/Aug 94 NetWare Programming in Visual Basic:
- Using Apiary's NetWare Client SDK for Visual Basic
-
- 19. Visual Basic 4 news [**]
-
- Here is the news we have observed (and which was a guess in
- previous versions of this FAQ)
-
- a. Two versions: 32-bit and 16-bit
- Like Visual C++ 1.5, VB 4 comes with compilers for the 16-bit API from
- Windows 3.1 as well as a real 32-bit compiler (or pseudocompiler) for
- Windows 95 (and NT) bundled together.
-
- b. New features inherited from VBA
-
- 1) VB 4.0 is really VB Applications Edition 2.0
- 2) Line continuation character " _" (space+underscore)
-
- 3) WITH statement, known from Pascal, to save typing and make code
- cleaner. An example:
-
- With Form1
- With Text1
- Bold = true
- FontName = "New Times Roman"
- End With
- End With
-
- 4) FOR EACH .. NEXT statement allows you to make changes to a group
- of objects at once better than FOR..NEXT. Syntax:
-
- For Each element In group
- [statements]
- [Exit For]
- [statements]
- Next [element]
-
- 5) OPTIONAL statement allows you to leave some Variant parameteres
- undefined when calling a user-defined sub or function. Also an ARRAY
- function that returns an array form a list supplied as parametres, and
- a special optional ParamArray optional parameter of Variants.
-
- 6) Boolean data type. Coded as 16-bit (2-byte), but can only have
- TRUE or FALSE value.
-
- 7) Byte data type (8-bit). Can have values from 0 to 255.
- 8) FUNCTION can be of user-defined type.
-
- 9) OLE Automation allows detailed control over objects taken from
- ie. Excel or Word.
-
- 10) Reusable Objects and Collections, called Classes
-
- 11) Property Procedures allows you to add custom properties to form
- and some other modules.
-
- 12) New enhanced development environment, which includes an object
- browser and allows add-ins. Pro edition also allows creation of your
- own add-ins. (For some strange reason, the 32-bit version of this does
- not use Win95 file dialog boxes!)
-
- 13) Conditional compilation: allows one source for 32- and 16-bit
- versions.
- 14) Data bound DBList, DBCombo, and DBGrid controls! VB 4 uses Jet
- 2.5 engine.
-
- c. VBX is dead. Long live OCX!
-
- You may not feel for celebrating this either, but the 32 bit VB 4 will
- not support the old 16-bit VBX'es. The 16-bit version of VB 4 will
- support them for backwards compatibility, but be aware that OLE 2 and
- OCX is the way of the future, at least if Microsoft gets it as they
- want.
-
- 20. How do you change the icon and otherwise manipulate the DOS box?
-
- Enclosed is the results of my digging around to enable me to
- change the icon
- of a DOS box launched with the SHELL function. It illustrates most
- aspects
- of dealing with DOS boxes.
-
- Example of launching PIF file minimized and running it in the
- background (Needs Execute Background box checked in PIF file), and
- assigning the PIF file a new Icon rather than the default DOS Box
- Icon.
-
- (Note: it seems this method changes the icon of ALL the active DOS
- boxes)
-
- Code follows:
- x-----------------------------------------------------------------
- ----x
- Option Explicit
-
- Global Const SWP_NOSIZE = 1
- Global Const SWP_NOMOVE = 2
- Global Const SWP_NOACTIVATE = &H10
- Global Const SWP_SHOWWINDOW = &H40
- Global Const SWP_HIDEWINDOW = &H80
- Global Const SWP_FLAGS = SWP_NOMOVE Or SWP_NOSIZE Or
- SWP_NOACTIVATE
- Global Const SWP_SHOW = SWP_SHOWWINDOW Or SWP_FLAGS
- Global Const SWP_HIDE = SWP_HIDEWINDOW Or SWP_FLAGS
- Global Const HWND_BOTTOM = 1
- Global Const GCW_HICON = (-14)
- Global Const GCW_HMODULE = (-16)
-
- Declare Function GetModuleUsage Lib "Kernel" (ByVal hWnd%) As
- Integer
- Declare Function ExtractIcon Lib "Shell" (ByVal hInst%, ByVal
- lpExeName$,
- |ByVal hIcon%) As Integer
- Declare Function DestroyIcon Lib "User" (ByVal hIcon%) As Integer
- Declare Function FindWindow Lib "User" (ByVal lpClassName As Any,
- ByVal
- |lpCaption As Any) as Integer
- Declare Function SetWindowPos Lib "User" (ByVal h%, ByVal hb%,
- ByVal X%,
- |ByVal y%, ByVal cx%, ByVal cy%, ByVal F%) as Integer
- Declare Function GetClassWord Lib "User" (ByVal hWnd%, ByVal
- nIndex%)
- |As Integer
- Declare Function SetClassWord Lib "User" (ByVal hWnd%, ByVal
- nIndex%,
- |ByVal wNewWord%) As Integer
-
- Sub LaunchPif(PifFile as String, IconName as String)
- Dim Res As Integer 'Return value from API call
- Dim MyInst As Integer 'Instance handle for this app
- Dim PifIcon As Integer 'Pif Icon Resource name
- Dim OldIcon as Integer 'Original Pif Icon resource (default =
- 0)
- Dim PifhWnd As Integer 'Dos Box Window handle
- 'Launch PIF file
- PifInst = Shell(PifFile, 6)
- 'Get Instance handle for main MDI Window (assumed to be
- frmMDI)
- MyInst = GetClassWord((frmMDI.hWnd), GCW_HMODULE)
- 'Create new Icon resouce by loading Icon from disk file
- 'Check Icon file exists
- If Dir$(IconName) <> "" Then
- 'Make sure string is null terminated
- IconName = IconName & Chr$(0)
- 'Create Icon resource in this window
- PifIcon = ExtractIcon(MyInst, IconName, 0)
- Else
- PifIcon = 0
- End If
- 'Reset Default Icon on DOS Box to PifIcon
- 'Check PIF file still running and Icon resource created
- If GetModuleUsage(PifInst) <> 0 and PifIcon > 0 Then
- 'Get Pif Window handle
- PifhWnd = FindWindow(0&, "Window name in PIF file")
- 'Set Icon handle to PifIcon resource
- OldIcon = SetClassWord(PifhWnd, GCW_HICON, PifIcon)
- 'Hide and show window to get a redraw of the Icon
- Res = SetWindowPos(PifhWnd, HWND_BOTTOM, 0, 0, 0, 0,
- SWP_HIDE)
- Res = SetWindowPos(PifhWnd, HWND_BOTTOM, 0, 0, 0, 0,
- SWP_SHOW)
- End If
-
- 'Wait for PIF file to complete
- Do While GetModuleUsage(PifInst) <> 0
- DoEvents
- Loop
-
- If PifIcon > 0 then
- 'Reset Icon to original
- Res = SetClassWord(PifhWnd, GCW_HICON, OldIcon)
- 'Tidy up by removing PIF Icon resource
- Res = DestroyIcon(PifIcon)
- Endif
- End Sub
- x-----------------------------------------------------------------
- ----x
- [Dr David Baird (BairdD@AgResearch.CRI.NZ)]
-
- 21. How do I make the mouse cursor invisible/visible?
-
- Use the API call ShowCursor(False) or ShowCursor(True). Just be
- aware that the Windows cursor is a shared object, so if your
- process hides it then it must also redisplay it as well. Also the
- function is not truly "True" or "False" in nature - it is LIFO, so
- that if your process has for some reason set it "False" multiple
- times then you must set it "True" the same number of times in
- order to re-display the cursor. Hard to explain but play with it -
- you'll see what I mean...
- [Galen Raben (galenr@hpgrla.gr.hp.com)]
-
- 22. How do I create controls dynamically (at run-time)?
-
- Search of VBKB_FT on "control* near array*" finds a number of
- articles, including Article ID: Q79029 "Creating Nested Control
- Arrays in Visual Basic" This is THE article to read to understand
- control arrays (plus a number of other neat concepts). In
- particular, look at the procedure "loadall_click".
-
- The key is that you need to create the first instance of
- your_control (ie. your_control(0)) at design time.
- [Ayn Shipley (ashipley@hookup.net)]
-
- 23. How do I set the Windows wallpaper at runtime?
-
- I'm surprised this isn't in the FAQ yet. [ED: now it is!] You need
- the SystemParametersInfo API function and the SPI_SETDESKWALLPAPER
- constant.
-
- For this you will need the following constants and function
- declaration...
-
- Const SPI_SETDESKWALLPAPER = 20
- Const SPIF_SENDWININICHANGE = &H2
- Const SPIF_UPDATEINIFILE = &H1
- Declare Function SystemParametersInfo Lib "User" (ByVal uAction As
- |Integer, ByVal uParam As Integer, lpvParam As Any, ByVal
- fuWinIni As
- |Integer) As Integer
-
- 'You then call the function as follows...
-
- Result% = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, ByVal
- BMPFile$,
- |SPIFlags%)
-
- '... where SPIFlags% is 0 if the change is not to be made
- permanent, or
- '(SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE) if it is to be
- carried across
- 'into future Windows sessions.
-
- NOTE: Please be certain to include the ByVal keyword before the
- bitmap
- filename, as this argument is declared as Any, NOT as ByVal
- String.
- [Luke Webber(webber@werple.apana.org.au)]
-
- 24. How do I call help files from a VB program? [**]
-
- There are 2 ways you can display help files:
- 1) In code
- a) Using the common dialog control
- b) Making a winhelp api call
- (see below for examples)
- 2) Pressing F1 when App.HelpFile is set to your
- help file.
- Note - if a control's HelpContextID property is
- set to the context id of a help topic, that topic
- will be displayed if the control has focus and the
- user presses F1, otherwise the contents is displayed.
-
- (see Mapping Context-Sensitive Topics, Chapter 6 pg. 117
- of the Professional Features Book 1 for information on
- setting the context ids for your help file. Many help
- authoring tools will generate the context ids for you.)
-
- - Include constant.txt in your project
- - Set App.HelpFile = "c:\yourfile.hlp"
- - Declare the following function in a .bas module
- (make sure it is all on one line):
-
- 'Function for display windows help files
- Declare Function WinHelp Lib "User" (ByVal hWnd As Integer,
- ByVal lpHelpFile As String, ByVal wCommand As Integer,
- dwData As Any) As Integer
-
- COMMON DIALOG:
- ---------------
- Note - The HelpContext property can only be assigned
- an integer. The equivalent WinHelp Api call can use a long.
- In this example the context id is 1000
-
- jump to a context id within help file.
- CMDialog1.HelpFile = "c:\yourfile.hlp"
- CMDialog1.HelpCommand = HELP_CONTEXT
- CMDialog1.HelpContext = 1000
- CMDialog1.Action = 6
-
- bring up contents
- CMDialog1.HelpFile = "c:\yourfile.hlp"
- CMDialog1.HelpCommand = HELP_CONTENTS
- CMDialog1.Action = 6
-
- bring up search window
- CMDialog1.HelpFile = "c:\yourfile.hlp"
- CMDialog1.HelpCommand = HELP_PARTIALKEY
- CMDialog1.HelpKey = ""
- CMDialog1.Action = 6
-
- quit help
- CMDialog1.HelpFile = "c:\yourfile.hlp"
- CMDialog1.HelpCommand = HELP_QUIT
- CMDialog1.HelpContext = 0
- CMDialog1.Action = 6
-
-
- WINHELP API:
- -----------------
- In the following examples iRetCde is declared as an integer.
-
- Jump to context id (e.x., context id is 1000)
- iRetCde = WinHelp(Me.hWnd, "c:\yourfile.hlp", HELP_CONTEXT,
- ByVal CLng(1000))
-
- bring up contents
- iRetCde = WinHelp(Me.hWnd, "c:\yourfile.hlp", HELP_CONTENTS,
- CLng(0))
-
- bring up search window
- iRetCde = WinHelp(Me.hWnd, "c:\yourfile.hlp", HELP_PARTIALKEY,
- ByVal "")
-
- quit help
- iRetCde = WinHelp(Me.hWnd, "c:\yourfile.hlp", HELP_QUIT,
- CLng(0))
-
- [Blake Miller (bemiller@amoco.com)]
-
-
- E. CALLING THE WINDOWS API AND DLLs IN GENERAL
-
-
- 1. What is the Windows API?
-
- The Windows API (Application Program Interface) is a collection of
- Dynamic-Link Libraries (DLLs) that do most of the common things in
- Windows. Calls to the Windows API gives you access to routines
- that do things like drawing menu bars, manipulating bitmaps,
- playing sound files, and pretty much every other function of
- Windows.
-
- 2. How do I call a DLL?
-
- Basically, you declare a DLL procedure which you can call in your
- VB program which in turn passes data to and/or retrieves data from
- the DLL. You should read the section of the VB manual that talks
- about calling DLLs ("Chapter 24 Calling Procedures in DLLs" in
- the VB 3.0 Programmer's Guide). This chapter covers the basics of
- using the Windows API DLLs and calling DLLs in general. Beyond
- that you may want to find a good book on this subject since it is
- too large to cover here (see the Book Listing in the Appendix of
- the General FAQ - Part 1). Don't be too intimidated! Using DLLs
- (especially many of the Windows API functions) is quite easy, once
- you learn how to call them. In fact, many of the newer DLLs
- include VB-compatible modules!
-
- 3. What about DLL calls that require callbacks?
-
- VB does not support callbacks, but various extensions can help.
-
- Dan Appleman's "Visual Basic Programmer's Guide to the Windows
- API" comes with a floppy disk which code samples and tools. It
- also includes a VBX which supports the callbacks which many API
- calls require. Dan is also founder and president of Desaware which
- sells more extensive tools, including SpyWorks, for VB developers.
- [Walter Hill (whill@netcom.com)]
-
- 4. Tips for calling DLLs (such as the Windows API)
-
-
- a. Using the BYVAL keyword is critical. Using it when you're
- supposed to call by reference and (more common) not using it when you
- are to give a value to the external function are the single most
- common mistakes. Wrong calling convention can often result in a
- General Protection Fault (GPF) or, even worse, corruption of another
- applications' data.
-
- b. Check return and parameter types. For return types, a C function
- declared as "void" means you use a Sub not a Function.
-
- c. Initialize strings by padding it to the necessary length! If you
- pass a string that is too short to the API it will happily write past
- the end of the string and possibly corrupt data.
-
- d. Use Option Explicit. A typing error that results in a bug in the
- VB source will occasionally cause a GPF when you call external code.
- e. It's a jungle out there! Check parameter values as there is no
- type checking outside VB. If you make a mistake, you'll often get a
- GPF.
-
- f. Save before you run! You may even need to restart Windows after a
- GPF, since DLL's often aren't unloaded properly. As a second option
- you can check out WPS (Windows Process Status) which is distributed
- with VB/Pro and placed in the CDK directory. This utility allows you
- to kick out any module (EXE, DLL) from memory (shooting yourself in
- the foot if you want to. WPS is a nice way to find out what DLLs are
- actually used, but save your work first!).
-
-
- F. VISUAL BASIC AND DATABASES
-
-
- 1. Why can't I use an index with my VB accessed database?
-
- There is a mistake in the docs which says you can set the active
- index for a recordset. You can't. The data control uses the
- primary key for tables and physical order (I think) for dynasets.
- [Nic Gibson (nic@skin.demon.co.uk)]
-
- NOTE: You can of course set the indexes yourself using code in
- VB/Pro (Table objects), but Data Control's can't. Sorry for the
- problems this possible misunderstanding caused!
-
- Thanks to John McGuire (jmcguire@jax.jaxnet.com) for clarifying
- this.
-
-
- 2. "Can't find installable ISAM" or Why does my compiled VB database
- app generate an error when it ran just fine in the design environment?
-
- You can thank Microsoft for documenting this topic so poorly. When
- you compile your VB database application, you must also have an
- INI file for it which provides the correct pointers to the
- appropriate database drivers. Therefore, if your application is
- named "INVOICE.EXE", you will need to have a properly configured
- "INVOICE.INI" file in your Windows directory. The file,
- EXTERNAL.TXT, that came with VB should explain all about it.
-
- 3. Is the Access Engine and Visual Basic Pro good enough for
- database work?
-
- That, of course, depends. Generally the answer is "yes", but you
- may need some third-party add-on products.
-
- These are the major weaknesses of VBPro's database functions:
-
- a. Limited data controls: No add, delete or search button; no bound
- list box or masked edit control and - the worst - no bound grid!
- b. No run-time query builder ("how good is your user in SQL?") or
- report builder.
- c. No direct advanced control of the Access 1.1 (or 2) Database
- Engine (ie. security, optimization, etc).
-
- d. SQL us SLOW. Handcoding is much faster (but harder to code)
-
- The good news is that lots of companies are willing to sell you
- products which address one or more of the above weaknesses.
-
- Also, if you build a database application with advanced database
- relations, it can be a good idea to build the database itself with
- Access and the front-end with VB.
-
- 4. How do you avoid the "Invalid use of null" error when reading
- null values from a database?
-
- If you try to retrieve a null value (empty field) from a database,
- you will get the error: "Invalid use of Null". Here is one way to
- get around this problem:
-
- I've worked around this problem with the following code:
-
- TextBox.Text = MyTest.Fields("TestFld") & ""
-
- This code converts the Null-Value into an empty string.
- [Ralf Metzing (rmm@dragon.stgt.sub.org)]
-
- 5. What is "NULL"?
-
- Contrary to popular belief, Null is not nothing. It's even less
- than nothing. 8^)
-
- The VB documentation describes all the horrors of misunderstanding
- the infamous NULL. Since people don't read the documentation, we
- feel like informing that
-
- If ThisVarIsNull = NULL then DoSomething
-
- will *always* fail, and the DoSomething can't possibly be
- executed. You *must* use IsNull(ThisVarIsNull) which will return
- True if the var is Null (phew!).
-
- If you want to find out why someone came to think of this strange
- value, read some relational database theory.
-
- 6. How can I access a record by record number?
-
- Use a counter or index field - or even better, a Bookmark property
- - for this.
-
- It is *impossible* to ask a relational database system to give you
- ie. "field number 3 in record number 10" since by definition a
- relational database does not have row or column numbers. Databases
- allowing direct access like that is not even remotely relational.
-
- Access (and therefore, VB) is about as close to a real relational
- database system as you can get.
-
- 7. How about Access 2.0 compatibility?
-
- You need the compatibility layer availability. The file COMLYR.EXE
- is in the MSBASIC library on Compuserve. This file provides all
- the items necessary for compatibility between VB 3.0 and Access
- 2.0.
- [Fred Griffin (72321.3230@compuserve.com)]
-
- For unknown reasons you can't install the compatibility layer
- without Acess 2.0 being installed, even if you just want to open a
- database from VB that was created by someone else.
- [Kent Boortz <boortz@sics.se>]
-
- The file COMLYR.EXE can be downloaded from ftp.microsoft.com. It
- is located in the directory /softlib/mslfiles. (NOTE: A "DIR" in
- this directory is rarely a wise course of action. There is an
- enormous amount of files im /mslfiles.)
-
- 8. Tips for VB database programming:
-
-
- a. Use Access and QBE. Once it's "working" (even if the parameters
- are hardcoded), then open up View.SQL and copy the stuff from the SQL
- window into your VB code. If you need to insert VB variables, try
- testing this under Access by using parameters instead. They're then
- nice & easy to spot when it comes to converting into VB - I always
- call my parameters "PR_xxxx", so I can just search my VB code for this
- to find any instances that I've missed.
-
- b. It never works first time. So put an error handler into your VB
- code that copies the contents of SQLStr onto the clipboard, should the
- query fail. Now it's quick & easy to switch back to Access, find a
- scratch query and paste the erroneous SQL into that. It's *much*
- easier to debug a SQL query in Access, after the variables have been
- merged in, than it is to do it blind from VB.
-
- c. Use carriage returns to break up your SQL. One before each
- reserved word is sensible. They're not significant in SQL. I assume
- you're not stupid enough to put them in the middle of field names -
- unfortunately Debug.Print is!
-
- d. When merging in the contents of a variable (building a SQL query
- in a VB string), it should *always* be surrounded by an ampersand and
- 3 double quotes, or an ampersand and 2 mixed quotes, depending on your
- local conventions:
-
- SQLStr = SQLStr & "WHERE Username <= """ & Username$ """ "
-
- or
-
- SQLStr = SQLStr & "WHERE Username <= '" & Username$ "' "
-
- e. If you're using dates, then it will *always* be one quote, a hash
- and an ampersand:
-
- SQLStr = SQLStr & "WHERE Start_Date <= #" &
- |Format$(CutOffDate,"Long Date") & "# "
-
- f. Another tip with dates is to format them with the long date
- format, not the short date. This is then safe against the
- transatlantic reversal of month & day position.
-
- g. If you're merging in a field/table name, enclose it in square
- brackets. That way the SQL will still be valid if the variable
- contains spaces:
-
- SQLStr = "SELECT * FROM [" & TableName$ "] ;"
-
- When building SQL strings in VB, then you'll often do this on several
- lines, concatenating SQLStr with the new string. If you leave a space
- at the end of every string, then you can guarantee you won't have
- problems with the text from successive lines running into each other.
-
- h. If you're using Access 1, you'll keep running into the 1024
- character limit on the length of a SQL string. Keep the table & field
- names short, especially if many JOINs are concerned. Using underscores
- in names is shorter than spaces, as you don't need the extra 2
- characters for the square brackets around them. If your SQL is
- slightly too long, then you'll probably see a "Missing semicolon"
- error, even though the semicolon is obviously there (To you, anyway!).
-
- i. Making a QueryDef is a complicated process that is often slower
- than executing the query ! Don't mess with the .SQL property, as that
- is equally slow (Access needs to do a lot of work to turn SQL into its
- internal query format). Two ways around this: Use ready-built queries,
- written with Access. If you need to merge in values from variables,
- then use a query with parameters. Setting parameter values is quick to
- execute.
-
- j. If you really need to build SQL on the fly -- you need to build
- an ad hoc query, or to supply table or field names (which can't be
- done with query parameters), then try using:
-
- database.Execute SQLStr
-
- As this doesn't build a QueryDef, then it's quick.
- [Tips a to j by Andy Dingley(dingbat@codesmth.demon.co.uk)]
-
- k. Make sure all Tables, Dynasets, Snapshots, Databases, and other
- data access objects are properly closed before ending the program. As
- near as I can tell, the pointers to these objects are not destroyed if
- your VB program doesn't Close them (including when a program crashes).
- A Microsoft guy did say he can't find anything that confirms that they
- close, but (of course) he wouldn't say for certain that they aren't
- closed. Based on resources after serious crashes (that I couldn't walk
- the program out of by hand), I don't think they're automatically
- closed.
- [John McGuire (jmcguire@jax.jaxnet.com)]
-
- 9. How come I get a "No Current Record" error when I use a a Data
- Control on an empty table?
-
- Well, this is a "feature" courtesy of Microsoft. KB article
- Q106494 explains this in detail. Basically, the workaround is to
- add an empty record to the table before the user can do anything
- (or before you try to do any Moves on the Table).
- [George Tatge (gat@csn.org)]
-
- 10. How can I speed up my VB database application?
-
- KB article Q109830 gives some hints. Things you should do
- include:
-
- - Use Snapshots when possible.
- - Use transactions whenever possible.
- - Use Dynasets when possible.
- - Use SQL action queries when possible.
- [George Tatge (gat@csn.org)]
-
- Major Weakness: SQL is SLOW! A hand-coded search (with indices) is
- MUCH faster than an equivalent SQL call, especially with complex
- search criteria. For example:
-
- SELECT * FROM Table WHERE SSN = '555-33-1234' AND Posted #01-31-
- 95#
-
- is a lot slower than:
-
- Table.Index = "SSN"
- Table.Seek "=", "555-33-1234"
- If Not Table.NoMatch Then
- While Not Table.EOF
- If Table("SSN") "555-33-1234" Then
- Table.MoveLast 'Forces an EOF
- ElseIf Table("Posted") #01-31-95# Then
- 'Do something
- End If
- Table.MoveNext
- Wend
- End If
-
- Granted, it is a LOT more code, but I ran a VERY similar query
- that took THIRTY HOURS! The equivalent hand-written code took
- ELEVEN MINUTES! That's 163 times faster! I think basically SQL
- isn't very good at figuring out which indexes to use (I also think
- I've read something to the effect that the newer version, 2.0 or
- 2.5, IS better at this).
- [John McGuire (jmcguire@jax.jaxnet.com)]
-
- 11. How do I get a bitmap picture in a field in an Access database?
-
- See p.466 of the Visual Basic (3.0) Programmer's Guide. It
- contains a section called "Using Bound Picture Box and Image
- Controls". Basically you have to bind the VB PictureBox to a field
- in the Access DB, set the .Picture property in the PictureBox, and
- then move to the next record or something. VB will then store your
- picture in Access in a form in which it can be retrieved by VB in
- the future.
-
- If you store the pictures in Access directly (using Access), VB
- won't be able to read them (using VB 3.0 and Access 1.1).
-
- You can also store the picture's filename as a text field in the
- database and use LoadPicture() to load that file into the VB
- PictureBox.
- [Tim Shea (shea@marcam.com)]
-
- 12. What is "Reserved Error -1209"?
-
- You will get a Reserved Error [-1209] ("There is no message for
- this error")
- when your database is corrupted. Try opening the database using MS
- Access;
- if it's corrupted you should get the option to repair it.
- [Joe Abley (joe_abley@originuk.demon.co.uk)]
-
- You should also compact it, after repair. I recommend you add the
- following to your File menu on your main form:
-
- Case ...
-
- RepairDatabase Curentdatabasename
-
- Case ....
-
- On Error resume next
- Kill "temp.MDB"
- Name curentdatabasename as "temp.mdb"
- on error goto errcompact
- compactdatabase "temp.mdb", Currentdatabasename
- kill "temp.mbd"
- exit sub
-
- errcompact:
- msgbox "compaction failed"
- name "temp.mdb" as Currentdatabasename
-
- Case ...
-
- [Ayn Shipley (ashipley@hookup.net) , Kym Wilson]
-
- 13. "Cannot perform operation. illegal.." with Paradox 3.5 table(s)
-
- Your Paradox table must have a primary key, or it will be read-
- only no matter what you set its properties to.
- [Ayn Shipley (ashipley@hookup.net)]
-
- 14. I'm getting error message "Reserved Error [-nnnn] ("There is no
- message for this error")" from Jet Engine 2.0. Huh?
-
- See the Knowledge Base article Q117900 "Reserved Error Numbers
- Returned by
- the Jet 2.0 Engine" for a complete list of the new error messages.
-
- Extract:
- "Jet_Error/Message_String
- -1010 Invalid database ID.
- -1016 Can't have more than 10 fields in an index.
- -1029 Database engine hasn't been initialized.
- -1030 Database engine has already been initialized.
- -1034 Query support unavailable."
- [Ayn Shipley (ashipley@hookup.net)]
-
- 15. Why do I get "object not an array" when I try reference the
- fields of a global object variable which I have set to a table?
-
- VB has a parser bug which makes it difficult to use database
- objects declared in a module from within a form.
-
- WORKAROUND: Just perform some _method_ on the table object
- somewhere _before_ you try to reference fields. Say in a form-
- based subroutine AAAA_IllBeFirst you have a Tbl.MoveFirst, which
- is never even executed. Then VB suddenly realises what the object
- is and all is forgiven.
-
- Credit to Luke Webber and "Joe Foster of Borg".
- [Ayn Shipley (ashipley@hookup.net)]
-
- 16. Steps for securing an Access 2.0 database [**]
-
- What I started with:
- A database that I wanted to make secure.
- Access 2.0 installed on my hard drive.
- No Access permissions or accounts ever played with under Access.
-
- 1) I ran MS Access Workgroup Administrator and created a new
- SYSTEM.MDA and assigned a unique workgroup id.
-
- 2) Ran Access and created a new database, DB1.MDB.
-
- 3) Changed the password for the Admin user using Change Password
- under
- the Security menu. Changed the password from nothing to
- "PASSWORD".
-
- 4) Clicked on Users under Security. Added a new user, "JOEUSER"
- and made
- it a member of the Admins and Users groups.
-
- 5) Closed Access, deleted the new database I had just created,
- DB1.MDB,
- and restarted Access. Logged in as the new user, "JOEUSER".
- Created
- a new database named DB1.MDB. Changed the password from
- nothing to=7F
- "PASSWORD".
-
- 6) From the File menu, clicked Add-ins and then Import Database.
- Imported
- my database, REAL.MDB, that I wanted to make secure.
-
- 7) Went to Permissions under the Security menu and turned off all
- permissions for all Groups and all Users for the database, all
- tables,
- forms, macros, etc. The only permissions I left on was full
- permissions
- for all objects for the new user, "JOEUSER". After changing
- the
- permissions, I closed Access (note that the database I just
- used was
- DB1.MDB).
-
- 8) I made a backup of my database REAL.MDB and renamed DB1.MDB to
- REAL.MDB.
-
- 9) Opened my VB code and added the line:
-
- SetDefaultWorkspace "JOEUSER", "PASSWORD"
-
- right before the line where I open the database.
-
- 10) Copied the SYSTEM.MDA from my C:\ACCESS directory to the
- directory
- where my VB code is. (Note, I do not have an INI file for my
- program).
-
- 11) Ran my VB program and my database can be opened by my program
- and nobody
- else. The SYSTEM.MDA has to be delivered with my program
- however.
-
- See SetDefaultWorkspace and SetDataAccessOption in VB help for
- more information on how to set up the data access paramaters in an
- INI file. Make sure you add error handling for a missing or
- messed up SYSTEM.MDA file.
-
- I think this is a good basic way to prevent people from
- looking/changing your database. Possible flaws are looking at a
- dump of the .EXE file and finding the name and password used to
- open the database (there are various workarounds for this) and
- also running a program to look at parameters passed when opening
- the database (don't know if this is possible and can't think of a
- workaround if it is).
- [Justin F. Smith (jsw117@psu.edu)]
-
-
- G. DISTRIBUTING VISUAL BASIC APPLICATIONS
-
-
- 1. What are some tips for using Setup Wizard?
-
- There were loads of bugs in the setup utilities supplied with VB3.
- Be sure to get the newest version of SETUPKIT (usually called
- SETUPK.EXE or -.ZIP). It is available from the sources listed in
- the beginning of this document, and in the General FAQ.
-
- Alternatively, if you have the older versions, you may have to
- manually remove the line referring to OLE2UI.DLL in the file
- SETUPWIZ.INI. See later in this document for dates of newest files
- on ftp.microsoft.com.
-
- Follow the instructions in SETUPK.TXT exactly. The files actually
- belong in two separate directories. Not placing them correctly can
- create strange and unusual side effects -- none of them good(!)
-
- Set all involved EXE, DLL and VBX files to Read-Only so that the
- setup program doesn't modify them.
- [Charles F. Mulks (21667cfm@msu.edu)]
-
- A *very* good tip. Actually, make all executables on your system
- read-only. If not, you can get a sharing violation if you try to
- run the same DOS executable twice at the same time.
-
- Also, the source code for a SETUP program is *included* with VB3
- Pro. It is quite trivial to tailor it to your specific needs.
-
- The question remains: Is SetupWiz good? No! Good enough? Perhaps.
-
- 2. Are there restrictions on what I can distribute with my VB
- program?
-
- The documentation tells what parts of the Visual Basic kit you can
- freely distribute: the VBX files, some DLL's and what the SetupKit
- includes on your distribution diskettes. Reading software license
- agreements may be more boring than asking the newsgroup, but is
- nevertheless a good idea. 8^)
-
- There have been some rumours on the newsgroup that you can't
- redistribute programs written with VB freely. This is nonsense.
- All applications created with VB can be redistributed freely
- without royalties (as long as you don't distribute proprietary
- external files).
-
- The rumours probably originated when Microsoft announced that they
- will not sell kits allowing third-party software to include the
- Visual Basic for Applications (VBA) system.
-
- 3. What alternatives to setup wizard do I have?
-
- Perhaps the best one is to simply modify the setup app which is
- supplied with VB. Look in your VB directory for the setupkit\
- setup1 directory. There you will find everything you need to do a
- complete setup program. This sample setup is coded to install a
- few sample app files and create a program group. You can comment
- out those lines and change to your files and program mgr. group.
- There are also a few global variables you will want to change.
- All of this is contained in the comments in the code.
-
- Using this, and the distribution information in the manual telling
- you about which files to distribute with your app will make things
- much easier than using the setup wizard (IMNSHO).
-
- There are also several third party setup products available.
- [George Tatge (gat@csn.org)]
-
- 4. Do I need to worry about users who have Progman replacements such
- as Norton Desktop and PC Tools?
-
- Earlier versions of those products and some others do not respond
- properly to the DLL commands to create groups and items. More
- recent versions do. All you can do in this case is to include
- some information in your readme.txt file that instructs users of
- those products to shut them down and start up program manager
- before installing.
- [George Tatge (gat@csn.org)]
-
- 5. Can I distribute my app without vbrunXXX.dll?
-
- If you are sure that your users have it or can get it, you can
- easily distribute your app without vbrunXXX.dll. Simply remove
- the file from your distribution disk or zip file and and ALSO
- remove it from the setup.lst file.
- [George Tatge (gat@csn.org)]
-
- 6. Why won't my setup program install commdlg.dll et. al.?
-
- There are a couple of DLLs that are almost always in use by
- windows. Commdlg.dll is the most common example. When faced with
- this problem, there is no easy way out. The full explanation is
- several pages long and beyond the scope of this FAQ. The general
- idea is as follows:
-
- Your setup program will need to create a .BAT file to expand and
- then copy these files. Then, it will need to shutdown Windows
- (see ExitWindowsExec API call) and run the .BAT file. Then it
- will need to restart windows and continue your setup program.
- Your setup program should delete the temporary .BAT file that is
- no longer needed.
- [George Tatge (gat@csn.org)]
-
- 7. Where do I install VBXs and DLLs?
-
- PLEASE- this is one place where everybody's life is much easier if
- you will follow Microsoft's recommendations. All PUBLIC VBXs and
- DLLs should be installed in the windows/system directory! A
- "PUBLIC" DLL or VBX is any which can be purchased on the open
- market. In other words, if another VB programmer might possibly
- use the same VBX or DLL, install it in the
- system directory.
-
- If you have written private VBXs or DLLs that will never be used
- by any program but yours, you can install them in the same
- directory where you install your application files.
-
- There are lots of good reasons for doing this, but it makes a
- short novel to rehearse them all.
- [George Tatge (gat@csn.org)]
-
-
- H. MISCELLANEOUS TIPS AND INFORMATION
-
-
- 1. Multiple identifiers after the DIM statement can be confusing
-
- Some programmers with background from Pascal can try the following
-
- Dim iA, iB, iC as Integer
-
- and think that all these 3 variables end up as Integer. In fact,
- the first two end up as default data type, normally Variant.
-
- Instead you should do
-
- Dim iA as Integer
- Dim iB as Integer
- Dim iC as Integer
-
- which takes up more space, but gives you room to comment your
- variables (hint, hint); *or*
-
- Dim iA%, iB%, iC%
-
- which does the whole job.
-
- 2. "Clean up" your project before final EXE compilation.
-
- When you are ready to compile your VB project into your 'finished'
- EXE, be sure to save the project files, exit VB, restart Windows,
- run VB, load your project and go straight to compiling. Otherwise,
- your EXE may be larger in file size than necessary due to
- 'garbage' getting included in the EXE. For some reason, VB does
- not fully clean up all of the previously used variables or objects
- that you may have been playing with while developing your program
- so these get included in your EXE even though they aren't used.
- Other VB users have even advocated saving all the project files as
- ASCII, then loading the ASCII files before compiling to further
- "clean up" the resulting EXE file.
-
- 3. Multiple END statements can be dangerous; or, The program that
- refused to terminate.
-
- Suggestion: put the END statement used to exit your program *only*
- in the Form_Unload event of the main form. Whenever you want to
- end the program, just tell the main form to unload.
-
- Some have reported that after their program have (supposedly)
- terminated, it still appears in the task list. This can happen if
- you only hide secondary forms and forget to unload them when you
- end/unload the main form.
-
- Also note that the Stop-button on the button-bar of the integrated
- development environment doesn't really unload anything. It *nukes*
- the program, which generally is a good idea since it could be a
- bug in it that caused it to be stuck in an eternal loop or
- something.
-
- 4. What are the latest versions of the various files used by VB?
-
- Date File to download Updates files Description
- 3/7/94 BTR110.EXE BTRV110.DLL Btrieve IISAM Driver
- 3/7/94 DATAINDX.EXE DATAINDX.DOC "Data Access Guide"
- Index
- 3/7/94 GENERIC.EXE \VB\CDK\GENERIC Sample custom control
- source
- 3/7/94 VBGRID.EXE GRID.VBX Grid control
- 3/7/94 VBHC505.EXE HC.EXE, HCP.EXE WinHelp compiler
- 3/7/94 MSAJT.EXE MSAJT110.DLL Access Database Engine
- 3/8/94 MSCOMM.EXE MSCOMM.VBX Serial
- Communications\control
- 3/7/94 ORA110.EXE ORACLE.TXT Updated ORACLE.TXT file
- 6/27/94 SETUPK.EXE SETUP.EXE Setup Toolkit
- 3/7/94 VBRUN300.EXE VBRUN300.DLL Visual Basic Runtime
- Library
- 3/7/94 XBS110.EXE XBS110.DLL XBase IISAM Driver
-
- There is an article in the Microsoft Knowledge Base that points to
- each of these files and provides more detailed information about
- the update. To find these articles, query the Microsoft Knowledge
- Base using the file name and the word "update3.00".
-
- Note the NEW SETUPKIT update!
- [Thanks to Marks Harrop <harrop@werple.apana.org.au>]
-
- Please inform the FAQ maintainer about newer versions.
-
-
- I. VISUAL BASIC FOR APPLICATIONS (VBA)
-
-
- 1. Any tips for VB/Win 3 programmers moving to VBA?
-
- You are in for some surprises. VBA is more unlike VB 3 than most
- people thought. Especially the development environment is very
- different, and the language puts more emphasis on objects. The
- latter is a trend you can get used to for VB also.
-
- For Excel 5 VBA, be aware that the environment is based on the
- "workbook" idea Microsoft stole from Borland. Your controls will
- be placed in one sheet, and the code will be in another.
- Doubleclicking on the control to open the code window doesn't
- help. You have to use the "Tools|Assign Macro" menu option.
-
- Also, be aware that the list of events is nowhere close to what
- VB3 supports! No GotFocus, no MouseMove, no nothing. You'll be
- very confused if you try to look for "events" in the VBA docs!
-
- 2. Does VBA support VBXs?
-
- No. If Microsoft have its way, VBX is a dead end. There will never
- be 32-bit VBXs, but OCXs using OLE 2. VBA is more a subset of VB 4
- than VB 3, but it does not fully support OCX yet. It will, though.
-
- 3. How do I access properties on my dialog boxes in VBA?
-
- As noted above, VBA is a culture chock to VB programmers. If you
- create a textbox in VBA, call it txName and try to
-
- cMyVar=txName.Text
-
- the impolite interpreter will give you a "variable not defined"
- error.
-
- The magic is objects. You have to
-
- Dim txName as Object
- Set txName = DialogSheets("NameDialog".EditBoxes("txName"))
-
- And then you can access your properties like you used to in good
- ol' VB 3. (Anyone volunteer to beat senseless the guy who thought
- out this?)
-
- 4. How do I use database routines from Excel VBA?
-
- The documentation is somewhere between sparse and inexistant on
- this topic. Any info on VBA and SQL would be much appreciated.
-
- Here Microsoft breaks the tradition and you *can't* use database
- objects, at least not the way you do in VB. Also, forget dynasets.
-
- I know nothing about databases in VBA. I just bring on the
- following tips from various magazines:
-
- Both SQLOpen and QueryGetData require a 'connection string'.
- That's about what the doc's say about the parameter. What is it?
- The doc is also tragically void of useful examples. Someone dug up
- the following example:
-
- "DSN=My data file;DBQ=c:\access\data.mdb;FIL=RedISAM;"
-
- which is about as understandable as it looks. If you use an empty
- string, you get a dialog which also can give you the string into a
- spreadsheet cell.
-
- Also, search for SQLREQUEST in the *main* help file for Excel 5
- (not the VBA help!) for these examples of connection_string's:
-
- dBASE DSN=NWind;PWD=test
- SQL Server DSN=MyServer;UID=dbayer;PWE=123;Database=Pubs
- ORACLE DNS=My Oracle Data Source;DBQ=MYSER VER;
- |UID=JohnS;PWD=Sesame
-
- There's a KnowledgeBase on Excel 5 on ftp.microsoft.com. Last time
- I looked, it was void of database stuff. Still, it may be a good
- idea to download it as the situation may have changed now.
-
-
- *** END OF VB/WIN FAQ DOCUMENT ***
-
- --
- Kris Nosack knosack@park.uvsc.edu
-
- >>>---> Be strange, but not a stranger! <---<<<
-