⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clsmenubarcontrol.cls

📁 AeroSuite--一组非常漂亮的VISTA控件集
💻 CLS
📖 第 1 页 / 共 4 页
字号:
            SetTextColor destDC, ConvertVBSysColor(m_fColor(fcDisabled))
        ElseIf m_LastState Then
            fColor = SetTextColor(destDC, ConvertVBSysColor(m_fColor(fcSelected)))
        Else
            fColor = SetTextColor(destDC, ConvertVBSysColor(m_fColor(fcInActive)))
        End If
        If m_HiliteStyle = 0 Then
            If m_HiliteStyle = 0 And ((m_TrackLevel Or 2) = m_TrackLevel) Then OffsetRect dcRect, 1, 1
        End If
        hFont = SelectObject(destDC, m_Font)
        mCaption = GetMenuItemCaption(m_CurSelect)
        DrawText destDC, mCaption, -1, dcRect, DT_CENTER Or DT_VCENTER Or DT_SINGLELINE
        SelectObject destDC, hFont
        SetTextColor destDC, fColor
    End If
    If destDC Then
        If hMnuBmp Then SelectObject m_MenuDC, hMnuBmp
        SelectClipRgn destDC, 0
        ReleaseDC p_Hwnd, destDC
    End If
End If

End Sub

Private Sub DrawHilite(hDC As Long, mRect As RECT, isPushed As Boolean)
Dim bColor1 As Long, bColor2 As Long
Dim xOffset As Long, yOffset As Long
Dim hOldPen As Long, hBrush As Long

If m_HiliteStyle Then
'    If isPushed Then
        hBrush = CreateSolidBrush(ConvertVBSysColor(m_HiliteColor(1)))
        FillRect hDC, mRect, hBrush
        DeleteObject hBrush
'    End If
    hBrush = CreateSolidBrush(ConvertVBSysColor(m_HiliteColor(0)))
    FrameRect hDC, mRect, hBrush
    DeleteObject hBrush
Else
    If isPushed Then
        bColor1 = m_HiliteColor(1)
        bColor2 = m_HiliteColor(0)
'        mRect.Bottom = mRect.Bottom + 1
    Else
        bColor1 = m_HiliteColor(0)
        bColor2 = m_HiliteColor(1)
    End If
    hOldPen = SelectObject(hDC, CreatePen(0, 1, ConvertVBSysColor(bColor1)))
    MoveToEx hDC, mRect.Left, mRect.Bottom, ByVal 0&
    LineTo hDC, mRect.Left, mRect.Top
    LineTo hDC, mRect.Right, mRect.Top
    DeleteObject SelectObject(hDC, CreatePen(0, 1, ConvertVBSysColor(bColor2)))
    LineTo hDC, mRect.Right, mRect.Bottom
    LineTo hDC, mRect.Left - 1, mRect.Bottom
    DeleteObject SelectObject(hDC, hOldPen)
End If
End Sub

Friend Function GetHitTest(X As Long, Y As Long) As Long
' identifies if mouse is over a menubar menu item
Dim itemNr As Long
For itemNr = 0 To UBound(mnuItem)
    If PtInRect(mnuItem(itemNr).mRect, X, Y) Then
        GetHitTest = itemNr + 1 ' append 1 here,it will be remove later
        Exit Function
    End If
Next
End Function

Friend Sub TrackSystemMenu(sysRegion As Long, leftAligned As Boolean)
' displays the system menu
Dim mPts As POINTAPI, sysRect As RECT
Dim X As Long, Y As Long, tpmFlags As Long
    
Const TPM_BOTTOMALIGN As Long = &H20&

If sysRegion = 0 Then
    GetCursorPos mPts
    X = mPts.X: Y = mPts.Y
Else
    GetRgnBox sysRegion, sysRect
    If leftAligned Then
        X = sysRect.Right + 2
        Y = sysRect.Bottom
        tpmFlags = TPM_BOTTOMALIGN
    Else
        X = sysRect.Left
        Y = sysRect.Bottom + 2
    End If
End If
If m_Tracking Then ' called as part of the menu loop
    TrackMenuBar -100, True, True, False, True, X, Y, tpmFlags
Else                ' default display method
    TrackPopupMenu GetSystemMenu(p_Hwnd, 0), tpmFlags, X, Y, 0, p_Hwnd, ByVal 0&
End If
End Sub

Friend Sub TrackMenuBar(ByVal menuPos As Long, ByVal isClicked As Boolean, _
    ByVal hasSysIcon As Boolean, ByVal hiliteOnly As Boolean, _
    Optional bSelectFirst As Boolean, _
    Optional ByVal X As Long, Optional ByVal Y As Long, _
    Optional ByVal pFlags As Long)

' This routine and the next four below are all part of the menu loop
' A bit unique from others out there cause it does handle keyboard
' loops to include the system menu & also handles menubar menu items
' that do not have submenus....

' THE MENU LOOP PART 1 - Showing the appropriate submenu/systemmenu

