• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 243
  • Last Modified:

Status Bar in VB - Can it be used with the MouseMove event?


I made a status bar in my project, sbr1.
It has 4 panels.
I'd like to be able to place text into this as the user moves the mouse over each menu item before it is clicked.

The menu items have only the 'Clicked' event associated with it.

I tried to place text into the first panel, as in:

sbr1.Panels(1).Text = "This menu selection does this."

But, it doesn't work. This seems like a MouseOver (JavaScript) event.

Is there a way to do this?

  • 9
  • 8
  • 4
  • +3
1 Solution
try this my friend

this will show you example of mouse over effect.

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)    Label1.ForeColor = vbRedEnd Sub

Private Sub Label1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)    Label1.ForeColor = vbBlueEnd Sub

i mean this

sorry problems cutting my code and pasting it.

this will work

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)  
Label1.ForeColor = vbRed
End Sub

Private Sub Label1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Label1.ForeColor = vbBlue
End Sub

If I understand your question - you want User's to be able to mouse thru the menu items and have a description show on the statusbar panel, correct?

If this is the case, then you will most likely have to find some subclassing code to create a watch on your menu items.


The above link had some code to do exactly what you are asking - but damn if I can find it now.  I will have to look once again.  You can try to perform a search for Menu Icons (many are subclassed) and provide the descriptions to show to the status bar.

I will continue to look ...
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Here is one I found that provides the subclassing and mouse_over events:

jnowlinAuthor Commented:

What is 'subclassing'? It's new to me.
I went to the site you suggested, but I didn't see anything on subclassing. Is subclassing defined in a different way? However, the cPopMenu control listed there sounds interesting, as well.

This should give you a good example of exactly what you are looking for:


Sorry about that.  Subclassing is a way of intercepting Window's event messages - sometimes people can do this and maintain stability and sometimes not :-(

Basically, subclassing is very cool with the things you can do and make possible, but the downside is it is sometimes not very stable.

The link I gave you above has had lots of stable products using subclassing.  In fact, I think all there products use subclassing - try there other stuff to see what are some of the possibilites.

Good Luck!
Richie_SimonettiIT OperationsCommented:
Hi, MELeBlanc, how about that old tab caption?

jnowlin, here are some sites that should help you regarding subclassing.


NOTE: when you subclass (Anything) and you are working on IDE, Never, never and never terminate your apps with STOP button.

one other advice - never use END when subclassing (always Unload your forms and Set objects = Nothing).
Ryan ChongCommented:
Hi jnowlin, i think you can take a look on this example:


In your module:

Option Explicit

Public Const MF_BYCOMMAND = &H0&
Public Const MF_BYPOSITION = &H400&
Public Const MF_POPUP = &H10&
Declare Function GetMenuString Lib "user32" Alias "GetMenuStringA" (ByVal hMenu As Long, ByVal wIDItem As Long, ByVal lpString As String, ByVal nMaxCount As Long, ByVal wFlag As Long) As Long

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) As Long

Private oldwndproc As Long
Private subclassedhWnd As Long

Public Const WM_MENUSELECT = &H11F
Public Const WM_NCDESTROY = &H82
Public Const GWL_WNDPROC = (-4)

Public Sub HookWindow(SubClassForm As Form)
    ' if something is already subclassed, don't subclass anything else
    If oldwndproc <> 0 Then Exit Sub
    subclassedhWnd = SubClassForm.hwnd
    'Get the handle for the old window procedure so it can be replaced and used later
    oldwndproc = GetWindowLong(SubClassForm.hwnd, GWL_WNDPROC)
    'Install custom window procedure for this window
    SetWindowLong SubClassForm.hwnd, GWL_WNDPROC, AddressOf WndProc
End Sub

Private Function WndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    'Does control want this message?
    If Msg = WM_MENUSELECT Then
      ' This occurs when the menu is being closed
      If lParam = 0 Then Exit Function
      Dim MenuItemStr As String * 128
      Dim MenuHandle As Integer
      ' Get the low word from wParam: this contains the command ID or position of the menu entry
      MenuHandle = GetLowWord(wParam)
      'If the highlighted menu is the top of a poup menu, pass menu item by position
      If (GetHighWord(wParam) And MF_POPUP) = MF_POPUP Then
        'Get the caption of the menu item
        If GetMenuString(lParam, MenuHandle, MenuItemStr, 127, MF_BYPOSITION) = 0 Then Exit Function
      Else    ' Otherwise pass it by command ID
        'Get the caption of the menu item
        If GetMenuString(lParam, MenuHandle, MenuItemStr, 127, MF_BYCOMMAND) = 0 Then Exit Function
      End If
        ' Add status bar message here!
        frmMenu.StatusBar1.Panels(1).Text = Trim$(MenuItemStr)
        'Otherwise, just call default window handler
        WndProc = CallWindowProc(oldwndproc, hwnd, Msg, wParam, lParam)
    End If
    'Unhook this window if it is being destroyed
    If Msg = WM_NCDESTROY Then
    End If
End Function

Public Sub UnHookWindow()
    ' If there is nothing subclassed, there is nothing to unsubclass!
    If oldwndproc = 0 Then Exit Sub
    'Return to default window handler
    SetWindowLong subclassedhWnd, GWL_WNDPROC, oldwndproc
    oldwndproc = 0
End Sub

Public Function GetLowWord(Word As Long)
    GetLowWord = CInt("&H" & Right$(Hex$(Word), 4))
End Function

Public Function GetHighWord(Word As Long)
    GetHighWord = CInt("&H" & Left$(Hex$(Word), 4))
End Function


Then in your form:

Option Explicit

Private Sub Form_Load()
    HookWindow Me
End Sub

Private Sub Form_Unload(Cancel As Integer)
End Sub

'Hope will help.
Richie_SimonettiIT OperationsCommented:
Similar but a little compacted:

Subclassing a form lets you give a helpful message whenever a user highlights a menu item. Use the Caption property to identify the menu item, then display the help message in a label (lblStatus), which is on the form:

' --- Form code
Private Sub Form_Load()
     origWndProc = SetWindowLong(hwnd, GWL_WNDPROC, _
          AddressOf AppWndProc)
End Sub

Private Sub Form_Resize()
     lblStatus.Move 0, ScaleHeight - lblStatus.Height, _
End Sub

Private Sub Form_Unload(Cancel As Integer)
     SetWindowLong hwnd, GWL_WNDPROC, origWndProc
End Sub

'--- Module code
     cbSize As Long
     fMask As Long
     fType As Long
     fState As Long
     wID As Long
     hSubMenu As Long
     hbmpChecked As Long
     hbmpUnchecked As Long
     dwItemData As Long
     dwTypeData As String
     cch As Long
End Type

Public Declare Function CallWindowProc Lib "user32" Alias _
     "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal _
     hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, _
     ByVal lParam As Long) As Long
Public Declare Sub CopyMemory Lib "kernel32" Alias _
     "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, _
     ByVal cbCopy As Long)
Public Declare Function GetMenuItemInfo Lib "user32" Alias _
     "GetMenuItemInfoA" (ByVal hMenu As Long, ByVal un As _
     Long, ByVal b As Boolean, lpMenuItemInfo As _
Public Declare Function SetWindowLong Lib "user32" Alias _
     "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As _
     Long, ByVal dwNewLong As Long) As Long

Public Const GWL_WNDPROC = (-4)
Public Const WM_MENUSELECT = &H11F
Public Const MF_SYSMENU = &H2000&
Public Const MIIM_TYPE = &H10
Public Const MIIM_DATA = &H20

Public origWndProc As Long

Public Function AppWndProc(ByVal hwnd As Long, ByVal Msg _
     As Long, ByVal wParam As Long, ByVal lParam As Long) _
     As Long
     Dim iHi As Integer, iLo As Integer
     Select Case Msg
          Case WM_MENUSELECT
               Form1.lblStatus.Caption = ""
               CopyMemory iLo, wParam, 2
               CopyMemory iHi, ByVal VarPtr(wParam) + 2, 2
               If (iHi And MF_SYSMENU) = 0 Then
                    Dim m As MENUITEMINFO, aCap As String
                    m.dwTypeData = Space$(64)
                    m.cbSize = Len(m)
                    m.cch = 64
                    m.fMask = MIIM_DATA Or MIIM_TYPE
                    If GetMenuItemInfo(lParam, CLng(iLo), _
                         False, m) Then
                         aCap = m.dwTypeData & Chr$(0)
                         aCap = Left$(aCap, _
                              InStr(aCap, Chr$(0)) - 1)
                         Select Case aCap
                              Case "&Open": _
                                   Form1.lblStatus.Caption = _
                                   "Open a file"
                              Case "&Save": _
                                   Form1.lblStatus.Caption = _
                                   "Save a file"
                         End Select
                    End If
               End If
     End Select
     AppWndProc = CallWindowProc(origWndProc, hwnd, Msg, _
          wParam, lParam)
End Function
?Matt Hart, Tulsa, Oklahoma

replace lblStatus with statusbar1.panels("yourchoice").text
Good luck

jnowlinAuthor Commented:

I put the code where you said to put it. I made a new module and placed it in there and I changed the references from lblStatus to sbr1.Panels(1).Text =, etc.

I only set up the "Open" and the "&Save As" with text just to see if it would put text in the first panel of the status bar.

Everthing compiled ok, but when I clicked on "Open" or moved over it before the click there was no text in the status bar. My present knowledge level of VB is such that I have a hard time figuring out what this code is doing.

I arbitrarily chose to try Richie_Simonetti's code 1st. I will try yours. The same holds true for your code with regard to my level of VB know-how. This is some impressive code!

Richie_SimonettiIT OperationsCommented:
Did you have checked the style property ( i mean, sbrNormal and sbrSimple)?
jnowlinAuthor Commented:
The syle property was set at sbrNormal and I changed it to sbrSimple. The results are the same - no text in the sbr1 status bar.
Richie_SimonettiIT OperationsCommented:
I could send by e-mail a working code, would you like it?
jnowlinAuthor Commented:

Email address is:

Richie_SimonettiIT OperationsCommented:
It is on its way rigth now.
jnowlinAuthor Commented:
OK. Now I'm going crazy.

The code you sent works EXACTLY as I want it to on my project. Thank you so much. But,......

I put everything exactly where it should go, I even deleted my original status bar with 4 panels and put one on there named sb1, thinking that maybe VB was getting confused with my earlier sbr1. I replaced the module code as appropriate, as in:

frmMDIMain.sb1.SimpleText = ""
as well as the other 2 ("&Open" and "&Save")


it doesn't work.

Your's works great!

Ah, but yours is not an MDI form and mine IS.

Could that be the reason? I don't understand why?



Richie_SimonettiIT OperationsCommented:
But, never we have been talking about MDI!
jnowlinAuthor Commented:
Yes. MDI.

How much does this change this? I would say not much, but, then again, I'm not a VB expert as yet.   ;)

Richie_SimonettiIT OperationsCommented:
When we are trying to subclass the menu, VB believes that we are trying to create a new MDI form and we are unable to "create" more than one MDI for application.
(That is the error what i get >)
jnowlinAuthor Commented:
Yes. Only 1 MDI form per project I know.
Is this a bug in Visual Basic that only SDI forms may be subclassed? I have seen many Windows applications which have status bar display messages. Is not WordPad an MDI application?
Richie_SimonettiIT OperationsCommented:
No, it isn't.
But, anyway, if you code in C++ (like Wordpad is done) you get complete control over each resource when is created at low level.
I think that vb .net should be enable to give us this power (besides other awful things! ;)
jnowlinAuthor Commented:
Thank you RS;

This was a tremendous help. I started another project, an SDI and the menu items work. They don't work, that is, place text in the status bar, if you add shortcut controls to your menu items - Ctrl+O for Open, Ctrl+S for Save, etc.
Oh, well. Yet another "fix" or "feature" of Visual Studio.Net!!

Thanks again,

Jim Nowlin
Richie_SimonettiIT OperationsCommented:
i didn't try but i think that menu caption is modified.
In example:
"&Open" is a different caption to "&Open   Ctrl+O".

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

  • 9
  • 8
  • 4
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now