Copyright: Copyright® 1994 David McCarter


CONTENTS
 Visual Basic For DOS

 Visual Basic For Windows

 Windows 3.1 Help Files

 Other Sources Of Help

 Programmer Tools

 VB Program Updates

 Release History

 About The Developer

 About Visual Basic Tips & Tricks

 Glossary Of Topics


VBDOS
Visual Basic For DOS

 Creating Global Variables

 Disabling The Text Box Beep

 Files & Directories


Creating Global Variables

How do I use (create) global variables in VBDOS? VBDOS provides the user with two types of global variables. These are both used in declarations of variables.

 To share variables between all subs and functions in a specific module, use the SHARED keyword. This makes that specific variable global _in that module_. For example:

DIM SHARED CancelFlag AS INTEGER

would make the variable CancelFlag a global variable in that module.

To share global variables between separate modules, use the COMMON keyword. For example:

COMMON SHARED CancelFlag AS INTEGER

 would make the variable global between all modules that this common statement appears in, and since we are using the SHARED keyword also, this will also be shared in all the subs and functions in the modules which this declare statement appears. All COMMON statements must be matched between modules which the variables should be global in. For example,  if you have one set of 10 COMMON statements in one module, and a different set of 10 COMMON statements in another module in the same project, you will get a 'Type Mismatch Error'. Make all COMMON blocks identical in all the modules in a specific project.

Tip From: VB/DOS Frequently Asked Questions


Disabling The Text Box Beep

Here's how to not make a text box beep when the the enter key is pressed.

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  '0 (zero) is nothing
   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. Usually they will want to jump to the next control, like the Tab key does. You will then change the line KeyAscii=0 to KeyAscii=9 (Key_Tab) in the example above.

 By the way, you'll also find this in the Microsoft VB Knowledge Base. They add that you should set the MultiLine
property to False. Of course.

Tip By: FAQ List


DOS_FINDING DIRECTORIES
Finding Directories

How do you test to see if a directory exists with Visual Basic for DOS? You might want to use the DIR$ command like this:

DIR$("c:\test\*.*")

This will work as long as there are files in the directory. But how about if the directory is empty? The above code won't work.

To get around this I use the "nul" specification. Every directory has a "nul" file in it, regardless if there are any other (real) files in it or not. Below is how to use it:

XY$ = DIR$("c:\test\nul")
IF XY$ <> "nul" THEN
   MKDIR "c:\test"
END IF

Submitted By: David McCarter


VBWIN
Visual Basic For Windows

 Buttons & Image Control

 Communications

 Controls

 Disks & Files

 Forms

 Graphics

 Hot Spots

 List Boxes

 Menus

 Miscellaneous

 MS Access

 Sounds

 Speed And Size Tips

 Text Boxes

 Windows


BUTTONS_IMAGE
Buttons & Image Control

 Image Control As A Button

 Mouse Button Up Or Down Status


IMAGE CONTROL AS BUTTON
Image Control As A Button

One of the easiest techniques for adding graphical effects to your program is to use an image control as a button. When the image control receives a Click event, you simply substitute the value of the Picture property. The key to this technique is to define a pair of invisible image controls with pictures corresponding to the up and down status of the control.

For example, you could create a button that visually represents a locked and unlocked state. One advantage of using icon files rather than bitmap files is that any underlying image shows through the mask area of the icon.

When the form is loaded, the Form_Load event procedure sets the appropriate image in the image control:

Sub Form_Load()
   Padlock.Picture = LockOpen.Picture
End Sub

The image control responds to the click event by replacing the picture in the control:

Sub Padlock_Click()
Static LockedFlag As Integer
If LockedFlag Then
   Padlock.Picture = LockOpen.Picture
      Else
 Padlock.Picture = LockClosed.Picture
End If
LockedFlag = Not LockedFlag
End Sub

Source: Microsoft Developer Network News, July 1993


MOUSE BUTTON UP OR DOWN
Mouse Button Up Or Down Status

Here is how to check the mouse button 'up_or_down' status.

Declare Function GetKeyState Lib "user" (ByVal k%) As Integer
Declare Function GetAsyncKeyState Lib "user" (ByVal k%) As Integer

This functions will tell you whether a key is up or down, and if it's "toggled". The high order bit tells you if the key is up or down. The low order bit tells you if it's toggled - each time the key is pressed and then released the low order bit will change.

The first function maintains the keyboard state when the last *window message* was received by the app and is the one you normally use. The second one corresponds to the real time keyboard state.

Now, why on earth do I talk keyboard when the question was about the mouse? - That's because the mouse buttons are considered as "virtual" keyboard keys. Some virtual key codes are:

VK_LBUTTON     1
VK_RBUTTON     2
VK_MBUTTON     4
VK_TAB         9
VK_ESCAPE     27

So to wait for the left mouse button to be first pressed and then released you could use:

Do While GetKeyState(VK_LBUTTON)>=0: DoEvents: Loop
Do While GetKeyState(VK_LBUTTON)<0: DoEvents: Loop

Submitted By: Dan Bystrom - InterNet:adbbyd@msmail.hk-r.se


Communications

 Dialing A Phone


Dialing A Phone

Here's how to dial a phone number using the MSCOMM VBX in VB Pro.  The MSCOMM VBX 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

Tip From: VB/WIN Frequently Asked Questions


Controls

 Copying Data From A Grid Control

 Searching A List Or Combo Box

 Using Controls Indirectly To Change Data


Copying Data From A Grid Control

The grid control in Visual Basic provides the CLIP method for copying cells to the clipboard from the grid.  The CLIP method puts a tab between each column and a line feed between each row.  This works great for copying to Excel (I have not tried other spreadsheets), but does not work well copying into word processors because only the line feed is placed between each row, not line feed and carriage return.  The Visual Basic manual describes how to insert the carriage return by copying the string one character at a time, inserting the carriage return in the appropriate places.  Copying the grid with both line feed and carriage return allows pasting in Excel and word processors.

Looking at each character is time consuming.  I have found that it is faster to copy each cell individually, inserting the tab and CR/LF characters as needed.

Below is the routine I use to copy an entire grid.  Note that fixed rows and columns are not copied.  To copy fixed rows and columns, you would set First_Col and First_Row to 0.

Note also that I set the MousePointer to 11 (Hourglass) at the begining and set it back to 0 (default) at the end.  This is because large grids may still take a few seconds to copy on slower systems.

Sub CopyGrid_Click ()

Dim CopyText, NC, NR As String
Dim First_Col, First_Row As Integer

screen.MousePointer = 11

Clipboard.Clear

    	NC = Chr$(9)
    	NR = Chr$(13) & Chr$(10)

    	First_Col = datagrid.Fixedcols
    	First_Row = datagrid.FixedRows

    	For i% = First_Row To datagrid.Rows - 1
        	datagrid.Row = i%
        	For j% = 0 + First_Col To datagrid.Cols - 1
        d	atagrid.Col = j%
            	If j% = First_Col Then
                	CopyText = CopyText & datagrid.Text
            	Else
                	CopyText = CopyText & NC & datagrid.Text
            	End If
        	Next
        	CopyText = CopyText & NR
    	Next

    	Clipboard.SetText CopyText

    	screen.MousePointer = 0

End Sub

Submitted By: Dennis Cabell


Searching A List Or Combo Box

I know of a couple of ways to do this. The first uses a combo box with the "style" property set to "0". Put the following constants in your declaration section:

Const WM_USER = &H400
Const CB_FINDSTRING = (WM_USER + 12)
Const CB_FINDSTRINGEXACT = (WM_USER + 24)
Const CB_SHOWDROPDOWN = (WM_USER + 15)
Const CB_GETDROPPEDSTATE = (WM_USER + 23)

Put the following functions in your declaration section:

Declare Function SendMessageByString Lib "user" Alias "SendMessage" (ByVal
hWnd%, ByVal wMsg%, ByVal wParam%, ByVal lParam$) As Long
Declare Function SendMessageByNum Lib "user" Alias "SendMessage" (ByVal
hWnd%, ByVal wMsg%, ByVal wParam%, ByVal lParam&) As Long

Put the following code in your combo box's keypress event:

Dim flgIsdropped As Integer
Dim lngRetval As Long

'if return was pressed, then set the combobox.listindex to the first match in the list

'The parameters (in order) are: window handle to the combo box, constant 'to find the first match in the list, the list position to start the 'search from, the text to search for.

If KeyAscii = 13 Then
   combobox.ListIndex = SendMessageByString(combobox.hWnd, CB_FINDSTRING, 0,combobox.Text)
   Exit Sub
End If

'if the list box is not already dropped, then drop it

'returns nonzero if list box is dropped, zero otherwise
flgIsdropped = SendMessageByNum(combobox.hWnd, CB_GETDROPPEDSTATE, 0, 0)

If Not flgIsdropped Then
    'set third paramater to true to show dropdown box, false to hide it
    lngRetval = SendMessageByNum(combobox.hWnd, CB_SHOWDROPDOWN, True, 0)
End If

Put the following code in your combo box's lostfocus event:

combobox.ListIndex = SendMessageByString(combobox.hWnd, CB_FINDSTRING, 0,
combobox.Text)

This code checks to see if the list box has already been dropped and drops it if need be. Once the list box gets dropped, Windows takes care of moving the list around to seek an entry that matches what the user has typed. The
disadvantage to using this method is that even though Windows displays the entry that matches the typed string, I don't know how to get Windows to highlight the entry. If anybody knows how to do this, I would like to hear about it. The other option is to use a text box and a list box. Put the following code in the text box's change event:

listbox.ListIndex = SendMessageByString(combobox.hWnd, LB_FINDSTRING, 0,
combobox.Text)
(LB_FINDSTRING is WM_USER+16)

If you want to find an exact match, the constant is:

LB_FINDSTRINGEXACT (WM_USER+35)

Then put code in the text box's lost focus event that changes the text to the selected list index. This option will mimic the operation of the search box in help files. The disadvantage is that you have that big list box on your
screen all the time. (Although I guess you could toggle the visible property)

Tip By: Scott Hamilton


USING CONTROLS INDIRECTLY
Using Controls Indirectly To Change Data

In certain cases, you might not want the user to change data in a control directly, but indirectly using another control. This technique can minimize, or even eliminate the process of validating user input.

Let's say you want the user to enter a due date that is from 1 to 30 days from today's date. You can solve this scenario by using a horizontal scroll bar that modifies the Caption property of a label:

The scroll bar property settings are:

LargeChange=5
Min=1
Max=30

Every time you change the scroll bar value, the HScroll1_Change event procedure is generated, which in turn calls the DisplayDate procedure:

Sub HScroll1_ Change ()
   DisplayDate
End Sub

Sub DisplayDate ()
   TimeVal = Now + HScroll1.Value
   Label1.Caption = Format(timeVal, "mm/dd/yy")
End Sub

The TimeVal variable contains the current time returned from the Now function plus the current setting of the scroll bar's Value property (1-30). In Visual Basic, adding integer values to a time value increments the time value by days.

Lastly, to set the initial date value on the label, you need to call the DisplayDate procedure when the form is loaded:

Sub Form_Load ()
   DisplayDate