' Parameters....
' menuPos is the zero-based menubar item position
' isClicked is same as mouse down
' hasSysIcon indicates keybd navigation can go to the system menu in a loop
' hiliteOnly only will not display submenus; otherwise it will
' bSelectFirst will attempt to hilight the 1st menu item in submenu (disabled or not)
' X & Y are optional screen coords to display popup menus
' pFlags are optional and generally used here to redraw/refresh menubar

Dim subID As Long
Dim mnuRect As RECT, wndRect As RECT

If isClicked = True And hiliteOnly = False Then ' user clicked on the submenu item
    If menuPos > -1 Then    ' not the system menu which is either -99 or -100
        ' Test for upper level menus without submenus -- some people do this...
        subID = GetSubMenu(m_Menu, menuPos) ' see if it has a submenu
        If subID = 0 Then                   ' no submenu - fire the event
            TrackingState = False   ' release hooks & refresh menubar
            DrawMenuBarItems 1, 0, mnuRect, wndRect, MNU_Reset, MNU_Refresh
            ' send the click event
            If (mnuItem(menuPos).Flags And MF_DISABLED) <> MF_DISABLED Then _
                PostMessage p_Hwnd, WM_COMMAND, mnuItem(menuPos).ID, ByVal 0&
            HTrack.htk_FromKeyBd = False
            HTrack.htk_ESC = False
            Exit Sub
        End If
    End If
Else
    If isClicked Then
        subID = GetSubMenu(m_Menu, menuPos) ' see if it has a submenu
    Else
        ' special meaning and used internally in this class...only when not displaying items
        If pFlags = MNU_Refresh Or pFlags = MNU_Reset Or pFlags = MNU_Reset * 100 Then
            DrawMenuBarItems 1, 0, mnuRect, wndRect, menuPos, pFlags
            If pFlags = MNU_Reset * 100 Then
                ' special case: user exited menu with escape while submenus were
                ' displayed. Windows generally remains in the loop and this message
                ' will re=enter the loop to mimic that functionality
                TrackingState = False
                PostMessage p_Hwnd, &H112, &HF100&, -menuPos
            End If
            HTrack.htk_FromKeyBd = False
            HTrack.htk_ESC = False
            Exit Sub
        End If
    End If
End If

''Debug.Print "entering menu loop with "; menuPos

' build the hotkey list if needed
If Len(m_HotKeys) = 0 Then BuildHotKeyList

' calc tracking level :: 1=hilite only, 2=auto select submenu
m_TrackLevel = 1 - isClicked
If hasSysIcon Then m_TrackLevel = m_TrackLevel Or 4

Do
    
    m_Tracking = False     ' initially turn of tracking
    If menuPos = -99 Or menuPos = -100 Then ' system menu here
        ' erase any previously highlighted menubar items
        DrawMenuBarItems 1, 0, mnuRect, wndRect, MNU_Reset, 0
    Else    ' menubar item, highlight it
        DrawMenuBarItems 1, 0, mnuRect, wndRect, menuPos, pFlags
        pFlags = 0
    End If
    m_Tracking = True ' set property for subclass wndProc to check
    
    ' regardless whether or not a menu item has a submenu, if we are
    ' on the 1st level of tracking (hilighting only) then don't show submenu
    If (m_TrackLevel Or 1) = m_TrackLevel Then subID = 0
    
    SetProp p_Hwnd, "nextMnuPos", -1    ' set a default "failure" value
    SetInputHook False, Nothing         ' ensure keybd/mouse hook disabled
    
    GetCursorPos HTrack.htk_Pt    ' cache current cursor
    
    If subID > 0 Then   ' menubar item has a submenu - easy
    
        SetMenuHook True, Me    ' sneak a peek on mouse movements
        
        ' show the menubar submenu & select 1st item if appropriate
        If bSelectFirst Then
            PostMessage p_Hwnd, &H100&, vbKeyDown, ByVal 0&
            bSelectFirst = False
        End If
        TrackPopupMenu subID, pFlags, _
            m_MBarXY.X + mnuItem(menuPos).mRect.Left, _
            m_MBarXY.Y + mnuItem(menuPos).mRect.Bottom, 0, p_Hwnd, ByVal 0&
        
        SetMenuHook False, Nothing  ' disable menu hook
        ' get the next menu to display set in routine: SetMenuAction
        menuPos = GetProp(p_Hwnd, "nextMnuPos")
        m_Tracking = False ' reset variable
        
    ElseIf menuPos = -99 Then   ' keyboard left/right to system menu
        ' forward message back so routines can prevent VB's min/max/close drawing
        PostMessage p_Hwnd, &H313, &HF100&, ByVal 0&
        menuPos = -1    ' prevent looping; the above postmessage will get back here
        
    ElseIf menuPos = -100 Then  ' sysmenu is back and ready to display
        
        SetMenuHook True, Me    ' sneak a peek on mouse movements
        
        ' show the system menu with optional X,Y & alignment flags
        ' and also auto-select the 1st menu item
        PostMessage p_Hwnd, &H100&, vbKeyDown, ByVal 0&
        TrackPopupMenu GetSystemMenu(p_Hwnd, 0), pFlags, X, Y, 0, p_Hwnd, ByVal 0&
        
        menuPos = GetProp(p_Hwnd, "nextMnuPos") ' get next menu to display
        pFlags = 0      ' reset if ever used
        m_Tracking = False ' reset flag
        
    Else ' main menu item without submenus, or tracking in hilight mode only
         ' We'll need to track via mouse & keyboard hooks
        menuPos = -1            ' prevent looping for now
        m_Tracking = True ' set flag
        SetInputHook True, Me   ' start the keybd/mouse hooks
    End If
    
    HTrack.htk_FromKeyBd = False  ' flag to indicate menu navigated via keyboard
    If menuPos = -1 Then   ' is there a next menu to display?
        Exit Do ' no next menu or hilight tracking only; boogy out
    Else
        subID = 0           ' reset variables
        With HTrack         ' this is used to help navigate popups
            .htk_Was = 0    ' with keyboard and mouse simultaneously
            .htk_Now = 0
            .htk_Next = 0
            .htk_ESC = False        'flag to indicate ESC last pressed or not
        End With
        ' now see if the next menu item has a submenu or not
        If menuPos > -1 Then subID = GetSubMenu(m_Menu, menuPos)
        ' return back up to the loop
    End If
