Visual Basic Text API Routines
Pure VB: Cue Banners for the XP Impaired
Posted:   Tuesday September 30, 2003
Updated:   Monday December 26, 2011
Applies to:   VB5, VB6
Developed with:   VB6, Windows XP
OS restrictions:   None
Author:   VBnet - Randy Birch


Pure VB: Cue Banners for the XP Impaired
Manifests: Make the VB IDE use Windows XP Styles
SendMessage: Use Cue Banners to Prompt Users
CreateWindowEx: 21st Century ToolTips for VB - The Basics
Shell_NotifyIcon: Windows Systray NOTIFYICONDATA Overview
Shell_NotifyIcon: Add Icon to Windows System Tray
Shell_NotifyIcon: Respond to Systray Icon/Menu Interaction
Shell_NotifyIcon: Respond to Systray Icon/Menu Interaction in a MDI App

Shell_NotifyIcon: Animate the System Tray Icon
Shell_NotifyIcon: Display Systray Balloon Tips

Shell_NotifyIcon: Respond to Systray Balloon Tip Clicks
Shell_NotifyIcon: Use SetTimer to Define Balloon Tip Life
SendMessage: Add Balloon Tips to a Combo Edit Box

SendMessage: Add Balloon Tips to a Text Box

OK, so not everyone is running XP. But no worries .. simulating the cue prompt feature in VB text boxes, rich text boxes or the edit portion of Style 0 or 1 combo boxes is simple and can be used with all versions of Windows using the code below. Where form real estate may be at a premium, this is a useful way to indicate the data expected in a control without using form space for labels.

Unlike the XP-supported SendMessage/EM_SETCUEBANNER method, where the control itself retains the string in order to redisplay the cue text prompt as required, using pure VB it's a bit more code to create, maintain and apply the simulated cue text prompts.

This pure-VB solution utilizes the control's tag property to store the cue prompt text to be displayed in the control, and, because a flag is required for each control to know whether the cue text should be displayed or not, this demo takes a unique approach and uses the control's typically never-used HelpContextID property to hold the Boolean flag, since in many applications control-sensitive context help is not implemented.

If your application uses the tag property of the control and/or the HelpContextID for other purposes, you will need to implement a different mechanism to store the prompt string and flags ... most likely using Boolean and String arrays (as my first attempt at this did before I decided to simplify and use control properties to do the work). And, if you're developing the application for multiple Windows versions I would be inclined to use the XP method if possible by making a test for XP and then depreciate to using this method if XP was not the OS - code called from Form Load could handle determining the OS version and populating the tag and HelpContextID properties if required. Code you can use to determine the OS version, specifically the IsWinXP() or IsWinXpPlus() routines, is available from the Related links above. The Comments section following the code speaks further to utilizing both methodologies.

Simulating the cue prompt feature is fairly straightforward. A series of wrapper routines accepting a control are created, one each to test for activity in the Change, GotFocus and LostFocus events. On load the control and cue prompt text is passed to the setup routine, which assigns the text to the Tag and Text properties of the control. The Tag is set first since assigning the Text fires the Change event, which in turn fires the CheckCuePromptChange wrapper routine.

CheckCuePromptChange is solely responsible for setting a flag to indicate whether the text box contains user-entered data (Tag <> Text), or not. The Got and LostFocus events of each control fire the CheckCuePromptOnFocus and CheckCuePromptOnBlur routines respectively. CheckCuePromptOnFocus tests the flag (conveniently stored in the HelpContextID for the control), and if True (indicating the control currently contains the cue prompt text), clears the edit box and restores the ForeColor to vbWindowText. If HelpContextID is False, the control's edit window does not contain cue text, but since the control has gained focus the existing text is selected for editing.

CheckCuePromptOnBlur works the other way. If, on loosing focus the length of the text in the edit control is greater than 0, it is presumed the user has entered data and no action occurs. If the length is 0, nothing was entered and the control's ForeColor reverts to vbButtonShadow and the cue prompt text is redisplayed. 

As you'll see from the demo, this code is most economically used with controls in a control array. Also, the code does not perform any validation of the control passed to the wrapper routines. You may want to add TypeOf checks to ensure the code does not set unsupported properties of controls mistakenly passed to the routine.

 BAS Module Code

 Form Code
Add three text boxes in a control array (Text1(0) through Text1(2)), and a combo (Combo1). Because the cue text disappears when a control gains focus, another control is required on the form to take the initial focus on start-up, so add a command button (Command1). The Load code will set the TabIndex to 0.

Option Explicit
' Copyright 1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
Private Sub Form_Load()

  'ensure the edit controls do not
  'gain initial focus on start-up
   Command1.TabIndex = 0

  'assign the cue prompt text to the respective controls
   SetupCueControl Text1(0), "Enter regional office"
   SetupCueControl Text1(1), "Enter the sales group"
   SetupCueControl Text1(2), "Enter the group leader"
   SetupCueControl Combo1, "Select regional office"
   SetupCueControl Combo2, "Select the sales group"
   SetupCueControl Combo3, "Select group leader"
  'some dummy combo data
   Combo1.AddItem "test item"
   Combo2.AddItem "test item"
   Combo3.AddItem "test item"

End Sub

Private Sub SetupCueControl(ctl As Control, sCue As String)

  'assign the cue text to the control's edit
  'box, as well as to the tag property. Using
  'the tag property to store the cue prompt text
  'negates the requirement to maintain the text
  'in a separate array. If your application design
  'uses are using the tag property for another
  'purpose, such as to store the dirty text of
  'the control, then a string array must be maintained
  'along with a mechanism to identify the control
  'in order to assign the correct prompt to the
  'respective control.
   With ctl
      .ForeColor = vbButtonShadow
     'tag is set first to ensure
     'CheckCuePromptChange sets correct value
     'when the control's Change event fires
      .Tag = sCue
      .Text = sCue

   End With
End Sub

Private Sub CheckCuePromptChange(ctl As Control)

   ctl.HelpContextID = Trim$(ctl.Text) = ctl.Tag
End Sub

Private Sub CheckCuePromptOnFocus(ctl As Control)

   With ctl
      If .HelpContextID = True Then

         .Text = ""
         .ForeColor = vbWindowText

         .SelStart = 0
         .SelLength = Len(.Text)
         .HelpContextID = False
      End If

   End With

End Sub

Private Sub CheckCuePromptBlur(ctl As Control)

   With ctl
      If Len(Trim$(.Text)) = 0 Then
         .Text = .Tag
         .ForeColor = vbButtonShadow
         .HelpContextID = True

      End If

   End With

End Sub

Private Sub Combo1_Change()

   CheckCuePromptChange Combo1
End Sub

Private Sub Combo1_GotFocus()
   CheckCuePromptOnFocus Combo1
End Sub

Private Sub Combo1_LostFocus()

   CheckCuePromptBlur Combo1

End Sub

Private Sub Combo2_Change()

   CheckCuePromptChange Combo2
End Sub

Private Sub Combo2_GotFocus()
   CheckCuePromptOnFocus Combo2
End Sub

Private Sub Combo2_LostFocus()

   CheckCuePromptBlur Combo2

End Sub

Private Sub Combo3_Change()

   CheckCuePromptChange Combo3
End Sub

Private Sub Combo3_GotFocus()
   CheckCuePromptOnFocus Combo3
End Sub

Private Sub Combo3_LostFocus()

   CheckCuePromptBlur Combo3

End Sub

Private Sub Text1_Change(index As Integer)

   CheckCuePromptChange Text1(index)
End Sub

Private Sub Text1_GotFocus(index As Integer)

   CheckCuePromptOnFocus Text1(index)
End Sub

Private Sub Text1_LostFocus(index As Integer)

   CheckCuePromptBlur Text1(index)

End Sub
Probably the easiest way to utilize the code above as well as the XP API method within the same app is to, on load:
  • determine the OS version by calling IsWinXP() or IsWinXpPlus(), and save the return value to a form level flag, ie bIsXp
  • if bIsXp, call a SetupXPCueControl() routine that would contain the code from the load event in SendMessage: Use Cue Banners to Prompt Users
  • If not bIsXp, call SetupCueControl instead
  • In each of the three wrapper routines, add as the first line:
        If bIsXp Then Exit Sub

This would allow the same code to be used within the events of each control, yet abort the VB-specific action within the wrapper routines if XP had been detected allowing the XP control take care of maintaining the cue prompt text and status.


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


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


Hit Counter