Visual Studio Web Site Visual C++ Web Site Visual FoxPro Web Site Visual InterDev Web Site Visual J++ Web Site
Microsoft HomeProductsSearchSupportShopWrite Us Microsoft Home
 
 Visual Basic Home
 Product Information
 Technical Resources
 Samples & Downloads
 Developer Community
 News & Reviews
 Registration
 Site Map
 Search Developer Sites:
 
 

Dynamic Duo: SQL 7 and Visual Studio 6.0. MSDN has technical articles to help you learn more about how these two products work seemlessly together.

Tips & Tricks

Past Tips of the Week


Ziff-Davis logoThe Visual Basic Tip of the Week is provided by ZD Journals, publishers of Inside Visual Basic, a monthly publication for Visual Basic users. Sign up for your free preview Issue today. Find out how to receive the Tip of the Week in e-mail!

You can quickly navigate to past tips using the alphabetical topic list below. The tips are also organized chronologically further down on this page.

Add Dithered Backgrounds to your VB Forms
Confirm Screen Resolution
Creating a incrementing number box
Creating a new context menu in editable controls
Creating Win32 region windows

Dragging items from a list to another one
Finding the last day of the month
GETting the contents of a file
Importing Registry settings
Increase Your RAD-ness by Creating Your Own VB5 Templates
Increment and decrement dates with the [+] and [-] keys
Labeling your forms

Manipulate your controls from the keyboard
Measuring a text extent
Opening a browser to your homepage
Quick Custom Dialogs for DBGrid Cells
Quick Text Select On GotFocus

Showing long ListBox entries as a ToolTip
Simple file checking from anywhere
Take Advantage of Built-in OLE Drag and Drop
Use FileDSNs to ease ODBC Installs
Use FreeFile to Prevent File Open Conflicts
Use ParamArray to Accept an Arbitrary Number of Parameters
Using the Alias Option to Prevent API Crashes


November 09, 1998
Finding the last day of the month
In many industries (particularly in the insurance industry), it's important to know the last day of the month. To find the last day of a given month, add a text box and a command button to a form. Enter the following code in the command button:

Dim TEMP2 As Date
Dim nLastDay As Integer
TEMP2 = InputBox$("Please Enter A Date", "LastDay")
nLastDay = DatePart("d", DateAdd("M", 1, TEMP2 - DatePart("d", TEMP2)))
Text1.Text = nLastDay

When you run the application and click the button, you'll be prompted for a date. Then, the program will display the last day of that month of any year.

Top of Page


August 31, 1998
GETting the contents of a file
submitted by Pritesh
TransCapacity LP; spritesh@hotmail.com

To read a complete file in VB, the normal procedure is to read the contents of the file line by line and accumulate it into a string. Instead, you can use the GET function to read the file with a single call. Doing so simplifies and speeds up the process of reading a file.

You can use the following function:

    Dim Handle As Integer
    Dim FileString As String
    Handle = FreeFile
    Open "C:\TEMP\TST.TXT" For Binary As #Handle
    FileString = Space(FileLen("C:\TEMP\TST.TXT"))
    Get #Handle, ,FileString  
    Close #Handle
This code involves a single call to return the contents of the file.

Top of Page


August 24, 1998
Help with Shell
submitted by Brad Gile
bgile@amfam.com

Suppose you have a DOS program, Dosapp.exe. This program produces an output file that will subsequently be processed, and you want to do this N times. The code might look like this:

    for Trial = 1 to N
    x=shell("Dosapp.exe",vbHide)
    Process the output 
    Next Trial
The problem is, the code after the Shell may be executed before the Shelled Dosapp.exe has created the file. There are complicated ways of solving this, including API calls, but here's a simple solution: the FileLen function. If the file to be processed is x$, you can just insert a few lines of code:

    for Trial = 1 to N
    Open x$ for output as 1
    Close 1
    ' This sets file length equal to zero
    x=shell("Dosapp.exe",vbHide)
    Do While FileLen(x$) = 0
    DoEvents
    ' Halt further execution until x$ is created and closed
    Loop

    ' Process the output to add to a new file
    Next Trial
You may want to do other things such as using Timer to prevent an infinite Do Loop, but this is the main idea. FileLen() works because even if x$ is open and has data in it, FileLen(x$) = 0. Thus you're assured that the process code won't execute until x$ is fully created.

Top of Page


August 17, 1998
Watch your window state
submitted by Rick Michelhaugh
3m8@ornl.gov

My application saves the window location and size, so it will open the next time at the same screen location. This technique is great and pleases customers. But after several months, the program wouldn't start right -- it would die with an 'overflow error'. We tried every possible test, and could only determined that something in the INI file had become corrupted. Finally, we found that the window's Top, Left, Width, and Height values were incorrect. When the program started and read these wrong numbers, the 'overflow error' was the result.

As it turned out, the numbers were being thrown off when the user minimized the window and exited Windows with it minimized. As the program closes, it saves the position values of the minimized state -- which messes up the values. To fix the problem, we added some code to check the windowstate. If it's vbMinimized, the program skips the code that saves the window position.

Top of Page


August 10, 1998
Writing to and reading from INI files
submitted by David Dommisse
Dommisse@hotmail.com

Here's an example that will write to and read from a INI file. You can use a file named TEST.INI that looks like this:

  [MyApp]
  Key1= TestString
Put the following code in the declaration section of a module:

Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" _
  (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, _
  ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" _
  (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, _
  ByVal lpFileName As String) As Long


Now, use the following code to read from the INI file:

  Dim iret As Long                'return code
  Dim retStr As String * 30 'return string -> answer is in it
  iret = GetPrivateProfileString("MyApp", "Key1", "Default", retStr, 30, "c:\test.ini")
  txtResult = "Return Code: " & iret & vbCrLf & "Return String: " & retStr


The key's value will be in retStr = TestString. The following code will write to the INI file:

  Dim iret As Long          'return code
  iret = WritePrivateProfileString("MyApp", "Key2", "My Test", "c:\test.ini")
  txtResult = "Return Code: " & iret


After you write to the INI file, its contents will look like this:

  [MyApp]
  Key1=TestString
  Key2=My Test

Top of Page


August 3, 1998
Tracking down Resume Next
submitted by Bill Shadish
Fundamental Objects, Inc; bills@fo.com

This tip is extremely simple. But try it, and see if it helps you some time in the future.

Maybe you've inherited a large chunk of code from that developer who's smiling on the way out the door. Or, perhaps you're getting ready to ship that version 1.0 application to 100 users, try this. In any case, take a minute to search all of the code for the string

     On Error Resume Next
In fact, try this even if you don't want to ship your code to 100 users -- or especially if you have code that seems to fail "for no reason." You might be surprised at what that ol' Resume Next is hiding.

Top of Page


July 27, 1998
Labeling your forms
submitted by Bill Shadish
Fundamental Objects, Inc; bills@fo.com

Do you have a ton of screens in your application? Do you also have plenty of users who want to "help you" by pointing out buttons that are one twip out of place? Sometimes it's hard to know what screen users are talking about when they're trying to communicate a problem -- particularly if they're in a different location than you.

To reduce the pain of this process, I add a label (called lblHeader) to the top of each GUI window, nominally to hold start-up information for users when they first open the window. You can also use this label to hold the name of the window the user is looking at, by using the following code:

Private Sub Form_Load()
    SetupScreen me
End Sub


Public SetupScreen (frm as Form)
    ' Do other set-up stuff here (fonts, colors).
    HookInFormName frm
End Sub

Public Sub HookInFormName(frm As Form)
    ' The Resume Next on Error allows forms that do not use a standard
    ' header label to get past this.
    On Error Resume Next
    frm.lblHeader.Caption = "(" & frm.Name & ") " & frm.lblHeader.Caption
End Sub
Note that if you don't want to use a label, that you can also use code like

    frm.print frm.name 
to print to the back of the window itself.

Top of Page


July 6, 1998
Opening a browser to your homepage
submitted by Dan Newsome
D&D Information Professionals, newsomed@earthlink.net

You can use code like the following to open a browser to your homepage. Modify filenames, paths, and URLs as necessary to match the values on your system.

Dim FileName As String, Dummy As String
Dim BrowserExec As String * 255
Dim RetVal As Long
Dim FileNumber As Integer
Const SW_SHOWNORMAL = 1 ' Restores Window if Minimized or

Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long

Declare Function FindExecutable Lib "shell32.dll" Alias "FindExecutableA" _
(ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As _
String) As Long
'<Code> ---------

BrowserExec = Space(255)
FileName = "C:\temphtm.HTM"

FileNumber = FreeFile() ' Get unused file number

Open FileName For Output As #FileNumber ' Create temp HTML file
Write #FileNumber, " <\HTML>" ' Output text
Close #FileNumber ' Close file

' Then find the application associated with it.
  RetVal = FindExecutable(FileName, Dummy, BrowserExec)
  BrowserExec = Trim$(BrowserExec)
  ' If an application is found, launch it!
  If RetVal <= 32 Or IsEmpty(BrowserExec) Then ' Error

    Msgbox "Could not find a browser"

  Else
    RetVal = ShellExecute(frmMain.hwnd, "open", BrowserExec, _
      "www.myurl.com", Dummy, SW_SHOWNORMAL)
    If RetVal <= 32 Then ' Error
      Msgbox "Web Page not Opened"
    End If
  End If

Kill FileName ' delete temp HTML file

Top of Page


June 29, 1998
Creating a incrementing number box
submitted by Bryan Shoemaker
www.shadow.net/~fubar

You can't increment a vertical scroll bar's value -- a fact that can become annoying. For example, start a new project and place a text box and a vertical scroll bar on the form. Place the vertical scroll bar to the right of the text box and assign their Height and Top properties the same values. Assign the vertical scroll bar a Min property value of 1 and a Max value of 10. Place the following code in the vertical scroll bar's Change event:

Text1.Text = VScroll1.Value

Now press [F5] to run the project. Notice that if you click on the bottom arrow of the vertical scroll bar, the value increases; if you click on the top arrow, the value decreases. From my perspective, it should be the other way around.

To correct this, change the values of the Max and Min properties to negative values. For example, end the program and return to the design environment. Change the vertical scroll bar's Max value to -1 and its Min value to -10. In its Change event, replace the line you entered earlier with the following:

Text1.Text = Abs(Vscroll1.Value)

Now press [F5] to run the project. When you click on the top arrow of the vertical scroll bar, the value now increases. Adjust the Height properties of the text box and the scroll bar so you can't see the position indicator, and your number box is ready to go.

Top of Page


June 22, 1998
Measuring a text extent
submitted by Nenad Cus Babic
Nenad@computer.org

It's very simple to determine the extent of a string in VB. You can do so with WinAPI functions, but there's an easier way: Use the AutoSize property of a Label component. First, insert a label on a form (labMeasure) and set its AutoSize property to True and Visible property to False. Then write this simple routine:

Private Function TextExtent(txt as String) as Integer
   labMeasure.Caption = txt
   TextExtent = labMeasure.Width
End Function
When you want to find out the extent of some text, simply call this function with the string as a parameter.

In my case it turned out that the measure was too short. I just added some blanks to the string. For example:

Private Function TextExtent(txt As String) As Integer
   labMeasure.Caption = " " & txt
   TextExtent = labMeasure.Width
End Function

Top of Page


June 15, 1998
Importing Registry settings
submitted by Dan Newsome
D&D Information Professionals, newsomed@earthlink.net

You can use just a few lines of code to import Registry settings. If you have an application called myapp.exe and a Registry file called myapp.reg, the following code will put those settings into the Registry without bothering the user.

Dim strFile As String
strFile = App.Path & "\" & opts.AppExeName & ".reg"
If Len(Dir$(strFile)) > 1 Then
    lngRet = Shell("Regedit.exe /s " & strFile, vbNormalFocus)
End If

Top of Page


June 01, 1998
Use FreeFile to Prevent File Open Conflicts
Submitted by markus@bactive.com

Both Access and VB let you hard code the file numbers when using the File Open statement. For example:

     Open "myfile.txt" for Append as #1
     Print #1,"a line of text"
     Close #1

The problem with this method of coding is that you never know which file numbers may be in use somewhere else in your program. If you attempt to use a file number already occupied, you'll get a file error. To prevent this problem, you should always use the FreeFile function. This function will return the next available file number for your use. For example:

     IntFile=FreeFile()
     Open "myfile.txt" for Append as #intFile
     Print #intFile,"a line of text"
     Close #intFile

Top of Page


May 25, 1998
Confirm Screen Resolution
Submitted by Nicholas L. Otley, nicholaso@kalamzoo.co.uk; www.kalamazoo.co.uk

Here's a great way to stop the user from running your application in the wrong screen resolution. First, create a function called CheckRez:

Public Function CheckRez(pixelWidth As Long, pixelHeight As Long) As Boolean
    '
    Dim lngTwipsX As Long
    Dim lngTwipsY As Long
    '
    ' convert pixels to twips
    lngTwipsX = pixelWidth * 15
    lngTwipsY = pixelHeight * 15
    '
    ' check against current settings
    If lngTwipsX <> Screen.Width Then
        CheckRez = False
    Else
        If lngTwipsY <> Screen.Height Then
            CheckRez = False
        Else
            CheckRez = True
        End If
    End If
    '
End Function

Next, run the following code at the start of the program:

    If CheckRez(640, 480) = False Then
        MsgBox "Incorrect screen size!"
    Else
        MsgBox "Screen Resolution Matches!"
    End If

Top of Page


May 18, 1998
Quick Text Select On GotFocus
Submitted by scott@beacon-inc.com

When working with data entry controls, the current value in the control often needs to be selected when the control received focus. This allows the user to immediately begin typing over any previous value. Here's a quick subroutine to do just that:

Public Sub FocusMe(ctlName As Control)
    '
    With ctlName
        .SelStart = 0
        .SelLength = Len(ctlName)
    End With
    '
End Sub

Now add a call to this subroutine in the GotFocus event of the input controls:

Private Sub txtFocusMe_GotFocus()
    Call FocusMe(txtFocusMe)
End Sub

Top of Page


May 11, 1998
Take Advantage of Built-in OLE Drag and Drop
Submitted by Michael C. Amundsen, mike_tips@amundsen.com, http://www.amundsen.com

To add fully functional drag and drop to your forms, all you need to do is set the OLEDragMode property and OLEDropMode property of the input controls to "Automatic." This works across forms and even across applications on the same workstation. To test this, add two text boxes to a form. Use the Property Window to set the OLEDragMode and OLEDropMode properties to "Automatic." Now run the app and enter text in one text box and drag and drop it into the other text box.

Hint: Some controls only support OLEDrag. A few others do not support OLEDrag or OLEDrop. To determine what a control supports, check for the OLEDragMode and OLEDropMode properties. If their missing the control does not support OLEDrag and/or OLEDrop.

Top of Page


May 04, 1998
Use ParamArray to Accept an Arbitrary Number of Parameters
Submitted by Michael C. Amundsen, mike_tips@amundsen.com, http://www.amundsen.com

You can use the ParamArray keyword in the declaration line of a method to create a subroutine or function that accepts an arbitrary number of parameters at runtime. For example, you can create a method that will fill a list box with some number of items even if you do not know the number of items you will be sent. Add the method below to a form:

Public Sub FillList(ListControl As ListBox, ParamArray Items())
    '
    Dim i As Variant
    '
    With ListControl
        .Clear
        For Each i In Items
            .AddItem i
        Next
    End With
    '
End Sub

Note that the ParamArray keyword comes BEFORE the parameter in the declaration line. Now add a list box to your form and a command button. Add the code below in the "Click" event of the command button.

Private Sub Command1_Click()
    '
    FillList List1, "TiffanyT", "MikeS", "RochesterNY"
    '
End Sub

Top of Page


April 27, 1998
Use FileDSNs to ease ODBC Installs
Submitted by Michael C. Amundsen, mike_tips@amundsen.com, http://www.amundsen.com

If you're using an ODBC connection to your database, you can ease the process of installing the application on workstations by using the FileDSN (data source name) instead of the more-common UserDSN. You define your ODBC connection as you normally would with UserDSNs. However, the resulting definition is not stored in the workstation registry. Instead it gets stored in a text file with the name of the DSN followed by ".dsn" (i.e. "MyFileDSN.dsn"). The default folder for all FileDSNs is "c:\program files\common files\Odbc\data sources". Now, when you want to install the VB application that uses the FileDSN, all you need to do is add the FileDSN to the Install package and run the install as usual. No more setting up DSNs manually!

NOTE: FileDSNs are available with ODBC 3.0 and higher.

Top of Page


April 20, 1998
Increase Your RAD-ness by Creating Your Own VB5 Templates
Submitted by Michael C. Amundsen, mike_tips@amundsen.com, http://www.amundsen.com

You can create your own VB Templates quickly and easily. If you find that you are adding the same routines to your forms, classes, BAS modules, etc. you can build generic versions and place them in the Templates folder tree of VB5. By placing the coding module (frm, bas.cls, etc.) in the proper subfolder of the Templates folder, you'll see the new item appear whenever you select the Add... dialog box. You can add as many controls, library references, and lines of code as you wish to the templates.

CAUTION: If you uninstall VB5, you may loose your Templates folder and all its contents. Be sure to keep a secured copy of all your template files in a safe location.

Top of Page


April 06, 1998
Add Dithered Backgrounds to your VB Forms
By: Barron Anderson, Micron Electronics, Inc.

Ever wonder how the SETUP.EXE screen gets its cool shaded background coloring? This color shading is called dithering, and you can easily incorporate it into your forms. Add the following routine to a form:

   Sub Dither(vForm As Form)
   Dim intLoop As Integer
      vForm.DrawStyle = vbInsideSolid
      vForm.DrawMode = vbCopyPen
      vForm.ScaleMode = vbPixels
      vForm.DrawWidth = 2
      vForm.ScaleHeight = 256
      For intLoop = 0 To 255
         vForm.Line (0, intLoop)-(Screen.Width, intLoop - 1), RGB(0, 0, 255 -intLoop), B
      Next intLoop
   End Sub

Now, add to the Form_Activate event the line

   Dither ME

This version creates a fading blue background by adjusting the blue value in the RGB function. (RGB stands for Red-Green-Blue.) You can create a fading red background by changing the RGB call to

   RGB(255 - intLoop, 0, 0).

Top of Page


March 30, 1998
Dragging items from a list to another one
By Bassam Alkharashi, bkhrashi@kacst.edu.sa

Here's a way that you can let users drag items from one list and drop them in another one. Create two lists (lstDraggedItems, lstDroppedItems) and a text box (txtItem) in a form (frmTip).

Put the following code in the load event of your form.

Private Sub Form_Load()
  ' Set the visible property of txtItem to false
  txtItem.Visible = False
  'Add items to list1 (lstDraggedItems)
  lstDraggedItems.AddItem "Apple"
  lstDraggedItems.AddItem "Orange"
  lstDraggedItems.AddItem "Grape"
  lstDraggedItems.AddItem "Banana"
  lstDraggedItems.AddItem "Lemon"
  '
End Sub

In the mouseDown event of the list lstDraggedItems put the following code:

Private Sub lstDraggedItems_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  '
  txtItem.Text = lstDraggedItems.Text
  txtItem.Top = Y + lstDraggedItems.Top
  txtItem.Left = X + lstDraggedItems.Left
  txtItem.Drag
  '
End Sub

In the dragDrop event of the list lstDroppedItems put the following code:

Private Sub lstDroppedItems_DragDrop(Source As Control, X As Single, Y As Single)
  '
  If lstDraggedItems.ItemData(lstDraggedItems.ListIndex) = 9 Then
    Exit Sub
  End If
  ' To make sure that this item will not be selected again
  lstDraggedItems.ItemData(lstDraggedItems.ListIndex) = 9
  lstDroppedItems.AddItem txtItem.Text
  '
End Sub

Now you can drag items from lstDraggedItems and drop them in LstDroppedItems.

Note that you cannot drag from the second list to the first. Also, the dragged item remains in the first list. You'll have to address those limitations yourself.

Top of Page


March 23, 1998
Creating a new context menu in editable controls
By Antonio Almeida, future.systems@mail.telepac.pt

This routine will permit you to replace the original context menu with your private context menu in an editable control.

Add the following code to your form or to a BAS module:

Private Const WM_RBUTTONDOWN = &H204 Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Public Sub OpenContextMenu(FormName As Form, MenuName As Menu)

  'Tell system we did a right-click on the mdi
  Call SendMessage(FormName.hwnd, WM_RBUTTONDOWN, 0, 0&)
  'Show my context menu
  FormName.PopupMenu MenuName
  '
End Sub

Next, use the Visual Basic Menu Editor and the table below to create a simple menu.

Caption

Name

Visible

Context Menu

mnuContext

NO

...First Item

mnuContext1

 

...Second Item

mnuContext2

 

Note that the last two items in the menu are indented (...) one level and that only the first item in the list ("Context Menu") has the Visible property set to NO.

Now add a text box to your form and enter the code below in the MouseDown event of the text box.

Private Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

  If Button = vbRightButton Then
    Call OpenContextMenu(Me, Me.mnuContext)
  End If

End Sub

Note: If you just want to kill the system context menu, just comment out the line:

FormName.PopupMenu MenuName

in the OpenContextMenu routine.

Top of Page


March 16, 1998
Quick Custom Dialogs for DBGrid Cells
By Mike Amundsen, mike@amundsen.com, http://www.amundsen.com

It's easy to add custom input dialogs to all the cells in the Microsoft Data Bound Grid control.

First, add a DBGrid control and Data control to your form. Next, set the DatabaseName and RecordSource properties of the data control to a valid database and table ("biblio.mdb" and "Publishers" for example). Then set the DataSource property of the DBGrid control to Data1 (the data control).

Now add the following code to your form.

' general declaration area
Dim strDBGridCell As String

Private Sub DBGrid1_AfterColEdit(ByVal ColIndex As Integer)
  '
  DBGrid1.Columns(ColIndex) = strDBGridCell
  '
End Sub

Private Sub DBGrid1_BeforeColEdit(ByVal ColIndex As Integer, ByVal KeyAscii As Integer, Cancel As Integer)
  '
  strDBGridCell = InputBox("Edit DBGrid Cell:", , DBGrid1.Columns(ColIndex))
  '
End Sub

Now whenever you attempt to edit any cell in the DBGrid, you'll see the InputBox prompt you for input. You can replace the InputBox with any other custom dialog you wish to build.

Top of Page


March 9, 1998
Using the Alias Option to Prevent API Crashes
By Mike Amundsen mike@amundsen.com, http://www.amundsen.com

A number of Windows APIs have parameters that can be more than one data type. For example, the WinHelp API call can accept the last parameter as a Long or String data type depending on the service requested.

Visual Basic allows you to declare this data type as "Any" in the API call, but this can lead to type mismatch errors or even system crashes if the value is not the proper form.

You can prevent the errors and improve the run-time type checking by declaring multiple versions of the same API function in your program. By adding a function declaration for each possible parameter type, you can continue to use strong data type checking.

To illustrate this technique, add the following APIs and constants to a Visual Basic form. Notice that the two API declarations differ only in their initial name ("WinHelp" and "WinHelpSearch") and the type declaration of the last parameter ("dwData as Long" and "dwData as String").

' WinHelp APIs
Private Declare Function WinHelp Lib "user32" Alias "WinHelpA" (ByVal hwnd As Long, ByVal lpHelpFile As String, ByVal wCommand As Long, ByVal dwData As Long) As Long
Private Declare Function WinHelpSearch Lib "user32" Alias "WinHelpA" (ByVal hwnd As Long, ByVal lpHelpFile As String, ByVal wCommand As Long, ByVal dwData As String) As Long
'
Private Const HELP_PARTIALKEY = &H105&
Private Const HELP_HELPONHELP = &H4
Private Const HelpFile = "c:\program files\devstudio\vb5\help\vb5.hlp"

Now add two command buttons to your form (cmdHelpAbout and cmdHelpSearch) and place the following code behind the buttons. Be sure to edit the location of the help file to match your installation of Visual Basic.

Private Sub cmdHelpAbout_Click()
  '
  WinHelp Me.hwnd, HelpFile, HELP_HELPONHELP, &H0
  '
End Sub


Private Sub cmdHelpSearch_Click()
  '
  WinHelpSearch Me.hwnd, HelpFile, HELP_PARTIALKEY, "option"
  '
End Sub

When you press on the HelpAbout button, you'll see help about using the help system. When you press on the HelpSearch button, you'll see a list of help entries on the "option" topic.

Top of Page


March 2, 1998
Increment and decrement dates with the [+] and [-] keys
By Mike Coleman, Mike.Coleman@anixter.com

If you've ever used Quicken, you've probably noticed a handy little feature in that program's date fields. You can press the [+] key to increment one day, [-] to decrement one day, [PgUp] to increment one month, and [PgDn] to decrement one month. In this tip, we'll show you how to emulate this behavior with Visual Basic.

First, insert a text box on a form (txtDate). Set its text property to "" and its Locked property to TRUE.

Now place the following code in the KeyDown event:

Private Sub txtDate_KeyDown(KeyCode As Integer, Shift As Integer)
'
' 107 = "+" KeyPad
' 109 = "-" KeyPad
' 187 = "+" (Actually this is the "=" key, same as "+" w/o the shift)
' 189 = "-"
' 33 = PgUp
' 34 = PgDn
'
Dim strYear As String
Dim strMonth As String
Dim strDay As String
'
If txtDate.Text = "" Then
  txtDate.Text = Format(Now, "m/d/yyyy")
  Exit Sub
End If
'
strYear = Format(txtDate.Text, "yyyy")
strMonth = Format(txtDate.Text, "mm")
strDay = Format(txtDate.Text, "dd")
'
Select Case KeyCode
  Case 107, 187 ' add a day
    txtDate.Text = Format(DateSerial(strYear, strMonth, strDay) + 1, "m/d/yyyy")
  Case 109, 189 ' sbutract a day
    txtDate.Text = Format(DateSerial(strYear, strMonth, strDay) - 1, "m/d/yyyy")
  Case 33 ' add a month
    txtDate.Text = Format(DateSerial(strYear, strMonth + 1, strDay), "m/d/yyyy")
  Case 34 ' subtract a month
    txtDate.Text = Format(DateSerial(strYear, strMonth - 1, strDay), "m/d/yyyy")
End Select
'
End Sub

The one nasty thing about this is that if you have characters that are not the characters usually in a date (i.e., 1-9, Monday, Tuesday, or /) you get errors in the format command. To overcome this, I set the Locked property to True. This way, the user can't actually type a character in the field, but the KeyDown event still fires.

Top of Page


Febuary 23, 1998
Creating Win32 region windows
By AlMoataz B. Ahmed, AlMoataz_m@hotmail.com

The Win32 API includes a really amazing feature called region windows. A window under Win32 no longer has to be rectangular! In fact, it can be any shape that may be constructed using Win32 region functions. Using the SetWindowRgn Win32 function from within VB is so simple, but the results are unbelievable. The following example shows a VB form that is NOT rectangular. Enjoy!

' This goes into the General Declarations section:
 
Private Declare Function CreateEllipticRgn Lib "gdi32" _
(ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, _
ByVal Y2 As Long) As Long
 
Private Declare Function SetWindowRgn Lib "user32" _
(ByVal hWnd As Long, ByVal hRgn As Long, _
ByVal bRedraw As Boolean) As Long
 

Private Sub Form_Load()
  Show 'The form!
  SetWindowRgn hWnd, _
  CreateEllipticRgn(0, 0, 300, 200), _
  True
End Sub

Top of Page


Febuary 16, 1998
Manipulate your controls from the keyboard
By Narayana Vyas Kondreddi, vyas@aditi.com,
https://members.tripod.com/~vyaskn/index.html

If you're not comfortable using your mouse--or can't achieve the precise results you'd like--these tips will come in handy.

First, you can resize controls at design time by using the [Shift] and arrow keys, as follows:

SHIFT + RIGHT ARROW increases the width of the control
SHIFT + LEFT ARROW decreases the width of the control
SHIFT + DOWN ARROW increases the height of the control
SHIFT + UP ARROW decreases the height of the control

Note: The target control must have focus, so click on the control before manipulating it from the keyboard.

Second, by using the [Control] key and the arrow keys, you can move your controls at design time, as follows:

CONTROL + RIGHT ARROW to move the control to the right
CONTROL + LEFT ARROW to move the control to the left
CONTROL + DOWN ARROW to move the control downwards
CONTROL + UP ARROW to move the control upwards

If you select more than one control (by clicking on the first and shift-clicking on the others), the above procedures will affect all the selected controls.

Top of Page


Febuary 9, 1998
Simple file checking from anywhere
By Matthew Kent, mace@pacificcoast.net

To keep my applications running smoothly, I often need to check that certain files exist. So, I've written a simple routine to make sure they do. Here it is:

Public Sub VerifyFile(FileName As String)
  '
  On Error Resume Next
  'Open a specified existing file
  Open FileName For Input As #1
  'Error handler generates error message with file and exits the routine
  If Err Then
    MsgBox ("The file " & FileName & " cannot be found.")
    Exit Sub
  End If
  Close #1
'
End Sub
 
Now add a button to your form and place the code below behind the "Click" event.
 
Private Sub cmdVerify_Click()
  '
  Call VerifyFile("MyFile.txt")
  '
End Sub

Top of Page


Febuary 2, 1998
Showing long ListBox entries as a ToolTip
By Matt Vandenbush, matt_vandenbush@whbrady.com

Sometimes the data you want to display in a list is too long for the size of ListBox you can use. When this happens, you can use some simple code to display the ListBox entries as ToolTips when the mouse passes over the ListBox.

First, start a new VB project and add a ListBox to the default form. Then declare the SendMessage API call and the constant (LB_ITEMFROMPOINT) needed for the operation:

Option Explicit

'Declare the API function call.
Private Declare Function SendMessage _
Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
' Add API constant
Private Const LB_ITEMFROMPOINT = &H1A9

Next, add some code to the form load event to fill the ListBox with data:

Private Sub Form_Load()
'
' load some items in the list box
With List1
.AddItem "Michael Clifford Amundsen"
.AddItem "Walter P.K. Smithworthy, III"
.AddItem "Alicia May Sue McPherson-Pennington"
End With
'
End Sub

Finally, in the MouseMove event of the ListBox, put the following code:

Private Sub List1_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
'
' present related tip message
'
Dim lXPoint As Long
Dim lYPoint As Long
Dim lIndex As Long
'
If Button = 0 Then ' if no button was pressed
  lXPoint = CLng(X / Screen.TwipsPerPixelX)
  lYPoint = CLng(Y / Screen.TwipsPerPixelY)
  '
  With List1
    ' get selected item from list
    lIndex = SendMessage(.hwnd, _
    LB_ITEMFROMPOINT, _
    0, _
    ByVal ((lYPoint * 65536) + lXPoint))
    ' show tip or clear last one
    If (lIndex >= 0) And (lIndex <= .ListCount) Then
      .ToolTipText = .List(lIndex)
    Else
      .ToolTipText = ""
    End If
  End With '(List1)
End If '(button=0)
'
End Sub

Top of Page


 
Last Updated: 11/11/98  

© 1998 Microsoft Corporation. All rights reserved. Terms of Use.