Results 1 to 29 of 29

Thread: [RESOLVED] how do i show an image when mouse is over a menu item?

Threaded View

  1. #15
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: how do i show an image when mouse is over a menu item?

    Just because I love puzzles, this is a good solution, but has one drawback addressed at bottom of this post.

    The fix is to locate the menu immediately, test whether the mouse X,Y coords are within the window bounds, and testing if the menu is visible or not. Seems to work really well for mouse "hover" over a menu selection.
    Code:
    Option Explicit
    Private Declare Function GetCursorPos Lib "user32.dll" (ByRef lpPoint As POINTAPI) As Long
    Private Declare Function WindowFromPoint Lib "user32.dll" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
    Private Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hWnd As Long, ByRef lpRect As RECT) As Long
    Private Declare Function ScreenToClient Lib "user32.dll" (ByVal hWnd As Long, ByRef lpPoint As POINTAPI) As Long
    Private Declare Function IsWindowVisible Lib "user32.dll" (ByVal hWnd As Long) As Long
    Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Type POINTAPI
        X As Long
        Y As Long
    End Type
    Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    
    Private myMenuHwnd As Long
    
    Private Sub mnuMain_Click()
        ' when menu opens, start timer
        Me.Caption = "Waiting for menu selection" ' testing purposes
        DoEvents ' should allow menu to appear
        myMenuHwnd = FindWindow("#32768", vbNullString)
        Timer1.Tag = "-1"
        Timer1.Interval = 100
        Timer1.Enabled = True
    End Sub
    
    Private Sub Timer1_Timer()
        Dim mPT As POINTAPI, sBuffer As String
        Dim wRect As RECT, mIndex As Long
        Dim nrMenuItems As Long
        
        GetCursorPos mPT
        If myMenuHwnd = 0& Then
            myMenuHwnd = WindowFromPoint(mPT.X, mPT.Y)
            sBuffer = String$(6, vbNullChar)
            Call GetClassName(myMenuHwnd, sBuffer, 7)
            If sBuffer <> "#32768" Then myMenuHwnd = 0&
        ElseIf IsWindowVisible(myMenuHwnd) = 0& Then
            Me.Caption = "Menu closed" ' testing purposes
            Timer1.Enabled = False
            myMenuHwnd = 0&
        End If
        If myMenuHwnd Then
            GetWindowRect myMenuHwnd, wRect
            If mPT.Y > wRect.Top And mPT.Y < wRect.Bottom Then
                If mPT.X > wRect.Left And mPT.X < wRect.Right Then
                    ScreenToClient myMenuHwnd, mPT
                    nrMenuItems = 3 ' I only used 3 for my test
                    mIndex = mPT.Y \ ((wRect.Bottom - wRect.Top) \ nrMenuItems)
                    If mIndex <> Val(Timer1.Tag) Then
                        Timer1.Tag = mIndex
                        Me.Caption = "over menu item " & mIndex + 1 ' testing purposes
                    End If
                End If
            End If
        End If
    End Sub
    Downside. Does not deal with user moving up/down menu items via the keyboard. Can be overcome with a keybd hook (like subclassing) or another timer testing keyboard for strokes (GetAsyncKeyState API for example)
    Edited:
    Other potential issues if they apply:
    1. If menu is large and eventually scrolls; all bets are off and will require a lot more work
    2. If menu opens any contained submenus; needs more work to stop timer when submenu opens & restart timer when submenu closes

    Subclassing is the correct way to do what you want and all issues will be overcome; but as mentioned before, subclassing requires some practice and has zero-tolerance for errors. Makeshift workarounds rarely work as well, can be buggy, and often are less efficient than the "correct" way. Just FYI.
    Last edited by LaVolpe; Jan 26th, 2010 at 12:17 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width