Loop
''Debug.Print "exiting menu loop"
End Sub

Friend Function SetMenuAction(lParam As Long) As Boolean

' THE MENU LOOP PART 2 - Normal popups including system menu

' This routine is the callback function from the MessageHook &
' is used only for menubar items with submenus.

''Debug.Print " getting menu messages "

If lParam = 0 Or m_Tracking = False Then Exit Function

Dim newMsg As MSG
Dim newMenuID As Long

' copy the message so we can look at it
CopyMemory newMsg, ByVal lParam, Len(newMsg)


With newMsg
    Select Case .message    ' these are common WM_flags
    Case WM_MOUSEMOVE
        ' ensure the point is somewhere in our window!
        If WindowFromPoint(.pt.X, .pt.Y) = p_Hwnd Then
            ' each popup usually is followed by 1 or more mouse moves
            ' Since we cached the current coords, we can prevent misfiring
            ' when cursor is over one item, but user keyboards to another
            ' and when it opens, the mouse move message would trigger the
            ' routines to go back to the item where the cursor is. Annoying.
            If HTrack.htk_Pt.X <> .pt.X Or HTrack.htk_Pt.Y <> .pt.Y Then
                ' ok, a new spot, get a hit test on menuitems
                newMenuID = GetHitTest(.pt.X - m_MBarXY.X, .pt.Y - m_MBarXY.Y) - 1
                ' ensure not already highlighted and is enabled...
                If newMenuID <> m_CurSelect And newMenuID > -1 Then
                    ' set flag & post cancel message will will then
                    ' release the loop so it can continue
                    SetProp p_Hwnd, "nextMnuPos", newMenuID
                    PostMessage p_Hwnd, WM_CANCELMODE, 0, ByVal 0&
                End If
            End If
        End If
    Case WM_KEYDOWN ' keyboard navigation
        HTrack.htk_ESC = False  ' indicate last key pressed is not the ESC key
        ' when navigated from submenu-less item to here, the right or left
        ' Key_Down message will follow unfortunately. So we use the
        ' HTTrack.htk_FromKeyBd set in that routine to warn us here.
        ' For description of other HTTrack elements, see further below.
        Select Case .wParam     ' virtual key codes
        Case vbKeyLeft
            If (HTrack.htk_Now = HTrack.htk_Was Or HTrack.htk_Was = 0) _
                And HTrack.htk_FromKeyBd = False Then
                ' set flag to next menu item, send cnx message to loop
                SetProp p_Hwnd, "nextMnuPos", NextMenuPosition(True, True)
                PostMessage p_Hwnd, WM_CANCELMODE, 0, ByVal 0&
                SetMenuAction = True    ' eat this message
            Else
                HTrack.htk_FromKeyBd = False    ' reset flag
            End If
        Case vbKeyRight
            If HTrack.htk_Next = 0 And HTrack.htk_FromKeyBd = False Then
                'set flag to next menu item, send cnx message to loop
                SetProp p_Hwnd, "nextMnuPos", NextMenuPosition(False, True)
                PostMessage p_Hwnd, WM_CANCELMODE, 0, ByVal 0&
                SetMenuAction = True    ' eat this message
            Else
                HTrack.htk_FromKeyBd = False    ' reset flag
            End If
        Case vbKeyReturn
            If (HTrack.htk_Now = 0 Or HTrack.htk_FromKeyBd = True) Then
                HTrack.htk_FromKeyBd = False
                SetMenuAction = True
            End If
        Case vbKeyEscape
            HTrack.htk_ESC = True   ' identify as last key pressed
        End Select
    
    Case &H11F  ' wm_menuselect
        If HiWord(.wParam) = -1 And .lParam = 0 Then ' menu is closing
            If m_CurSelect < 0 Then ' system menu

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -