Link to home
Start Free TrialLog in
Avatar of jnowlin
jnowlin

asked on

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

Hi.

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?

JN
Avatar of Microsoft
Microsoft

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.

http://www.domaindlx.com/e_morcillo/default.asp

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 ...
Here is one I found that provides the subclassing and mouse_over events:

http://www.vbaccelerator.com/codelib/cpopmenu/article.htm
Avatar of jnowlin

ASKER

PBuck,

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:

http://www.planetsourcecode.com/xq/ASP/txtCodeId.3313/lngWId.1/qx/vb/scripts/ShowCode.htm

-M
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!
Avatar of Richie_Simonetti
Hi, MELeBlanc, how about that old tab caption?

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

http://www.mvps.org/vbnet/code/subclass/systemabout.htm
http://www.vbonline.com/vb-mag/9907/article/subclass.htm
http://www.vbsquare.com/api/tip400.html
http://freeweb.coco.cz/jankudr/prj_subclasser.htm
http://www.ccrowley.f9.co.uk/vbweb/tutorials/subclassing.htm
http://www.thescarms.com/vbasic/SubClassTxt.htm


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).
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)
    Else
        '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
        UnHookWindow
    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)
    UnHookWindow
End Sub

'Hope will help.
Similar but a little compacted:

PROVIDE STATUS MESSAGES FOR MENUS
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, _
          ScaleWidth
End Sub

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

'--- Module code
Type MENUITEMINFO
     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 _
     MENUITEMINFO) As Long
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


Avatar of jnowlin

ASKER

Richie_Simonetti,

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.


ryancys,
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!

JN
Did you have checked the style property ( i mean, sbrNormal and sbrSimple)?
Avatar of jnowlin

ASKER

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.
I could send by e-mail a working code, would you like it?
Avatar of jnowlin

ASKER

OK.

Email address is:
jnowlin@rcn.com

Jim
ASKER CERTIFIED SOLUTION
Avatar of Richie_Simonetti
Richie_Simonetti
Flag of Argentina image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of jnowlin

ASKER

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")

and

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?

Mysteries......

Jim

But, never we have been talking about MDI!
Avatar of jnowlin

ASKER

Yes. MDI.

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

JimNowlin
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 >)
Avatar of jnowlin

ASKER

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?
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! ;)
Avatar of jnowlin

ASKER

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
i didn't try but i think that menu caption is modified.
In example:
"&Open" is a different caption to "&Open   Ctrl+O".