End Sub

Source: Microsoft Developer Network News, September 1993


DISKSFILES
Disks & Files

 Formatting A Foppy Disk


Formatting A Foppy Disk

Below is code on how to format a floppy disk from Visual Basic for Windows.

Type Rect
    Left As Integer
    Top As Integer
    Right As Integer
    Bottom As Integer
End Type

Declare Sub SetWindowPos Lib "User" (ByVal hWnd As Integer, ByVal hWndInsertAfter As Integer, ByVal x As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal wFlags As Integer)
Declare Sub GetWindowRect Lib "User" (ByVal hWnd As Integer, lpRect As Rect)
Declare Function IsWindow Lib "User" (ByVal hWnd As Integer) As Integer
Declare Function WinExec Lib "Kernel" (ByVal lpCmdLine As String, ByVal nCmdShow As Integer) As Integer
Declare Function SetActiveWindow Lib "User" (ByVal hWnd As Integer) As Integer Declare Function GetActiveWindow Lib "User" () As Integer
Declare Function LockWindowUpdate Lib "User" (ByVal hwndLock As Integer) As Integer
Declare Function GetDesktopWindow Lib "User" () As Integer
Declare Function FindWindow Lib "User" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Integer
Declare Function PostMessage Lib "User" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Long) As Integer
Const WM_COMMAND = &H111
Const WM_CLOSE = &H10
Dim wFlag%
Dim lpDlgRect As Rect
Dim lpDskRect As Rect
Const SWP_NOSIZE = &H1
Const SWP_NOZORDER = &H4

Sub CenterDialog (WinText As String)
   Do
    If FindWindow(0&, WinText) Then Exit Do
    x% = DoEvents()
   Loop

 wnd% = GetActiveWindow()
 Call GetWindowRect(wnd%, lpDlgRect)
 wdth% = lpDlgRect.Right - lpDlgRect.Left
 hght% = lpDlgRect.Bottom - lpDlgRect.Top
 Call GetWindowRect(GetDesktopWindow(), lpDskRect)
 Scrwdth% = lpDskRect.Right - lpDskRect.Left
 Scrhght% = lpDskRect.Bottom - lpDskRect.Top
 x% = (Scrwdth% - wdth%) / 2
 Y% = (Scrhght% - hght%) / 2
 Call SetWindowPos(wnd%, 0, x%, Y%, 0, 0, SWP_NOZORDER Or SWP_NOSIZE)
End Sub

Sub FMFormat (F As Form)

    FMhWnd = FindWindow("WFS_Frame", 0&)

    If FMhWnd = 0 Then
    i% = WinExec("Winfile", 0)
    FMhWnd = FindWindow("WFS_Frame", 0&)
       If FMhWnd = 0 Then
           MsgBox "FileMan ain't home"
           Exit Sub
       End If
    wFlag = 1
    End If

    i% = LockWindowUpdate(GetDesktopWindow())

    i% = PostMessage(FMhWnd, WM_COMMAND, &HCB, 0)

    Call CenterDialog("Format Disk")

    i% = LockWindowUpdate(0)

    wnd% = GetActiveWindow()

    While IsWindow(wnd%)
    x = DoEvents()
    Wend

    x = DoEvents()

    If wFlag Then
    wFlag = 0
    i% = PostMessage(FMhWnd, WM_CLOSE, 0, 0)
    End If

    i% = SetActiveWindow(F.hWnd)

End Sub

Tip By: Woody Pewitt


Forms

 Detecting Previous Instances Of A Program

 Portable Forms

 Setting The "TabIndex" Property

 Setting Video Resolution for Multiple Forms


DETECTING PREVOUS INSTANCES OF A PROGRAM
Detecting Previous Instances Of A Program

There are times when you may want to prevent a second instance of your program from running. The App object provides a PrevInstance property that allows you to determine whether a previous instance of the program is running. Here's how you might write your code:

Sub Form_Load ()
If App.PrevInstance Then
   msg$ = App.EXEName & " already running "
   MsgBox msg$, 48
   End
End If
End Sub

Notice that the procedure uses the EXEName property of the App object to display the program's name in the Visual Basic message box.

Source: Microsoft Developer Network News, July 1993


Portable Forms

The following gives a nice way to produce forms on one screen resolution while keeping the same aspect ratio on other resolutions.

While designing a form the programmer should choose the twips unit, and should always design using one fixed resolution (i.e. 800x600). What I mean by that is when a button is designed on an 800x600 screen it will become larger and maybe outside the screen area on a 640x480 screen.

To avoid such an annoyance we should read Screen.Width and Screen.Height during design time, and during run time. This will provide us with a ratio with respect to the reference at design time. This ratio is then used to readjust the form, shape, and/or button or all of the visible controls when the form is run. For example try:

Shape1.Width = Shape1.Width * Ratio

Where Ratio is Screen.Width / SCREEN_WIDTH_REFERENCE for the X coordinate, in a similar way this could be done for the Y coordinate.

Submitted By: Nadim El-fata


SETTING THE TABINDEX PROPERTY
Setting The "TabIndex" Property

Here is a no-fuss method of setting the "TabIndex" property at design time.

One of the most enjoyable features of the Visual Basic environment is its ease of form design.  Just plop some controls on a form, drag them around until you get the most appealing layout and you're done.  Except of course you have to go back and set the "TabIndex" property for all the controls to match your final design.

My method used to be to click the first control, set its "TabIndex" to 0, click the next control set its "TabIndex" to 1, ... until I discovered this trick.  Start with the last control (usually the bottom right) and work your way backwards (left and to the top).  Each time you click a control set its "TabIndex" property to "0".  When you reach the first control all "TabIndex" properties will now be in the correct order.  This method works since VB references the "TabIndex" property for all controls on the form when you change the property to a value that already exists on another control.  This method is even easier with the new properties window in VB3 because the "TabIndex" property will keep the focus even as you click controls.  Just keep one finger on the "0" button and the other on the mouse.  Then click, press "0", click, press "0", click press "0"...

Submitted By: Kyle Lutes


Setting Video Resolution for Multiple Forms

Following is a subroutine that will set the video resolution for multiple forms.

Load Form
Call SetDeviceIndependentWindow(Form)
Form.Show

The subroutine was in a different module and this has always worked for
me but I also have never tried to call it from the Form Load Event.

As a side note, I had to make a change in the subroutine in order for it work with my machine.  The subroutine relies on the fact  that Screen.TwipsPerPixelX, Screen.TwipsPerPixelY will change according to whatever video resolution is selected.  My problem may be due to the fact that the video drivers for the Cirrus Logic video chip have been written poorly but on my system irregardless of what video resolution I was in 640 x 480, 800 x 600, etc. the value for Screen.TwipsPerPixelX or Y never changed from 12 but I have worked on other machines with different video cards and the value did change.  I have included a modified version of the routine.

Sub SetDeviceIndependentWindow (TheForm As Form)

    Dim DesignX%
    Dim DesignY%
    Dim XFactor As Single
    Dim YFactor As Single
    Dim Z As Integer

'    DesignX% = 12
'    DesignY% = 12

'    XFactor = DesignX% / Screen.TwipsPerPixelX
'    YFactor = DesignY% / Screen.TwipsPerPixelY

**  This is what I changed, I design my screens to look appropriate for VGA
and
**  then resize the screen if the user is using a higher video resolution
>
>   XFactor = Screen.Width / 9600
>    YFactor = Screen.Height / 7200
>
>    If XFactor = 1 And YFactor = 1 Then
>        Exit Sub
>    End If

    TheForm.Move TheForm.Left * XFactor, TheForm.Top * YFactor,
TheForm.Width * XFactor, TheForm.Height * YFactor

    For Z = 0 To TheForm.Controls.Count - 1

        'If TypeOf TheForm.Controls(Z) Is CommonDialog Then
        If TypeOf TheForm.Controls(Z) Is Timer Then
        ElseIf TypeOf TheForm.Controls(Z) Is Menu Then
        ElseIf TypeOf TheForm.Controls(Z) Is Line Then
        ElseIf TypeOf TheForm.Controls(Z) Is DriveListBox Then
            TheForm.Controls(Z).Move TheForm.Controls(Z).Left * XFactor,
TheForm.Controls(Z).Top, TheForm.Controls(Z).Width * YFactor
        ElseIf TypeOf TheForm.Controls(Z) Is ComboBox Then
            If TheForm.Controls(Z).Style <> 1 Then
                TheForm.Controls(Z).Move TheForm.Controls(Z).Left * XFactor,
TheForm.Controls(Z).Top * YFactor, TheForm.Controls(Z).Width * XFactor
            End If
        Else
            TheForm.Controls(Z).Move TheForm.Controls(Z).Left * XFactor,
TheForm.Controls(Z).Top * YFactor, TheForm.Controls(Z).Width * XFactor,
TheForm.Controls(Z).Height * YFactor

            If TypeOf TheForm.Controls(Z) Is TextBox Then
                TheForm.Controls(Z).FontSize = TheForm.Controls(Z).FontSize
* XFactor
            ElseIf TypeOf TheForm.Controls(Z) Is Label Then
                TheForm.Controls(Z).FontSize = TheForm.Controls(Z).FontSize
* XFactor
            End If
        End If
     Next Z

End Sub

Tip By: Russell Brandon


Graphics

 Decoding Binary CGM Graphics


Decoding Binary CGM Graphics

Here is how you decode binary CGM (Computer Graphics Metafile) files in Visual Basic 3.0 std.  The binary CGM standard specifies byte-order and bit-order for multi-byte binary numbers as left-to-right (big-Endian), but the PC byte order is not left-to-right, it is little-Endian.

Byte-swapping is simple in C or C++, but not so simple in visual basic. (Problems with sign extension in signed integer types, and no unsigned integer types.)  Thus, I used the following function to swap two-byte integers:

Function SwapBytes (num As Integer) As Integer
' Take an input integer, assumed to be in "left to right" byte order, and convert it to "standard" Intel format by swapping the two bytes.

Dim TextVal As String
Dim NewTextVal As String
Dim StringLength As Integer

TextVal = Hex$(num)
StringLength = Len(TextVal)
Select Case StringLength
Case 1
   NewTextVal = "&H" & "0" & TextVal & "00"
Case 2
   NewTextVal = "&H" & TextVal & "00"
Case 3
   NewTextVal = "&H" & Right$(TextVal, 2) & "0" & Left$(TextVal, 1)
Case 4
   NewTextVal = "&H" & Right$(TextVal, 2) & Left$(TextVal, 2)
End Select
SwapBytes = Val(NewTextVal)
End Function

Submitted By: Steven W. Layten - InterNet: swl26@cas.org


UC
This Topic Is Under Construction!


List Boxes

 How To Find Program Manager Groups

 Tab Stops In A List Box

 Searching A List Box


PM GROUP LIST
How To Find Program Manager Groups

Below is how to get a list of all the Program Manager groups into a list box.

There are two ways to do this that I know of.  One is an API call that uses the Progman.Ini file.  I like the second method which uses Dynamic Data Exchange (DDE).

1	 Place a textbox, a listbox, 2 labels, and 1 command  button on a form.  Keep the default names.

