Visual Basic Developers Resource Centre

  Can I install VB6 without first performing the Java installation?
Sure! Before you attempt to install VB, just use Notepad to create a file under c:\windows\system32\ called msjava.dll - it can be 0 length.  The installer will see this file and bypass the installation section for the Java runtime.

Note: don't bypass this if you're installing Visual Studio 6 InterDev, as it's required here.

  Maximum Number of Controls on a Form (KB article 229756)
The maximum number of controls allowed on a single form depends on the type of controls used and available system resources. However, there is a fixed limit of 254 control names per form. This includes menus. (Although you can have up to 254 control names in a form, a large number of controls in a form will severely degrade your program's performance. In some cases, you will experience out-of-memory error. To maximize the performance of your program, you should minimize the number of controls in each form.)

There are three ways to work around the control name and system resource limitations:

  • Use control (and menu) arrays - instead of using several instances of a control (or menu) on a form, create a control (or menu) array for all the similar controls on the form. Members of an array share the same control name.
  • Dynamically create the controls as required - instead of loading all the controls on a form when you first display the form, try loading the controls as needed. This only works well when you potentially need many controls, but will use only a few of them at any given time. (For more information about dynamically creating controls, see KB article 190670 HOWTO: Dynamically Add Controls to a Form with Visual Basic 6.0)
  • Put your controls on a UserControl - similar to using a control array, you can create a UserControl that contains your controls and then add the UserControl to your project. For example, if you need a form that displays 50 text boxes, create a UserControl that contains 25 text boxes, and put two instances of your UserControl on the form. You now have 50 text boxes on the form, but only two control names counting towards the limit. Or better still, rethink your need for 50 text boxes at all!

  OK, how do I create a control array?
A control array is a group of similar controls that all have the same name but different Index property values. Each control array shares the same event procedures making development of applications easier, and because controls in a control array all share the same control name, this counts as one towards the maximum number of control names allowed on a form.

To create a control array with a new control placed on the form, either change the control's Index property to 0 or copy and paste the control and answer Yes to the resulting ehe unique controhe current actio n is taking place, and can thus be easily coded for different actions, if required, by using a Select Case Index block.

To make a control array out of an existing control the same technique is used, however the declarations for each of the control's event procedures that already contain code will need modification to introduce the Index property passed to the procedure.

  How do I create a menu array?
Like a control array, a menu array is a group of menu items under the same parent menu all having the same name but different Index property values. Each menu array member shares the same event code.

To create a menu array for a new menu added to the form, set each menu item's Index property to the next available Index property beginning at 0.  Menu array members must be contiguous (you can't break a menu array by inserting a different menu name midway through the list.  And menu can have any number of different menu arrays (for example under the File menu you may prefer to have one menu array for the New, Open, Save and Save AS options, and a second menu array for the Print and Print Preview options, or you can use the same menu array for the entire menu. (Naturally, just as for a normal menu the top-level menu item shown in the menu bar must be a different name than the items in its dropdown menu.)

Changing non-array menu into a menu array utilizes pretty well the same technique, however the menu code residing under the menu click events will need to be moved to the new menu's click event (the old procedures containing code will appear under the right-hand combo on the code window).

  PDW application installing Crystal Reports takes exceedingly long time.
When the PDW has packaged Crystal reports and corresponding RPT files into a single CAB file, the installation takes an extremely long time.  This is a known issue with the PDW and large cabs, and can be resolved by rerunning the PDW and selecting single-disk sized cabs. Although distribution via the web will become more difficult, the actual installation will proceed at an expected rate. If you need to package everything for the web as a single install, you'll have to either follow this suggestion then create a self-extracting exe using one of the pkzip or WinZip tools, use a third party install program, or the new Microsoft Installer, or look to utilities like Open Software Associates NetDeploy.


  'Unable to register <dllname>" error when installing Visual Basic.
Windows 95 and Windows 98 have a maximum registry size of 64k, while NT-based Windows have 64k key limits. This limit can be quickly met with the installation of some of the larger applications (i.e. Office 97/2000, VB6, Informix).  Most often the problem is related to unneeded and unreferenced string entries in the registry's Shared DLL key. The Shared DLL key is intended to store the path to all shared DLLs installed on the system. However, many applications use this as a repository for paths to non-DLL files which may not be installed in a customized or partial install, or which remain after an uninstall. VB6 is one such app that stores non-DLL data in this key. Because of the limit on the registry/key size, once the maximum has been reached the installer can't continue and the above (misleading) error is thrown.

VBnet has a Microsoft utility - shrdll.exe - available for download (less than 28k).  Shrdll.exe is used to identify -- and optionally remove -- those errant entries in the registry's Shared DLL section that consume valuable registry space but no longer point to valid files. I have found that using this utility on machines generating this error resolves the install problem, typically removing about 25k of unneeded entries. It is perfectly safe - I use it routinely on my own system after adding/removing programs.  But as it doesn't prepare an 'undo' file you are urged to export the 'Shared DLL' registry key if you are overly concerned.

  'Unable to register <dllname>" error when installing an application onto a user's Windows 95 or Windows 98 machine.
See the solution to the above FAQ.

  Can I add my own variables to a control event procedure in order to pass additional data to the event?
No. Form and control events that are listed in the Object combo box in the code window can only use the event variables assigned by VB that make up the event's default declaration.

  I have a simple project. Can I declare an API or user-defined type (UDT) just in a form?
Yes, however the declare or Type must be prefaced with the Private keyword. This restricts the scope of the variables (or APIs) to the form they are declared in. Be careful doing this, as its easy to forget to modify an API if a change is required when that API had been declared multiple times as Private in more than one form or module.

  How can I activate a running app, or launch it if it is not running?
Declare the FindWindow and BringWindowToTop APIs in a form or module, then use:

Private Sub Command1_Click()

   Dim hCalcWnd As Long
   Dim x As Long

   hCalcWnd = FindWindow("SciCalc", "Calculator")

   If hCalcWnd = 0 Then
        Call Shell("CALC.EXE", vbNormalFocus)
       Call BringWindowToTop(hCalcWnd)
  End If

End Sub

  How can I display an ampersand (&) in a menu item or in a label?
The ampersand is a special symbol to windows denoting a keyboard accelerator key (underscoring the ALT+<key> used to access the command from the keyboard). To display an actual ampersand in a label or menu, use two ampersands together, i.e. 'Save && Exit' displays as 'Save & Exit'. Some controls also provide a UseMnemonic property that can be toggled to display the ampersand without resorting to doubling the characters.

  Menus on Windows 2000 / XP / Vista etc. no longer show the keyboard accelerators (underlined Alt-letters)
The default setting for Windows 2000 is to hide keyboard accelerators until the user presses Alt. This is new behaviour. To configure Windows for the traditional (not to mention _expected_ behaviour), go to Control Panel, Display, Effects and uncheck the "Hide keyboard navigation until I use the Alt key" option.

  How do I use an accelerator in a label to have the focus move to the textbox or control associated with that label?
Label controls, although they support the ampersand accelerator and tabindex/tabstop, never actually receive focus. When a label is activated by the mnemonic key, control moves to the control having the next higher tabindex. So, by setting the tabindex of a textbox (or control) that you want to gain focus when the label mnemonic is pressed to 1 more than tabindex of the label, focus will move to that control when the accelerator key is pressed.

  I've finished designing my form. Is there an easy way to set the desired TabIndex for the controls at design time?
The easiest, sure-fire way of ensuring a user's tabbing between controls follows a route you desire is to set the TabIndex properties of all the controls backwards! Begin with the LAST control on the form that should receive focus using the Tab key, and set that control's TabIndex property to 0. Then move to the second-to-last control, and set that control's TabIndex to 0. Continue backwards through all the controls setting each control's TabIndex to 0 until you've assigned 0 to the first control on the form that will receive receive focus. All the tabs will be ordered ordered correctly - just run the project and hit tab to test the flow.  The free mztools (www.mztools.com) also provides a gui-based tab reordering utility.

  How can I find out how many MDI child forms are open in a MDI project?
The Count property of the Forms collection returns the number of forms currently loaded in the project. However, this number also includes the MDI parent form itself, as well as any other non-MDI child forms and hidden forms open in the project. To determine which open forms are actual MDI child windows, you can use:

Public Function GetMDIChildCount() As Integer

    Dim frm As Form
    Dim cnt As Integer

    For Each frm In Forms
        If (frm.MDIChild And frm.Visible) Then cnt = cnt + 1
    Next frm

    GetMDIChildCount = cnt

End Function

Call the routine as:
    NumberOfOpenForms = GetMDIChildCount()

  What is the easiest way to find the number of open forms in my app?
There are two ways - equally easy.   The first is to retrieve the form collection count...

   numFormsOpen = Forms.Count

...and the second is to use the DoEvents function!...

   numFormsOpen = DoEvents()

  How can I show the Windows95/98 'Open With' dialog in response to a command button click?
The Open With dialog can be invoked with the following code:

Private Sub Command1_Click()

   Call Shell("rundll32.exe shell32.dll,OpenAs_RunDLL [path]filename.ext")

End Sub

  How can my application receive command-line parameters?
Simple.  All command line parameters are passed to the VB program and are accessible via the Command$ function. Its fully documented in the VB help. Essentially its use is :
   Public Sub Main
      Dim sParams as String
      sParams = Command$()
      <do something with sParams>
   End Sub

  How do I call a procedure in one form from a routine in another form in VB4/5/6?
In VB4/VB5/VB6, any new sub or function that you create in the form will be exposed to all other forms and bas modules if you declare the routine as Public. Note though that you can not invoke a control's event this way, that is, you can not use Form2.Command1_Click. The routines that are listed in the code window Object combo box are always private to that form unless you change them to Public. However, this practice is unnecessary as the control and its properties are available to other forms and modules, and can be fired by using the <formname>!<controlname>.<property> syntax, as in Form2.Command1.Value = True.

  How do I call a procedure in one form from a routine in another form in VB3?
VB3 does not support Public routines in a form, so form-level routines are not directly callable from outside that form. Common or global routines must be declared in a BAS module.

  How do I declare a constant to make it available to all procedures in all forms?
In a BAS module, place the words Public Const (VB4, VB5, VB6) or Global Const (VB2, VB3) before the variable assignment.

  How do I declare a variable to make it available to all procedures in all forms?
In a BAS module, place the word Public (VB4, VB5, VB6) or Global (VB2, VB3) before the variable. You can also create private or public properties in BAS or CLS modules in VB5 and VB6.

  What is the scope of a variable DIM'med in different parts of a project? (excludes Static variables)
A variable DIM'med inside any sub or function (in any module or form) is local to that routine only (only known about by the dim'ming routine), and is destroyed upon exiting that routine.

A variable DIM'med as Private in the general declarations section of a Form is available only to routines in that form. The variable remains valid as long as the form is loaded.

A variable DIM'med as Public in the general declarations section of a Form (i.e. Public Foo As Long) is available to routines in that form by referencing the variable name (i.e. Foo), or to modules or forms other than the declaring form by explicitly referring to the variable with its form name as a prefix (i.e. Form1.Foo). The variable remains valid as long as the form is loaded.

A variable DIM'med Private in the general declarations section of a BAS module is available routines only in that bas module. The Private keyword is not available in VB2 or 3; use a standard DIM statement.

A variable DIM'med Public (or Global in VB2 or 3) in the general declarations section of a BAS module is available to all routines in all forms and bas modules.

A variable DIM'med inside any sub or function that has the same name as a Public or Global variable takes precedence over the Public one in that routine where it is DIM'med. Its initial value is 0 or empty. The Public variable's contents is not affected by use of the local variable of the same name. The local variable is destroyed upon exiting that routine; the global variable remains valid. Download a VB4 demo and view the code. Generally, using the same name for a Public and Local variable is considered poor programming practice.

  Why do I get an Overflow Error when multiplying:

          Dim x as Long
          x = 33 * 1000   
'generates overflow error

   ...yet when I set the value x = 33000 directly, it works with no error?

VB, in calculating the results to assign to x, uses a temporary variable. In doing so, it creates and uses an internal temporary working variable whose data type is the smallest possible one that would could contain without error either of the values being multiplied.

Because the both data types being multiplied are integers, VB uses an integer as the temporary working variable. As the result of the multiplication exceeds 32k (the limit for an integer), VB is forced to toss an overflow error (even though VB itself was responsible for creating the error in the first place!)

To ensure that VB will use an internal temporary working variable of a data type sufficient to hold the result (as opposed to each item), you must assign a type-declaration character to one of the values in the expression. This, following the rules stated above, forces VB to use an internal temporary working variable of sufficient capability to hold the result, thus completing the action without error. For example:

x = 33 * 1000&

x will hold the correct result, since the expression indicated that 1000 was to be treated as a Long (even though the value 1000 fits inside an integer) and thus VB used a long to create its internal temporary working variable. However, be aware that the code:

x = 33 * 1000 * 100&

will still generate the error. In this case, despite the inclusion of the Long declaration character in the expression, VB must perform the calculation in parts. Since the expression did not contain brackets forcing one portion to be evaluated over another, VB attempts to compute the first part of the multiplication ( 33 * 1000 ) into its internal temporary working variable created it as an integer, again generating the error. The fix under these circumstances is, as above, to assign the long to the one of the first two values being evaluated largest value, or to bracket the equation to have VB perform the computation containing the long first:

x = 33 * 1000& * 100
x = 33 * (1000 * 100&)

  VB says I don't have a license to use my controls. Why?
When you try to use some components in VB5 or VB6, a message box appears with the message "License information for this component not found. You do not have an appropriate license to use this functionality in the design environment." The problem stems from missing registry information, and can be repaired by running the version-specific Microsoft license fix utility listed on under the Control Fix section on the Dev Resources page

While these utilities will repair missing or damaged registry entries for controls provided with your version of Visual Basic, only those controls for which the VB version applies will be repaired. In other words, if you are attempting to use a VB control installed on your machine but not provided with your VB version (for example you have Learning Edition and you are trying to use a control provided with the Enterprise version) these utilities will not enable use of those unlicensed controls.

  How do I automatically maximize code windows in VB?
When using VB 6 in MDI mode, to force code/object windows to open maximized add a new key called 'MDIMaximized' to the registry as indicated below, and set its value to a string value of 1:

HKEY_CURRENT_USER/Software/Microsoft/Visual Basic/6.0/MDIMaximized = "1"

  How can I prevent a single-selection VB listview control from automatically selecting the first item?
Execute this once all the items have been added to the listview.  This only works for single-selection listviews:
   If Not ListView1.SelectedItem Is Nothing Then
      ListView1.SelectedItem.Selected = False
      Set ListView1.SelectedItem = Nothing
   End If

  How can I prevent a multiple-selection VB listview control from automatically selecting the first item?
Execute this once all the items have been added to the listview.  This works for single- and multi-select listviews:
   Dim itmx As ListItem

   If Not ListView1.SelectedItem Is Nothing Then

      For Each itmx In ListView1.ListItems
         itmx.Selected = False

   End If

  Using the API, how can I prevent the VB listview control from automatically selecting the first item in the list?
This takes a bit more code than above, but achieves the same result ...:
   Private Declare Function SendMessage Lib "user32" _
   Alias "SendMessageA" _
  (ByVal hwnd As Long, _
   ByVal wMsg As Long, _
   ByVal wParam As Long, _
   lParam As Any) As Long

   Const LVIF_STATE = &H8
   Const LVIS_SELECTED = &H2

   Private Type LVITEM
      mask As Long
      iItem As Long
      iSubItem As Long
      state As Long
      stateMask As Long
      pszText As String
      cchTextMax As Long
      iImage As Long
      lParam As Long
      iIndent As Long
   End Type

' code ----

   Dim lv As LVITEM
   Dim numSelected As Long

   With lv
      .mask = LVIF_STATE
      .state = False
      .stateMask = LVIS_SELECTED
   End With

   Call SendMessage(ListView1.hwnd, LVM_SETITEMSTATE, -1, lv)

  How can I set focus to a specific control when the form first loads? Using .SetFocus causes an error.
Focus can only be set to a control that is visible. Until the Load event of a form has completed, the form and its constituent controls are invisible and attempting to SetFocus to a control from the Load event will throw an error. 

To set the focus prior to displaying the form you have two options: set the tabindex of the control to have initial focus to 0 - either at design time or programmatically, or, in the Load event place an explicit Me.Show statement just before the code to SetFocus. Note however this last option is only available when the form is being shown non-modally; attempting to execute a Show statement for a modal form will generate an error.

  I want to install Visual Studio (or Visual Basic) on a new computer. Is there anything special I should know first?
The rule of thumb for installing any software onto a newer operating systems is to install the oldest applications first, then newer ones. For example, if you were installing Visual Basic 5, Visual Studio 6, Microsoft Office 2003, and Microsoft FrontPage 2002, you'd install VB5 first, then VS6, then FrontPage 2002, then Office 2003. I've used this rule when installing apps on all my systems from Win98 through XP and never had a problem at all.

Just be aware that when installing Visual Studio 6 or Visual Basic 6 on Windows XP, the installation CD will require that you first install the MS Java runtime, as on XP MS removed its java per agreement with Sun. Just do it and reboot, and the install will continue.

Remember to install the MSDN help afterwards (install will prompt you), unless you also have the later October 2001 MSDN library CD that also contains the VB help files. If you do have this later version of the MSDN you can skip the Visual Basic (or Visual Studio) MSDN install (say OK when warned that 'help will be unavailable'), and install the Oct 2001 MSDN instead. This will create/associate the MSDN with VB automatically and help will work as usual.



PayPal Link
Make payments with PayPal - it's fast, free and secure!


Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy


Hit Counter