Sub Form_Load ()
    Move (screen.Width - Width) \ 2, (screen.Height - Height) \ 2
    text1.LinkTopic = "Progman|Progman"
    text1.LinkItem = "Progman"
    text1.LinkMode = 2
    text1.LinkRequest

    On Error Resume Next
    text1.LinkMode = 0

    text$ = text1.Text
    length = Len(text$)
    ReDim x$(length)

    text1.SetFocus

    For i = 1 To length
        dummY$ = Mid$(text$, i, 1)
            If dummY$ = Chr$(13) Then
                i = i + 1
                a = a + 1
            End If
            x$(a) = x$(a) + dummY$
    Next i
    text1.Visible = False
    For i = 1 To a
        x$(i) = Mid$(x$(i), 2, Len(x$(i)) - 1)
        list1.AddItem x$(i)
    Next i
    list1.ListIndex = 0
End Sub

Sub List1_Click ()
    label1.Caption = list1.Text
    text1.Text = list1.Text
End Sub

Sub Command3D1_Click ()
    Unload form1
    End
End Sub

I started this because I wanted my users to be able to choose what group my program would be installed to.  To do that you would just need to add a line of code to the Form_Load procedure, and add another Command button.  Attach code to the new button that initiate DDE again, and use CreateGroup, Additem, and ShowGroup.  If anyone wants this, send me Email via Internet.  Michael.Eaton@bbs.meu.edu.

Submitted By: Michael Eaton


Tab Stops In A List Box

The standard Visual Basic list box supports tab stops. This means that if the string value you add to the list box contains tab characters, the tabs cause the list box to display columns of strings.

Here's how to add the first item to the list box:

t=Chr$(9)
name="Michael Cage"
list1.AddItem name + t + "44" + t + "C/F"

You could also narrow the width of the list box so that you don't display the second and third columns. This technique allows you to store multiple strings per item, while only displaying the first string. Notice, however, that you would need to write additional code to extract specific strings.

Taking the idea of a list box as a storage mechanism one step further, you could make the list box invisible and only refer to it in your code.

Source: Microsoft Developer Network News, July 1993


Searching A List Box

Here is how to search a list box using API calls:

Declare Function SendMessage Lib "User" (ByVal hWnd%, ByVal wMsg%, ByVal wParam%, lParam As Any) As Long
Declare Function SendMessageByNum Lib "User" Alias "SendMessage" (ByVal hWnd%, ByVal wMsg%, ByVal wParam%, ByVal lParam&) As Long
Declare Function SendMessageByString Lib "User" Alias "SendMessage" ByVal
hWnd%, ByVal wMsg%, ByVal wParam%, ByVal lParam$) As Long

' This code belongs wherever you are doing the search
'
Dim SearchString as String
Dim StringPos as Long,Result as Long

SearchString = "String to find"

StringPos = SendMessageByString&(List1.hWnd, LB_FINDSTRING, 0, SearchString)
If (StringPos >= 0) Then
   Result = SendMessageByNum(List1.hWnd, LB_SETTOPINDEX, CInt(StringPos), 0)
End If

This will find the position in the listbox that the string is found in, and then scroll the listbox so that the string can be seen.  You might also want to look into LB_SELECTSTRING (if it is a single selection listbox).  I think
I originally found this in Appleman's book - if so then all credit to him.  Even if not it is a fine book (like we haven't heard that from 10,000 other people in this group) and well worth the money to have as a reference.

Tip By: Andrew Dowswell


Menus

 Changing The Control Box Menu

 Help Menu On Right Side Of Menu Bar

 Pop-up Menus


Changing The Control Box Menu

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're doing something critical in your VB program that should not be interrupted and 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 in your code to remove the "close" option:

SystemMenu% = GetSystemMenu (hWnd, 0)
Res% = RemoveMenu(SystemMenu%,6, MF_BYPOSITION)
Res% = RemoveMenu(SystemMenu%,6, MF_BYPOSITION) 'also remove the separator line

 Check out the GetMenuID and InsertMenu API functions to do more complicated tasks.

Tip From: VB/WIN Frequently Asked Questions


Help Menu On Right Side Of Menu Bar

To position the Help Menu to the right side of the Menu Bar, use a backspace character (Chr$(8)) as the first character in the Caption property of the menu. You must do this at runtime, in the Form_Load event.

HelpMenu.Caption= Chr$(8) & HelpMenu.Caption

Tip By: Brian Dalton


POPUP MENUS
Pop-up Menus

One of the new features of Visual Basic 3.0 is pop-up menus. You can easily create a pop-up menu from an existing menu structure. Let's look at how you would create a pop-up menu from the traditional menu in the Blanker sample application provided with Visual Basic (in your VB\SAMPLES\GRAPHICS directory).

First, use Menu Design windows to set the Visible property of mnuOption to False. Then, add the following event procedure to display the pop-up menu:

Sub Form_MouseUp (Button As Integer,...)
If Button = 2 Then
   PopupMenu mnuOption
End If
End Sub

Notice that the Form_MouseUp event procedure uses the right mouse button to display the menu.

Source: Microsoft Developer Network News, July 1993


Miscellaneous

 Automatic Selection Of Text

 Creating Screen Savers

 Easy Help

 Finding Hard/Floppy/Removable Drives

 Imitating A Combo Box

 Reading INI Files

 Re-reading The WIN.INI File

 Printer Control

 Setting TabIndex At Design Time

 Starting A Large Application

 Tool Box

 Restarting/Exit Windows

 Using Undo


Automatic Selection Of Text

When using text boxes, it is often useful to generate automatic selection of text when the control gets focus. You can do this easily by adding a couple of lines to the GotFocus event procedure:

Sub Text1_GotFocus ()
Text1.SelStart = 0
Text1.SelLength = 65000
End Sub

Notice that the length value for SelLength is 65000, nearly the maximum length allowed in a text box. This forces Visual Basic to use the actual length of the text as the SelLength.

Source Microsoft Developer Network News, July 1993


Creating Screen Savers

Overview:

Have you ever wanted to write your own screensaver, but was told, "You can't do that in Visual Basic!" In fact, one person I heard from told me that Microsoft said that screensavers were impossible in Visual Basic. I didn't believe hem, and this is the result.

Windows screensavers are easy and fun to write in Visual Basic, but there are some very important things to know.

Experts can go straight to the Code Section of this document.

Description:

Application Title:

A Windows screensaver is nothing more that a regular Windows executable file that has been renamed with the .scr extension. In Visual Basic, when you are making the executable file, you will need to set the Application Title in the Make EXE dialog box. This Application Title MUST be set to "SCRNSAVE title", where title is the text you want displayed in the Control Panel screensaver dropdown box.

Command Line Arguments:

When Windows starts up a screensaver it calls it with the "/s" argument, and when it wants to Setup the screensaver it uses the "/c" argument. So, we use a code module called SCRNSAV.BAS. In SCRNSAV.BAS you will see that a Select Case statement is used to capture this argument. You will need to change the Startup Form in the options|Project Dialog Box to Sub Main.

Telling Windows that the Saver is Running:

How long Windows waits before loading the screensaver is specified in the Control Panel. But if your screensaver doesn't tell Windows that it is running, Windows will reload the screensaver after that time passes again, even though the screensaver is already running. At first I thought I could remedy this situation by using VB 3.0's App object. The App.PrevInstance property will tell you whether or not there is a previous instance loaded.

This should've worked, and I got many comments saying that I must have messed something up, but it didn't. For some reason, with the screensaver this kills both instances, not just the second. But there is a way out. To fix this I found a Windows API call which tells Windows that the screensaver is inactive, so don't load one. To use this API you need to use the API call SystemParametersInfo. This function is used to change system wide parameters, such as whether or not the screensaver is active. Be careful when using this call, since changes are permanent. You will need to make sure that your screensaver turns the screensaver back off when it has ended.

See Sub Main, and Sub ExitNice in the Code Section.

Hiding The Cursor:

When you write a screensaver, you'll want it to hide the mouse cursor as well as whatever else your saver does. To do this you need to use the API call -  ShowCursor. When ShowCursor( False ) is called, the cursor is hidden; when ShowCursor( True ) is called, the cursor is re-displayed. The Windows cursor is a shared object, so if your process hides it your process needs to redisplay it as well. See Code section.

Knowing when to end:

When your screensaver ends is up to you, but generally you'll want it to end if any of the following occur: mouse moves, button pressed, key pressed. To do this you will need to call a routine to exit properly from each of these
  events in your screensaver form. See SaverForm. You need to call this routine because this is where the other half of the SystemParametersInfo call is made. If this is left out, the screensaver won't run again after it wakes up. Another problem is that the MouseMove message is sent if the cursor is over the form, REGARDLESS if it is moved or not. So, you need to check to see if it has moved somehow. See the Code Section for my solution. (Not necessarily the prettiest.

Code:

ScrnSave.Bas

declarations
    DefInt A-Z
    Const SWP_NOSIZE = 1
    Const SWP_NOMOVE = 2
    Const SPI_SETSCREENSAVEACTIVE = 17
    Declare Function ShowCursor Lib "User" (ByVal bShow As Integer) As Integer
    Declare Sub SetWindowPos Lib "User" (ByVal hWnd, ByVal After, ByVal X,
      ByVal Y, ByVal cx, ByVal cy, ByVal Flags)
    Declare Function SystemParametersInfo Lib "User" (ByVal uAction, ByVal
      uParam, lpvParam As Any, ByVal fuWinIni)

  Sub Main
    Select Case Command$
      Case "/s", "/S"
        Res = SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, ByVal 0&, 0)
        Load SaverForm
        SetWindowPos SaverForm.hWnd, -1, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
        ok = DoEvents()
      Case "/c", "/C"
        ConfigForm.Show
    End Select
  End Sub

You may also need to add some initialization code for whatever your screensaver does.

Sub ExitNice
    Res = ShowCursor(True)  'Turn the cursor back on
    'reset screensaver
    Res = SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, ByVal 0&, 0)
    End
  End Sub

Saver.Frm
  Form_Load
    WindowState = 2	'Maximize the screensaver
    Me.Show	'Show the form
    This = ShowCursor(False)	'Hide the cursor

  Form_MouseMove
    If (OldX = 0) And (OldY = 0) Then
      OldX = X
      OldY = Y
      Exit Sub
    End If

    If (OldX <> X) Or (OldY <> Y) Then
      ExitNice
    Else
      OldX = 0
      OldX = 0
    End If

  Form_Click
    ExitNice

  Form_MouseDown
    ExitNice

  Form_KeyDown
    ExitNice

  Form_KeyPress
    ExitNice

Config.Frm

Windows will pass the "/c" argument to Sub Main if the "Setup" option is chosen from control panel. Here you can setup specific options for your screensaver. You might want to save these options in a .ini file (win.ini or your own). Its up to you! If your Config.Frm has a "Test" feature which starts the screensaver from the Config form, then you will need to be careful about remembering to turn on the cursor after the screensaver starts, and then turn it off before it ends.

Sources:

Conger, James L.., The Wait Group's Windows API Bible: The Definitive Programmer's Reference. The Wait Group: 1993. ISBN 1-878739-15-8
VBZ: The Electronic Journal on Visual Basic. Copyright 1993 User Friendly, Inc. Issue 01: January/February 1993

Disclaimer/Distribution:

This information is provided free of charge, and may be freely distributed. If you use portions of this document elsewhere, please indicate where you got it. All of the information here has been used and tested by me in Visual
Basic 3.0 Professional. Use at your own risk. Visual Basic and Microsoft Windows are registered trademarks of Microsoft Corp.

Submitted By: Peter Provost (provost@cs.colostate.edu)


Easy Help

I created a simple VB for Windows program that print company files to any network printer. I designed it to be easy to operate. When I went to write the help file, I decided against it. This would mean I would have to provide an additional file with the program and the time involved to write the help file was too much. I decided to add a text box with one line of help for each button.

I started by creating a SSPanel using the THREED.VBX file (any type of text box will do just fine). Then using the MouseMove event I added the following lines:

Sub Print_Now_MouseMove (Button As Integer, Shift As Integer, X As Single, Y As Single)
HelpText = "Sends the selected file to the selected location"
End Sub

It's that simple! You can also use MouseDown, MouseUp, GotFocus events. I found the MouseMove the easiest to use. Just make sure when you code your program that all the buttons and the form have some kind of help text otherwise the mouse could be over a button and display the wrong help line.

Submitted By: David McCarter


FINDING HARD DRIVES
Finding Hard/Floppy/Removable Drives

If you need to find what floppy drives, hard drives or removable drives (CD-ROM/Network) there is on a system, declare the following in a BAS file:

Declare Function GETDRIVETYPE Lib "Kernel" (ByVal nDrive As Integer) As Integer

You must pass this function the drive number, not a drive letter. Drive numbers always start a 0. For instance, drive A: is drive #0, Drive C: is drive #2.

DRIVETYPE = GETDRIVETYPE(DRIVENUM)

This function returns a 2 for removable drives, 3 for fixed drives or 4 for remote drives. This function will return a 0 if it is passed a drive number that does not exist on the system.

Submitted By: David McCarter


Imitating A Combo Box

To imitate a ComboBox that behaves like the one that appears in the "Search" option of Help, use this tip.

First, create a Textbox (eg. Text1) and a Listbox (eg. List1). Then paste the following code into the Declarations section of a form that contains the textbox and the listbox, and the bottom part of the code into a separate module.

Note the flags (in the declaration part of the module) that make this code not reentrant: it only permits one "combo" at a time (though many per application), but you can change this easily.

Code for module:

Option Explicit

Global CHClickList As Integer
Global CHInChange  As Integer

Sub CtrlTB_Change (OTB As TextBox, OLB As ListBox)
    Dim Pos As Integer, I As Integer, L As Integer
    Dim Aux As String

    If CHClickList Then
        CHClickList = False
        Exit Sub
    End If

    Aux = OTB.Text

    L = Len(Aux)
    For I = 0 To (OLB.ListCount - 2)
        If Not StrComp(Aux, Left$(OLB.List(I), L), 1) > 0 Then
            Exit For
        End If
    Next I

    OLB.TopIndex = I
    OLB.ListIndex = I
End Sub

Sub CtrlTB_KeyPress (OTB As TextBox, OLB As ListBox, KeyAscii As Integer)
    If KeyAscii = 13 Then
        OTB.Text = Left$(OLB.List(OLB.ListIndex), 60)
        CHInChange = False
    Else
        CHInChange = True
    End If
End Sub

Sub CtrlLB_Click (OTB As TextBox, OLB As ListBox)
    If Not CHInChange Then
        OTB.Text = Left$(OLB.List(OLB.ListIndex), 60)
    Else
        CHInChange = False
    End If
End Sub

Sub CtrlLB_MouseDown ()
    CHClickList = True
End Sub

Code:

Sub List1_Click ()
   CtrlLB_Click Text1, List1
End Sub

Sub List1_MouseDown (Button As Integer, Shift As Integer, X As Single, Y As Single)
   CtrlLB_MouseDown
End Sub

Sub Text1_Change ()
    CtrlTB_Change Text1, List1
End Sub

Sub Text1_KeyPress (KeyAscii As Integer)
   CtrlTB_KeyPress Text1, List1, KeyAscii
End Sub

Submitted By: Hernan Martinez Foffani, Buenos Aires - Argentina: email - hernan@condor.satlink.net


Reading INI Files

This is the subroutine I use to read INI files.

Function GetFromINI (SectionHeader$, VarName$, FileName$) As String
   Dim RetStr As String
   RetStr = String(255, Chr(0))
  'Get Requested Information
   GetFromINI = Left(RetStr, GetPrivateProfileString(SectionHeader$, ByVal
   VarName$, "", RetStr, Len(RetStr), FileName$))
End Function

Of course declare the following:

Declare Function GetPrivateProfileString Lib "Kernel" (ByVal lpApplicationName As String, lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Integer, ByVal lpFileName As String) As Integer

So you'd call it using something like:

Result = GetFromINI(Section, Variable name, Filename)

Submitted By: Daniel Bowen, Melbourne, Australia


REREADING WININI
Re-reading The WIN.INI File

To notify other apps on WIN.INI file changes, do:

SendMessage( HWND_BROADCAST, WM_WININICHANGE, 0, 0 )

HWND_BROADCAST = &HFFFF
WM_WININICHANGE = &H001A

Tip By: James Shields


Printer Control

A user can control *everything* (printer, paper size, orientation, print quality, etc.) from within the print setup common dialog.  In fact, here is all the code you need:

Sub FilePrintSetup_Click ()
Dim Msg$

    On Error GoTo FilePrintSetupError

    CMDialog1.Flags = PD_PRINTSETUP     ' Just enable print setup
    CMDialog1.Action = DLG_PRINT        ' Show printer setup dialog box

PrintSetupExit:
    Exit Sub

FilePrintSetupError:
    If Err <> CDERR_CANCEL Then         ' If user didn't select CANCEL
        Beep
        Msg$ = "Error" & Str$(Err) & ": " & Error$
        MsgBox Msg$, MB_ICONEXCLAMATION, "Error"
    End If
    Resume PrintSetupExit

End Sub

The capitalized constants are defined in CONSTANT.TXT.  You do need t to set the CancelError property to True if you want the CDERR_CANCEL error to indicate the user pressed Cancel.  (Even this really isn't needed, though).

Submitted By:  Stephen C. Smith


Starting A Large Application

If you have a large Visual Basic application, it can take a while to load. The user sometimes may think that the application has failed to load when infact it has not yet loaded (or failed to load!).

Therefore, a good idea may be to have a small Visual Basic program that starts another much larger one.

To do this one has to use the SHELL command. But, this in itself is not enough, since the 'loading' form will not display before the shelled app. starts.

This is solved easily by the use of a Timer, which delays the SHELL command, thus allowing the starting form to display - with a suitable message, eg; "Loading Application, please wait..."

1. Create a form (herein called RunForm) with a Timer, a suitable    message, and attributes as below, or as necessary.

ClipControls = 0   'False
   ControlBox = 0   'False
   MaxButton = 0   'False
   MinButton = 0   'False
   Tag = "RunForm"

   Timer Timer1
      Interval = 20  'Alter interval if req.

2. For the timer event, add the following code:

Sub Timer1_Timer ()

   Static NextOne

      If Not NextOne Then
         X = Shell(Filename, 1)
         Unload RunForm
      End If

      NextOne = Not NextOne

   End Sub

Submitted By: Darren Newbold > E-Mail: cdn@dmu.ac.uk


Tool Box

To create a tool box for your application, simply set up a form as a parent and another form as your toolbox/floating dialog whatever. In a suitable declarations section declare the API function as follows:

Declare Function SetParent% Lib "User" (ByVal hWndChild%, ByVal hWndNewParent%)

For a floating toolbox over a parent form, try the following in the routine to show the toolbox:

Sub ShowTbox_Click ()
Dim ret As Integer
If doshow = False Then 'toolbox not visible
   ret = SetParent(tbox.hWnd, parent.hWnd) 'this makes the toolbox float
   tbox.Left = 0 'sets position to top left corner of parent
   tbox.Top = 0
   tbox.Show 'makes toolbox visible
   'try tbox.show 1 i.e. modal to see what happens
   doshow = True
   Showtbox.Caption = "&Hide Toolbox"
      Else
         tbox.Hide
 doshow = False
 Showtbox.Caption = "&Show Toolbox"
End If
End Sub

A couple of small caveats however. If you try tbox.show 1 i.e. modal you'll find the form will show but you will be unable to do anything with it. Secondly you absolutely *MUST* unload the child form i.e. tbox BEFORE unloading the main form otherwise your program will crash.

Submitted By: Matthew Dexter - InterNet:ch01md@surrey.ac.uk


RESTARTINGEXIT WINDOWS
Restarting/Exit Windows

Listed below is a subroutine that will quit windows in three different ways if needed.  Passing 1 to it will reboot the computer, passing 2 will restart Windows, and passing 3 will exit Windows and return to DOS.

Put this on one line in the declarations section:

Declare Function ExitWindows Lib "User" (ByVal RestartCode As Long,ByVal DOSReturnCode As Integer) As Integer

Then add this subroutine to a module:

Sub ExitWin (ByVal nExitOption As Integer) Dim n As Integer

n = MsgBox("Do you really want to exit Windows?", 36, "Exiting")

If n = 7 Then Exit Sub 'User chose NO

Select Case nExitOption
Case 1
n = ExitWindows(67, 0) 'reboot the computer
Case 2
n = ExitWindows(66, 0) 'restart Windows
Case 3
n = ExitWindows(0, 0) 'exit Windows
End Select

End Sub

Tip By: Brian Simper


Using Undo

For most controls, you will have to keep track of changes yourself. 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.

Tip from FAQ Listing


Access

 Printing Blank Fields

 Copying Rows In Access


Printing Blank Fields

I was converting some Visual Basic 1.0 code to Visual Basic 3.0 using the Data Control to replace some database code.  The problem was that when I would print an empty field to the printer (i.e. Printer.Print Data1.Recordset("Field1")) instead of the printer printing nothing it would print '**NULL**'.  This was VERY frustrating.  To get around this problem I wrote the following Sub Routine:

Sub PrinterPrint (something as Variant)
   If IsNull(something) = False Then
      Printer.Print something
        Else
           Printer.Print ""
        End If
End Sub

Then, using the DOS edit program I replaced all occurrences of 'Printer.Print' with 'PrinterPrint'.

Submitted By: Mike Payne


Copying Rows In Access

It is always a good idea to do a MoveLast and a MoveFirst after opening a snapshot or dynaset.  It makes sure the BOF, EOF, and RecordCount properties (mostly RecordCount) are correct.  This fixes it for you.

Suppossedly, RecordCount is set correctly when you first open a snapshot, but the listbox test showed otherwise.
Try it yourself.  Here is the solution code with my debug lines commented out.

Sub CopyRows ()

    Dim i As Integer

    Dim db          As Database
    Dim snap        As Snapshot
    Dim tbl         As Table
    Dim wSQL        As String

    Set db = OpenDatabase("MYDATA.MDB", False, False)
    Set tbl = db.OpenTable("Table1")

' select the rows to be copied into a snapshot object
    'List1.Clear   'Mark's debug code

    wSQL = "Select * from Table1 where Field1 = 'A'"

        'I also changed your sql statement a
        'little, removed characters I don't use, but I don't
        'think it made any difference.

    Set snap = db.CreateSnapshot(wSQL)
    snap.MoveLast   '<===== MoveLast initializes RecordCount of snap
    snap.MoveFirst  '<===== Need to MoveFirst

    'List1.AddItem snap.RecordCount  'Mark's debug code
    'List1.AddItem "**"              'Mark's debug code

' loop through all rows in the snapshot

    Do Until snap.EOF
        tbl.AddNew
        ' copy each field in the snapshot row to the table row
        For i = 0 To snap.Fields.Count - 1
            tbl.Fields(i).Value = snap.Fields(i).Value
        Next i
        ' change the value of the other field
        tbl.Fields("Field2").Value = "B"
        ' insert the new row into the table
        tbl.Update

  ' Ack! Here's the problem.  This "tbl.Update" also is
        ' updating the contents of the snapshot.  Meaning the
        ' "snap.MoveNext" will never get to EOF!

        'List1.AddItem snap.RecordCount     'Mark's debug code
        'List1.Refresh                      'Mark's debug code
        'DoEvents                           'Mark's debug code

        snap.MoveNext
    Loop

' close everything

    snap.Close
    tbl.Close
    db.Close

End Sub

Tip By: Kyle Lutes


Sounds

 How To Play MID, WAV And Other Multimedia Files


HOW TO PLAY MID  WAV AND OTHER MULTIMEDIA FILES
How To Play MID, WAV And 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

Tip From FAQ Listing


Speed And Size Tips

 Avoid Default Variant Data Types

 GetTickCount API Routine Is 85% Faster Than Timer

 Move Method Is 45% Faster Than Setting Left, Top Properties

 Speeding Up Control Property Access


Avoid Default Variant Data Types

In VB2 and later, Variant is the default data type (VB1 was Single). Variants are bigger and slower than other data types. Place DefInt A-Z statement in the general declarations sections of a form to set the default data type to Integer (the fastest data type). In this sample code, without DefInt A-Z, the X variable is a Variant. The second portion of the code shows a 25% speed improvement when using an Integer instead:

'With No DefInt A-Z and no Dim statement.
'the X variable below is Variant
Call MhPrecisionTimerStart
For L& = 1 to 200000
   If X < 32767 Then
      X = X + 1
   Endif
Next
T1& = MhPrecisionTimerEnd$()

'Try the same code again with an Integer
Dim Y As Integer
Call MhPrecisionTimerStart
For L& = 1 to 20000
   If Y < 32767 Then
      Y = Y + 1
   Endif
Next
N2& = MhPrecisionTimerEnd&()
CompareTimes T1&, T2&
'Average results: 25% Faster

CompareTimes Sub

MhPrecisionTimerEnd$ Sub

Tip By: Mark Novisoff - VBITS Conference '94 San Francisco


CompareTimes

Use this sub to compare times:

Sub CompareTimes (Time1$,Time2&)
Difference&=Time1& - Time2&
X$ = "%faster"

If Difference& < 0 Then
   X$ = "%slower"
   Difference& = Abs(Difference&)
Endif

Percent& = (Difference& * 100)/Time1&
MsgBox Str$(Percent&) + X$

End Sub


GETTICKCOUNT API ROUTINE
GetTickCount API Routine Is 85% Faster Than Timer

If applicable to your program, the Windows API routine GetTickCount function is 85% faster than Timer. GetTick Count returns the number of milliseconds since Windows was started, and the "roll-over" point is every 49 days vs. Timer's 24 hours. Sample code:

Declare Function GetTickCount Lib "User"() As Long

Call MhPrecisionTimerStart
For L = 1 To 15000
   X!= Timer
Next
T1&=MhPrecisionTimerEnd()

Call MhPrecisionTimerStart
For L = 1 To 15000
   Y& = GetTickCount()
Next
T2& = MhPrecisionTimerEnd()

CompareTimes T1&, T2&

'Average Result: 85% Faster

A second variation on the above is to see how many times Timer and GetTickCount can excute within the same 10 second loop:

Iterations& = 0
Start1! = Timer

'Loop for 10 seconds
While Timer - Start! < 10
   Iterations& = Iterations& + 1
Wend
'Average Timer iterations: 70,000

Iterations& = 0
Start2& = GetTickCount()

'Loop for 10000 milliseconds (10 seconds)
While GetTickCount() - Start2& < 1000
   Iterations& = Iterations& + 1
Wend
'Average GetTickCount iterations: 650,000

CompareTimes Sub

Tip By: Mark Novisoff - VBITS Conference '94 San Francisco


MOVE METHOD IS 45
Move Method Is 45% Faster Than Setting Left, Top Properties

The Move method is 45% faster than setting a control's Top and Left properties. Plus, it moves the control all at once instead of first to Left, then to Top. Ditto for setting Width and Height. Sample code:

Mono Spaced


Speeding Up Control Property Access

Here's how to 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

And add 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.

Tip From FAQ Listing


Text Boxes

 Disabling The Text Box Beep

 Fixing Ampersand Problem

 Horizontal Scrollbars

 Ignoring Keyboard Input

 Making Text Boxes Read Only

 Masking Input


Fixing Ampersand Problem

If you test the caption or text property of an control using a string the has a "&" in it, VB will think you want the next letter to be a control character. This happens a lot when displaying file names. This is a very annoying problem. Here is how to fix it:

Do something like : Button.Caption=FixAmper("Apples & Oranges & Bannanas")

Function FixAmper(Strng as String) as String
  dim sTemp=as string, n as Integer
  while instr(Strng,"&")
    n=instr(Strng,"&")
    sTemp=sTemp+left$(Strng,n)+"&"
    Strng=mid$(Strng,n+1)
  wend
  sTemp=sTemp+Strng
  return sTemp
End Function

Tip By: Bart Larsen


Horizontal Scrollbars

The reson you put a horzontal scrollbar on a textbox is usually because you want your text to be wider than the textbox control itself. However, if you set the horizontal scrollbar property to true on a multiline textbox, the text will no longer automatically wrap. The way I work around this is to set the with of the rect (EM_SETRECT) to my desired width when the form loads. I don't use the scroll bars property in the textbox. Instead, I place a horizontal scrollbar control below my textbox. I create my own sub that scrolls the text left and right by moving the rect (not changing size). I monitor the KeyUp and MouseUp events using the GetCaretPos function: I call the sub when required or if the scrollbar is changed.

Sub Form1_load (...etc...)
   Dim rtn&
   Dim Posn As Rect
   rtn& = SendMessage(Text1.hWnd, EM_GETRECT, 0, Posn)
   'get original rect
   Posn.right = NewWidth%
   'formatting width you require
   rtn& = SendMessage(Text1.hWnd, EM_SETRECT, 0, Posn)
   'set new rect width
End Sub

Sub ScrollRect (ByVal hWnd%, direction%)
   Dim rtn&
   Dim Posn As Rect
   rtn& = Send Message (hWnd%, EM_GETRECT, 0, Posn)
   'get current rect

   'to move rect left direction% is a negative number
   'to move rect right direction% is a positive number
   Posn.left = Posn.left + direction%
   Posn.right = Posn.right + direction%
   rtn& = SendMessage(hWnd%, EM_SETRECT, 0, Posn)
   'move rect left or right
End Sub

Tip By: Douglas Marquardt


Ignoring Keyboard Input

Here's an easy way to have your application ignore all input from the keyboard except for the Return and Backspace keys. (I wrote this code while creating a timer application that required text boxes that would accept only numbers.)

Sub Text1_KeyPress (KeyAscii As Integer)
   If KeyAscii = 13 Then
      KeyAscii = 0 'Prevents the system from beeping
      'Code or Sub to execute at Return
   End If
   If KeyAscii = 8 Then Exit Sub   'Allow use of backspace key
   If KeyAscii < 48 Or KeyAscii > 57 Then KeyAscii = 0   'Ignore other keys
End Sub

This technique can be used to include ore exclude any characters based on their values in the ASCII character set.

Tip By: Daniel Switkin


Making Text Boxes Read Only

Here is how  to make a textbox read only and how to prevent  the user from changing the text. 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)

Tip By: Pete Jones


Masking Input

For greater control of data input, you might consider using the masked edit control. This control is included with the Visual Basic Professional Edition, along with many other custom controls.

The masked edit control provides a Mask property that lets you specify an input mask of literals and place holders. Literals provide visual cues about the type of data being used - for example, parentheses indicate a telephone area code. Placeholders represent a specific type of required value - for example, the # symbol indicates that you can only enter a decimal value (0-9).

Here's how you might set the Mask property to indicate a telephone number:

Mask 	(###)###-####

At run time, the insertion point moves to the first placeholder:

The underscores in the control represent characters to enter. In this case, you can enter only numeric characters.

Source: Microsoft Developer Network News, September 1993


Windows

 Hiding A DOS Windows/Icon

 Keeping A Window On Top


HIDING A DOS WINDOWSICON
Hiding A DOS Windows/Icon

To hide a DOS Windows or Icon, try using an API called WinExec and use SW_HIDE to hide the dos window.

Declare Function WinExec Lib "Kernel" (ByVal lpCmdLine As String, ByVal nCmdShow As Integer) As Integer

Declare Function GetModuleUsage Lib "Kernel" (ByVal hModule As Integer) As
Integer

Global Const SW_HIDE = 0
Global Const SW_NORMAL = 1
Global Const SW_MAXIMIZE = 3
Global Const SW_MINIMIZE = 6

stat = WinExec("dosprmpt.pif /c  YOUR DOS COMMAND HERE", SW_HIDE)
    While GetModuleUsage(stat) > 0
        tmpstat = DoEvents()
    Wend

You must have the dosprmpt.pif set to run in windowed mode (use the PIF editor). The while loop will wait until the WinExec SHELL is done before exiting.  Leave it out if you don't have to wait for the SHELL to complete before going on with the program.

Tip By: dburke@vax1.umkc.edu


Keeping A Window On Top

To keep a program window on top (always visible) in Visual Basic use a WINAPI function.

Code in Main Module:

Declare Sub SetWindowPos Lib "User" (Byval hWnd as integer, Byval hWndInsertAfter as Integer, Byval X as Integer, Byval Y as Integer, Byval cx
as Integer, Byval cy as Integer, Byval wFlags as Integer)

Code in a Submodule:

SetWindowPos form1.hWnd, -1, 0, 0, 0, 0, &H50 'This will make the window always visible!

Code in Submodule 2:

SetWindowPos form1.hWnd, -2, 0, 0, 0, 0, &H50 'This will put "Always Visible" off!

Submitted By: Henk Hakvoort


WINHELP
Windows 3.1 Help Files

 Adding Sound To A Help File

 Calling WINHELP

 Creating Bullets


Adding Sound To A Help File

To add sound support for .wav files in a windows help file:

In the [CONFIG] section of the project file:

RegisterRoutine("mmsystem","sndPlaySound","Si")

To call the DLL in a macro as a hotspot:

!sndPlaySound("anything.wav",0)

This is a way cool to way to build documents. It *could* be easier though.

Submitted By: Tod Massa - InterNet: MASSATR@SLUVCA.SLU.EDU


Calling WINHELP

Listed below are keywords used by WINHELP and an example on how to use it.

'Help engine declarations.
'Commands to pass WinHelp()
Global Const HELP_CONTEXT = &H1 ' Display topic identified by number in Data
Global Const HELP_QUIT = &H2 ' Terminate help
Global Const HELP_INDEX = &H3 ' Display index
Global Const HELP_HELPONHELP = &H4 ' Display help on using help
Global Const HELP_SETINDEX = &H5 ' Set an alternate Index for help file with more than one index
Global Const HELP_KEY = &H101 ' Display topic for keyword in Data
Global Const HELP_COMMAND = &H102 ' Execute Help macro
Global Const HELP_MULTIKEY = &H201  ' Lookup keyword in alternate table and display topic

Declare Function WinHelp Lib "User" (ByVal hWnd As Integer, ByVal lpHelpFile As String, ByVal wCommand As Integer, dwData As Any) As  Integer

Type MULTIKEYHELP
mkSize As Integer
mkKeylist As String * 1
szKeyphrase As String * 253
End Type

Case 2 ' Help Search Command
HelpCmd = HELP_COMMAND ' Set help command to bring up
search box
curFile = App.HelpFile
curData = "Search()" ' Data is macro to be executed by WinHelp

' To make this work, we need to do two help commands in succession, so we'll do one here and one down below. The commented line 2nd below is the command to be executed to bring up the search dialog.
result = WinHelp(hWnd, curFile, HELP_INDEX, 0&)
result = WinHelp(hWnd, curFile, HELP_COMMAND, ByVal "Search()")

Submitted By: Gary Ferguson - InterNet: GARYFE@MICROSOFT.COM


Creating Bullets

One night I spent at least 2 hours trying to figure out how to create bullet items in a Windows 3.1 Help File. I found some Microsoft documentation which in both places it showed how to do it wrong! Below is the way that I found that works when using the QDHelp shareware program to compile the RTF file:

/para \tx360 \li360 \fi-360
{\f1 \'B7} \tab
Configurable to use many different sizes of diskettes.
Can even use 3 1/2 1.4MB (2.7MB) floppies compressed with Stacker.
/endpara

The '\tx360' RTF command sets the first tab stop to 360. The '\li360' sets the left indent to 360 and the '\fi-360' sets the first line indent to -360 or 0 in this case. The '\f1' sets the font to #1, which should be the Symbol font. The '\'B7' is the hex code for the bullet character in the Symbol font. The '\tab' moves the first line of text to the tab stop created with '\tx360'.

Here is what it looks like:

Submitted By: David McCarter


Other Sources Of Help

 Help Files

 Locations For VBS,DLL and Modules Files

 Microsoft "Suggestion Box"

 User Groups

 Visual Basic/Access Books


Help Files

Visual Basic for Windows: Tips & Techniques

This very informative Windows Help File is released monthly (I think) and contains all of Knowledge Base articles.

This is a list of the main topics:  VB Programming Using Standard Controls,  VB Programming Using Custom & Third-Party Controls,  Optimization, Memory Management, & General VB Programming, Advanced VB Programming -- Networks, APIs, DLLs, Graphics,  Data Access & VB Database Programming, VB Design Environment, Running VB Applications, General VB References & Documentation Corrections, VB Setup, Installation, CDK, Help Compiler, DDE, & OLE

You can get the latest files off the Microsoft BBS or thru InterNet. The compressed file name is VBKB.EXE. This file comes with no search capibilities. If you want to search for topics or text, download VBKB_FT.EXE. Even though this file is much larger than the other, the search function in very valuable.

Sample

Visual Basic for Windows: Bugs, Fixes, & Updates

Instead of beating your head against the wall wondering why something won't work the way you think it should, first refer to this help file. I contains a list of unfixed bugs, fixed bugs (I guess that Microsoft knows about) and updates that are avaliable.

This is a list of the main topics:  Unfixed Bugs, Fixed Bugs, Updates Available.

You can get the latest file off the Microsoft BBS or thru InterNet. This help file comes with VBKB_FT.EXE.

Sample

Microsoft Access Knowledge Base

This help system (with full text search) includes articles that relate to the Microsoft Access  for Windows.  These articles were devloped by Microsoft's Product Support Engineers. This is a list of the main topics: Forms (Specific), Forms/Reports (Common), General, Import/Export/Attach,Interoperability,
Macros, Non-Product/Non-Technical, Windows Environment, Printing
Printing: General Win Troubleshooting, Printing: Specific Win3.1 Drivers
Programming, Queries, Reports (Specific), Security, Setup, Tables
Windows Issue,INF: Access Basic and Macros Questions & Answers
INF: Access Distribution Kit Questions & Answers, INF: Database Structure Questions & Answers, INF: Forms Questions & Answers
INF: How to Find Which Groups a User Belongs, INF: Interoperability Questions & Answers, INF: Querying Questions & Answers
INF: Reports Questions & Answers, INF: Setup Questions & Answers

You can get the latest file off the Microsoft BBS or thru InterNet.

Sample


VBKBBMP


VBKBBUGS


ACCESSKBBMP


LOCATIONS FOR VBS DLL AND MODULES FILES
Locations For VBX, DLL and Modules Files

InterNet

ftp.cica.indiana.edu:/pub/pc/win3/programr/vbasic - Best/largest source for Visual Basic files, utilities, example  programs, VBXs, etc.

ftp.microsoft.com - Microsoft's anonymous ftp site.  There is a lot on this site so look around.  Here are some of the more useful directories:

/Softlib/MSLFILES - Get the Knowledge Base for VB here!  VBKB.EXE (929K) is the regular KB in windows help format. VBKB_FT.EXE (2,563K)is the same as VBKB.EXE but with text searching added.  Lot's of other good
files in this directory.

/MSDN - Contains LOTS of Windows programming files and examples!  Get the index file MSDN-IDX.ZIP for a description of the files in this directory.  Suggestion: search the index file for the text "Visual Basic".
/MSDN/VBTECH - VB specific files.

/DEVTOOLS/LANG/VB/PUBLIC - Misc. VB files and updates.

On-Line Services

Compuserve - Compuserve does have a fairly active basic forum. To access this forum, type GO MSBASIC. Microsoft employees have been known to frequent this forum. May be useful for those last ditch pleas for some useful tidbit of information. Some Useful files in the MSBASIC forum:
- VBBK05.ZIP:  List of books/mags dealing with VB. - MLIST4.ZIP:  Multi-column listbox. No 64K limit.

America On-Line - America On-Line has a good selection of VB files and an active message area for discussing Visual Basic.


MS SUG BOX
Microsoft "Suggestion Box"

Microsoft has set up a "suggestions box" account on the Internet. Send suggestions for any Microsoft product to: mswish@microsoft.com.

On the Subject line, please try to include the following information: product name - product version - platform - suggestion summary.

To: mswish@microsoft.com.
Subject: Visual Basic - 3.0 - Windows - Support custom cursors It would be really cool if Visual Basic could load and display arbitrary .CUR files.
--
vbuser@somewhere.edu

You can use this account to make suggestions for any Microsoft product.  They will be automatically entered in a database and brought to the attention of the R&D teams for that product.  Of course, we can't guarantee that your suggestion will appear in the next version, but it will be considered and prioritized in conjunction with all the other
suggestions.  Additional information describing how you are using the product (and thus how this suggestion would help you) is useful in this regard.

Please don't use this alias to report bugs; it's not set up to handle bug reports.  We may set up such an account in the future.  For now, the best way to report bugs is via Compuserve or a phone call to Product Support (who may be able to provide you with a workaround if it is a known bug).


USER GROUPS INTERNET
User Groups - InterNet

VISBAS-L

This Visual Basic user forum is actually a server located at the Texas A&M University. Users send questions to this server and the question get broadcasted to over 600 subscribers (some include employees at Microsoft). From the beginner to advanced programmer, this list is GREAT place to find good help.

How To Subscribe:

Send a e-mail message to the following address:

LISTSERV@tamvm1.tamu.edu

In the body of the message type:

SUB VISBAS-L <your name>

Leave out signatures and the subject. This will just cause error messages to be sent back to you from the server.

 VISBAS-L FAQ


VISBASL FAQ
VISBAS-L FAQ

These are some of the Very Frequently Asked Questions for the VISBAS-L list.  This list is devoted to the discussion
of Microsoft Visual Basic and related topics.

LISTSERV fundamentals

How do I get off of this list?

Easy.  Send the mail command UNSUB VISBAS-L to LISTSERV@tamvm1.tamu.edu (this address is a program).

What if this doesn't work?

Networks being dynamic beasts, your e-mail address that is given in your mail message could have changed since you first subscribed.  You may not even be aware of this change since many of us are on mail forwarding systems.

In this case, just send a note to owner-visbas-l@tamvm1.tamu.edu (this address is a human) requesting that you be removed.

How do I access the old messages?

If you are getting this advanced, you should probably send the mail message:

HELP

To LISTSERV@tamvm1.tamu.edu.

To get a list of the files available, send the command INDEX VISBAS-L.  To retrieve one of the files, send the command GET VISBAS-L LOGyymm, where yy is the year and mm is the month.

Did my mail message get out?

By default, all new subscriptions are set up so that they do not receive a copy of their own mail.  However, you will
receive an acknowledgement from the LISTSERV system when your mail is distributed.  There are two options available to find out whether your mail was sent.

Sending the command REPRO will send a copy of your message to you.  NOREPRO will turn this option back off.

Sending the command ACK will tell LISTSERV to send an acknowledgement to you when it distributes your mail.  NOACK will turn this option off.

How do I get the full FAQ?

Once it is ready, I will make it available on tamvm1.tamu.edu and you can retrieve a copy by send a LISTSERV GET command.

Where can I get free support?

Here.  This is why I set up this list.  Microsoft provides several support services, but all of the cost money.  At present, Microsoft does not provide free support for Visual Basic.

Unfortunately, this seems to be an industry trend.  I have read articles about other companies that are cutting back on their free support personnel, or even not answering the free support lines.

Are there any rules about messages that can be posted?

Yes.  All things in moderation.

However, there are a few things that really get on the list maintainers bad side.

1	Disrespect for other subscribers.  If they are jerks, the rest of us can figure it out for ourselves.

2	Chain letters (MAKE MONEY FAST).

3	UUENCODEd binaries.


VISUAL BASIC ACCESS BOOKS
Visual Basic/Access Books

Visual Basic For Windows

Fun programming with VB, several authors, ISBN 1-56529-106-9. This uses a half-dozen or so projects to illustrate how various programmers designed and built apps using VB.

Learn Programming and Visual Basic with John Socha, John Socha:  Sybex, 1992.  ISBN 0-7821-1057-6. Includes disk.  A useful introduction for absolute beginner programmers thru intermediate.

The Visual Guide to Visual Basic for Windows, by Richard Mansfield, published by Ventura Press. This is a encyclopedia of the language itself. It supposes that you DO know how to program so basically (if you pardon the
pun) it's a guide to VB's slang. I use this for referencing the grammar when i get a bug.

The Waite Group's VB How-To, several authors, ISBN 1-878739-09-3. This is the ISBN number for version 1 - I
think it's been updated by now. Lots of examples to demonstrate each point. This is a close second.

Visual Basic How-To, Robert Arnson, Daniel Rosen, Mitch Waite &  Jonathon Zuck: The Waite Group, 1992.  ISBN 1-878739-09-3.  Includes  disk.  Many practical examples & some sample custom controls.Introduces & expands on the use of API's.  An excellent book suitable for Beginners thru Advanced - one of my most-often-used references.

Visual Basic Programmers guide to the Windows API, by Daniel Appleman. ISBN1-56276-073-4. If you only want to get one book on VB, this is the one. It covers the ground from simple to advanced programming very  well.

Visual Basic Utilities, by Paul Bonner, ISBN 1-56276-106-4. This has some excellent learning stuff in it and also some advanced stuff, including how to write your own DLLs (!) using GFA-BASIC.

Windows 3.1 programming for mere mortals, by Woody Leonhard, ISBN 0-201-60832-4. This covers VB and WordBasic. Some very neat examples.

Visual Basic For DOS

Access

Windows Help Files


Programmer Tools

 DLL Files

 Forms/Modules

 Programs

 VBX Files

This purpose of this section is to let programmer know about Freeware VBX & DLL files and programs to make life easier for programmers. Developers of these types of programs are welcome to submit their program to us to be included with this help file.

To find out about shareware VBX's, Dll's and programs, please download the latest version of The Shareware/Freeware Report. Published by DPM Computer Solutions.


DLL Files

CTLWhWnd.DLL

One function, ControlhWnd, which returns the hWnd for a given control.

Written By: Jonathan Zuck
File Name: vbhwnd.zip

ENTASK.DLL

Intercepts "End Task" from the Task Manager.

Written By: Jeff Simms
File Name: entask.zip

GTICON.DLL

Assigns and retrieves the DragIcon property of controls.

Written By: George R. Torralba
File Name: gticon.zip

INPOUT.DLL

An INP and OUT replacement, written in assembler and used like the
QuickBasic routines.  Includes source.  (For some reason Mr. Munro saw
fit to include Software Assist's SCFILE package -- the dll is actually
very small.)

Written By: Jay Munro
File Name: inpout.zip

QCARD.DLL

Deck of cards with card support functions.  Can work with 2 decks at a
time, no jokers.

Written By: Stephen Murphy
File Name: qcard.zip

MouseWatch

MWATCH.DLL dynamically tracks mouse position, emitting _KeyDown events to the form.  Good for dynamic hinting, a la Word Perfect.

Written By: User Friendly, Inc.
File Name: mwatch.zip

spSound

WINSOUND.DLL provides low-level port-based sound routines.

Written By:  Alfred J. Giordano
File Name: spsoun.zip

VBCARDS.DLL

Provides a bitmap collection of cards, including a joker, and basic card API.

Written By: Richard R. Sands
File Name: vbcards.zip

VBPoint

VBPOINT.DLL is two routines: convert long pointers (LP) to VB strings, and copy strings to another address (another LP).

Written By: Jonathan Zuck
File Name: vbptr.zip


FORMAS AND MODULES
Forms And Modules

Modules

Common01.BAS Version 1.0

This module file contains common subs and functions that are used with most programs that I write. Instead of writing the same code over and over, just attach this module to your project.

This is a summary of whats in Common01.BAS:

•	AppRunning: Checks to see if the current application is already running. To use just call the sub. If the application is already running, it will end the current application.

•	CenterForm: This code will center a form in the center of the screen.

•	CenterMDIChild: Centers a child form within a parent MDI form.

•	CutCopyPaste: This procedure puts all the cut,copy paste commands in one place.

•	GetAppPath: Returns the application path with a trailing \.

•	ReadINI: Returns a string from an INI file.

•	SelectText: Selects all the text in a text box.

•	WriteINI: Writes a string to an INI file.

Written By: David McCarter [Internet - DPMCS@HIGH-COUNTRY.COM | CIS - 74227,1557]
File Name: COMM0110.ZIP
Cost: $0

This file will be included with the VB Tips & Tricks Help File or can be found on BBS systems as COMM01xx.ZIP where xx is the version number.


TOOLPROGRAMS
Programmers Tool Programs

MessageBox Value

If you are like me, I can never remember all the different Message Box values available for use in Visual Basic for Windows. When ever I create a new message box, I always have to consult the Visual Basic help file.  MessageBox Value takes care of this problem!

With MessageBox Value, you choose what buttons you want to use, which icon, which button is the default, task or system modal and MessageBox Value displays the Message Box value to use. You can even copy the value to the clipboard and paste it into Visual Basic.

This program is great for (as the developer puts it), "people with small memories",

MessageBox Value Is Developed By:Gavin Lazarow File Name: MSGVAL.ZIP


VBX Files

Four Controls

Four graphic controls:  vmeter.vbx and hmeter.vbx are "flooding" status
gauge controls; spin.vbx (!) is a spin tool.  The best of the lot seems to be 3dlabel.vbx, which is actually a button which holds states like a
toolbar button.  No documentation.

Written By: Jeng Long Jiang
File Name: vb4ctrls.zip

Message Blaster

MSGBLAST.VBX  provides a floating palette, complete with tiny title bar, which you can use in conjunction with an MDI form.  Message notification is rather crude and hacky.

Written By: Ed Staffin
File Name: tbox100.zip

OpenDlg

OPENDLG.VBX does the same thing as cmdialog.vbx.

Written By: Zane Thomas
File Name: opendl.zip

ToolButton

TOOLBUTN.VBX is a full-feature toolbar buttons, with up to 6 states (for attributes).  Use your own image and break it into cells of graphic buttons, or use the suite of standard buttons.  Also includes ContextHelp control (same vbx) to assist with help management.

Written By: Brett Foster
File Name: vbtool20.zip

WinSock

VBWSK.VBX provides access to Windows Sockets API.

Written By: Brian Syme
File Name: vbwsk01a.zip


VB Program Updates

Updated On: 3/23/94

Visual Basic/Help Compilers

BTR110.EXE        71581   09-03-93    Updated Btrieve ISAM Driver Shipped W/Access
DATAINDX.EXE      36588   03-07-94    VB Data Access Guide Index
DATAMGR.EXE       38666   03-07-94    VB Data Manager Source Code
GENERIC.EXE       29705   07-27-93    CDK Sample left out of VBWIN 3.0
GRID.EXE          41357   07-27-93    Updated GRID.VBX, version 3.00.0538
HC505.EXE        228685   11-15-93    New Help Compiler for Use with WinWord 6.0 RTF File Format
HEALTH.EXE       250522   07-28-93    VBWIN 3.0 Pen Windows Sample Application
INSURE2.EXE      105250   07-28-93    VBWIN 3.0 Pen Windows Sample Application
LOANAPP.EXE       94661   07-28-93    VBWIN 3.0 Pen Windows Sample Application
MSAJT110.EXE     363656   10-20-93    Updated Access Engine Library, v 1.10.0001
MSCOMM.EXE        28643   03-08-94    Updated MSCOMM.VBX Control for VB
ORA110.EXE       122816   09-02-93    Updated Oracle ODBC Driver Shipped W/ Access
RECEIPT.EXE      135573   07-28-93    VBWIN 3.0 Pen Winodws Sample Application
SETUPK.EXE        76487   03-07-94    New VB Setup Toolkit & Setup Wizard
SQLUPDT.EXE      636209   09-13-93    Updated SQL & Oracle drivers
VBCOMDEM.EXE      30099   11-03-93    SIMPCOMM: Communications Demo Using Windows API's
VBGRID.EXE        41336   03-07-94    Updated GRID.VBX Control for VB
VBKB.EXE        1275840   03-01-94    Visual Basic Knowledge Base in help file format
VBKB_FT.EXE     3508893   03-01-94    VB KB Help Files w/ Full-Text Search
VBPRINT.EXE       95978   09-13-93    Sample Application and DLL that Demonstrate Advanced Printing in VB.
VBRUN100.EXE     172991   07-27-93    VBRUN100.DLL File
VBRUN200.EXE     220504   07-27-93    VBRUN200.DLL File
VBRUN300.EXE     246805   03-07-94    Updated VBRUN300.DLL File
XBS110.EXE       153916   07-27-93    Updated XBase driver, version 1.00.0002

Access

ACCBUG.TXT        29225    3-15-93    Bug list for MS Access. Contains known bugs and workarounds.
ACCFIX.TXT        34593   06-30-93    Known bugs that have been fixed in Access1.1
DDESRV.TXT        14341   07-08-93    Using Microsoft Access as a DDE Server
Q88164.TXT         6110   11-01-92    Intro to Windows Programming for MS-DOS Programmer
Q88173.TXT         2421   11-01-92    ODBC Setup for Access and SQL Server
Q88175.TXT         6026   11-01-92    Creating, Debugging, and Using an Access Library
Q88635.TXT         3268   07-28-93    How to Force a Cascading Delete
Q88653.TXT         4882   11-01-92    How to List the Related Tables in a Database
Q88655.TXT         7597   11-01-92    How Access Uses SQL Server Connections
Q88658.TXT         2622   11-01-92    Using TransferDatabase Macro to Attach to SQL Server Data
Q88907.TXT         4399   11-01-92    How to Modify the Toolbar in MS Access
Q88914.TXT         1023   11-01-92    Running MS-DOS SHARE with Windows for Workgroups
Q88940.TXT         6062   11-01-92    How to Dim (Gray) Menu Items with Access Basic
Q88999.TXT         1749   11-01-92    When to use Macros and When to use Access Basic
Q89590.TXT         1394   07-28-93    Making ENTER Add Lines in a Text Box
Q89594.TXT         3213   11-01-92    How to Display Immediate Window Without Module Window
WX0635.TXT        10260   09-10-93    Database Structure Questions & Answers
WX0636.TXT         5474   09-11-93    Access Basic and Macros Questions & Answers
WX0637.TXT         8147   09-10-93    Forms Questions & Answers
WX0638.TXT         8320   07-19-93    Nontechnical and Marketing Q& A
WX0639.TXT         9330   09-10-93    Querying Questions & Answers
WX0640.TXT         4661   09-11-93    Reports Questions & Answers
WX0811.TXT        11179   09-09-93    Interoperability with Other Applications Q&A
WX0812.TXT        12521   09-10-93    Setup Questions & Answers
WX0838.TXT         6423   06-20-93    Microsoft Access Questions & Answers
WX0867.TXT         9219   09-09-93    Access Distribution Kit Questions & Answers
4MEG.EXE          14402    1-08-93    performance enhancement suggestions for running Microsoft Access on a computer with 4 megs. of memory.
ACC-IN.EXE      1823586   02-09-94    Access KB Help File (2)
ACC-KB.EXE      1392723   02-09-94    Access (KB) Help File (1)
ACCADD.EXE        31601   02-12-93    Additional information on reported problems.
ACCSRV.EXE        23089    2-12-93    WinWord Template using Access as a DDE Server
BTR110.EXE        71832   03-07-94    Updated Btrieve Driver BTRV110.DLL
CHOOSE.EXE       130760   05-25-93    This document addresses the breadth of database users and the unique challenges each group may face. It goes on to provide Microsoft's answer to these challenges in terms of appropriate database tools.
DDL100.EXE        45060   06-09-93    DLL to create & manipulate objects in AB. For Access V1.0 (Not Supported by PSS)
DDL110.EXE        38979   06-18-93    DLL to create & manipulate objects in AB. For Access V1.1 (Not Supported by PSS)
ERLIST.EXE        26417    2-12-93    List of Access Basic error messages
MSAJT110.EXE     363677   03-07-94    Updated Microsoft Access Engine .DLL
ORA110.EXE       124155   03-07-94    SQORA.DLL Oracle ODBC Driver
OUTPUT.EXE       206085    2-12-93    Saving report output to a file
PACKPT.EXE        50319   07-08-93    Updated version of Microsoft Object Packager
PRMPT.EXE        183011   05-12-93    Prompt.mdb sample-"Running Microsoft Access"
SECURE.EXE        37316   10-07-93    Additional Microsoft Access Security document
SECWIZ.EXE       211276   10-07-93    This wizard makes implementing database security and easy task with fixes for SYBASE SQL Server 4.8 and 4.9
SPT100.EXE        73938   06-09-93    SQL Pass-through DLL for Access 1.0
SPT110.EXE        69878   06-18-93    SQL Pass-through DLL for Access 1.1
SQL100.EXE        43338   06-14-93    INSTCAT.48 and INSTCAT.SQL Catalog Stored Procedure scripts v 1.0 for ODBC
SQL110.EXE        29171   06-14-93    INSTCAT.SQL Catalog Stored Procedure script for Access 1.1 and SQL.
TIMER.EXE         31404    2-12-93    TIMERDLL.DLL for creating a background timer
UTIL.EXE          53641   07-07-93    MS Access v1.1 UTILITY.MDA file
WX0964.EXE       211148   12-08-93    SecurityWizard and White Paper
XBS110.EXE       153942   03-07-94    New XBase IISAM Driver XBS110.DLL

All these file are available from the MicroSoft BBS: 1-206-936-6735


HISTORY
Release History

Version 1.5 Released on: 3/30/94 - File Name: VBTIPS15.ZIP (85 Topics)

Version 1.4 Released on: 2/15/94 - File Name: VBTIPS14.ZIP (68 Topics)

Version 1.3 Released on: 1/3/94 - File Name: VBTIPS13.ZIP (49 Topics)

Version 1.2 Released on: 11/29/93 - File Name: VBTIPS12.ZIP

Version 1.1 Released on: 10/1/93 - File Name: VBTIPS11.ZIP

Version 1.0 Released on: 9/9/93 - File Name: VBTIPS10.ZIP


ABOUT DEVELOPER
About The Developer

The Visual Basic Tips & Tricks Help File Is Compiled By: David McCarter

I can be reached at:
DPM Computer Solutions
8430-D Summerdale Road
San Diego, CA 92126-5415
USA.

InterNet-DPMCS@HIGH-COUNTRY.COM
Compuserve: 74227,1557

All brand names and product names used in this help file are trademarks, registered trademarks or trade names of their respective holders.

If I (or someone that I know) has tested the submitted code to make sure that it works, then we tell you by adding a graphic like the one below for the Visual Basic version it was tested.

Disclaimer: I will try to make sure that all the coding in this help file is correct and works! I am not responsible for any damage that might happen to your computer or programs. REMEMBER...save your work before trying any coding listed here.

This help file is freeware, but if you would like to make a donation, any amout will be accepted. Also, 10% of all donations will go to chairity, the rest will go to purchase programs (we will try to buy only shareware) to keep this project going. Please make checks payable to: David McCarter.

This Help File was written with the following shareware programs:

Visual Help V2.0j - Developed By: WinWare, P.O. Box 2923, Mission Viejo CA 92690. CompuServe Address: 70272,1656

A Special Thanks To The Following People The Either Knowingly Or Un-Knowingly Helped With This Project:

•	Everyone that submitted a tip or trick!! Without you, this project would have not gotten very far.

•	Rick Huff - For his VB/Win Frequently Asked Questions listing.


ABOUT VBTT
About Visual Basic Tips & Tricks

The future of this project rests on your shoulders... I wanted to develop this help file to provide some sort of centralized forum for users to share VB Tips & Tricks.  I want to pool information from many different sources into one help file. As you might already know, Microsoft books and help files are (in my opinion) not written very well. They do not contain much help that a normal programmer might want. Some of their information is even printed wrong! So where does one turn? To off-the-shelf books, user forums, magazine articles and the like. Try to keep all that organized to retrieve the information you need quickly. Not so easy, is it?

I want this help file to provide HELP with small VB Tips & Tricks. Undocumented  ones, work arounds, easier way to do things etc... But I need your help!. I need your input!

Please submit your VB Tips & Tricks for others to use. Since this help file is freeware, the only thing you will receive is your name embedded in this help file forever.

How to submit your VB Tips & Tricks:

Write down your tip or trick explaining exactly what is it is. Provide any coding (make sure it works) and graphics if you want. Text must be is ASCII format and graphics must be 16 color in a BMP format.

Send your tip or trick to:

DPM Computer Solutions
c/o VB Tips & Tricks
8430-D Summerdale Road
San Diego, CA 92126-5415 USA

Please submit them on a 3 1/2 disk using a floppy disk mailer.

You can also save some $$$ and electronically send it to me at:

InterNet - DPMCS@HIGH-COUNTRY.COM
CompuServe - 74227,1557
Send any files using uuencoding.

How To Receive Updates:

The easiest way is to receive them electronically through e-mail. To get on the e-mailing list just submit a VB Tip or Trick! Use my e-mail address above and send me your name, e-mail address, coding preference (uuencode or binhex) and file size limitations your system might have long with your VB Tip or Trick. This will also be posted on many InterNet systems and BBS systems to be listed below.

Where To Find New Issues:

BBS Systems:

The Centre (New Zealand): (09) 443-7679 (V22bis, V32, V42bis, MNP5)

Windows-R-Us (San Diego, CA): (619) 944-7368 2400/ 1200/ 300. (619) 944-8583 USR 14.4.

HighCountry East (San Diego, CA): 619-789-4391  USR Dual Standard V32bis,   619-788-0831  Compucom. San Diego callers use 619-440-0231

InterNet FTP Sites:

CICA: ftp.cica.indiana.edu [129.79.20.17]

GARBO: garbo.uwasa.fi

On-Line Services:

CompuServe: File name= VBTIPS.ZIP


GLOSSARY
Glossary Of Topics

#

.WAV

A

About The Developer

About Visual Basic Tips & Tricks

Adding Sound To A Help File

AddItem

Ampersand

App.EXEName

App.PrevInstance

Automatic Selection Of Text

Avoid Default Variant Data Types

B

Books

Bullets in a Help File

Button

C

Calling WINHELP

Change

Changing The Control Box Menu

Chr

CLIP

Clipboard.SetText

CMDialog

Copying Data From A Grid

Copying Rows In Access

Creating Bullets

Creating Global Variables

Creating Screen Savers

D

datagrid.Fixedcols

datagrid.FixedRows

Declare Function

Declare Function

Declare

Declare

Declare

Decoding Binary CGM Graphics

Detecting Previous Instances Of A Program

Developer Address

Developer InterNet Address

Dialing A Phone

DIR$

Disclaimer

Disks & Files

E

Easy Help

ExitWindows

F

Finding Directores in VB DOS

Finding Hard/Floppy/Removable Drives

Fixing Ampersand Problem

Format

Formatting A Foppy Disk

Forms And Modules

G

GETDRIVETYPE

GetKeyState

GetTickCount API Routine Is 85% Faster Than Timer

GetTickCount

GotFocus

H

Help Menu On Right Side Of Menu Bar

Hiding A DOS Windows/Icon

Horizontal Scrollbars

How To Find Program Manager Groups

How to submit  your VB Tips & Tricks

HScroll

HWND_BROADCAST

I

Ignoring Keyboard Input

Image Control As A Button

Imitating A Combo Box

InterNet

IsNull

K

Keeping A Windows On Top

KeyAscii

KeyPress

L

Locations For VBS

M

Making Text Boxes Read Only

Masking Input

Max

Microsoft "Suggestion Box"

MID

Min

Mouse Button Up Or Down Status

MouseDown

MouseMove

MousePointer

MouseUp

Move Method Is 45% Faster Than Setting Left

Move Method

MSCOMM VBX

Multimedia

N

Now

O

Other Sources Of Help

P

Picture

Pop-up Menus

Portable Forms

Printer Control

Printer.Print

Printing Blank Fields

Program Manager Groups

Programmer Tools

R

Re-reading The WIN.INI File

Reading INI Files

RegisterRoutine

Release Histroy

Restarting/Exit Windows

S

Screen Savers

Searching A List Box

Searching A List Or Combo Box

SelLength

SelStart

SendMessage

SendMessage

Setting TabIndex At Design Time

Setting The "TabIndex" Property

Setting Video Resolution For Multiple Forms

SetWindowPos

Sounds

Speeding Up Control Property Access

Starting A Large Application

T

Tab Stops In A List Box

TabIndex

TabIndex

Text Boxes

TimeVal

Tool Box

U

Undo

Updates

User Groups - InterNet

Using Controls Indirectly To Change Data

Using Undo

V

VISBAS-L FAQ

VISBAS-L

Visual Basic for Windows: Bugs

Visual Basic for Windows: Tips & Techniques

Visual Basic Tips & Tricks Updates

Visual Basic Tips & Tricks

Visual Basic/Access Books

VK_ESCAPE

VK_LBUTTON

VK_MBUTTON

VK_RBUTTON

VK_TAB

W

WAV

WAV

Width

WINHELP

WM_WININICHANGE


FAQWIN
Frequently Asked Questions

 Automatic Selection Of Text

 Finding Drive Types

 Restarting/Exiting Windows From VB


FORM_LOAD EVENTS
Form_Load() Events

 Detecting Prevous Instances Of A Program


Setting TabIndex At Design Time

One of the most enjoyable features of the Visual Basic environment is its form-design facilities. Just plop some controls of a form, drag them around until you get the most appealing layout, and your done. Except, of course, you have to go back and set the TabIndex property for all the controls to match your final design.

My method used to be to click the first control and set its TabIndex to 0 (zero), click the next control and set its TabIndex to 1, and so on - until I discovered this trick: Start with the last control (usually the bottom right) and work your way backwards (left and to the top). Each time you click a control, set its TabIndex property to 0. When you reach the first control, all TabIndex properties will be in the correct order.

This method works because VB resequences the TabIndex property for all controls on the form when you change the property to a value that already exists on another control. With the properties windows in VB 3.0, the TabIndex property will keep the focus even as you click controls. Just keep one finger on the 0 button and another on the mouse. Then click, press 0, click, press 0, click, press 0, and so on.

Tip By: Kyle Lutes