VB语言

本类阅读TOP10

·Visual Basic 安装程序的制作!!
·VB中使用EXCEL输出
·一个简单的MP3播放器
·VB程序实现WindowsXP效果的界面!!
·VB打造超酷个性化菜单(六)
·透明位图
·平铺与拉伸MDI窗口的背景图 ~!~
·对《VB程序实现WindowsXP效果的界面》一文的补遗
·从Windows资源管理器中拖动文件
·VB打造超酷个性化菜单(一)

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
VB打造超酷个性化菜单(六)

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

VB打造超酷个性化菜单(六)

 

(接上篇)

 

' 拦截菜单消息 (frmMenu 窗口入口函数)
Function MenuWndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Select Case Msg
        Case WM_COMMAND                                                 ' 单击菜单项
            If MyItemInfo(wParam).itemType = MIT_CHECKBOX Then
                If MyItemInfo(wParam).itemState = MIS_CHECKED Then
                    MyItemInfo(wParam).itemState = MIS_UNCHECKED
                Else
                    MyItemInfo(wParam).itemState = MIS_CHECKED
                End If
            End If
            MenuItemSelected wParam
        Case WM_EXITMENULOOP                                            ' 退出菜单消息循环(保留)
           
        Case WM_MEASUREITEM                                             ' 处理菜单项高度和宽度
            MeasureItem hwnd, lParam
        Case WM_MENUSELECT                                              ' 选择菜单项
            Dim itemID As Long
            itemID = GetMenuItemID(lParam, wParam And &HFF)
            If itemID <> -1 Then
                MenuItemSelecting itemID
            End If
        Case WM_DRAWITEM                                                ' 绘制菜单项
            DrawItem lParam
    End Select
    MenuWndProc = CallWindowProc(preMenuWndProc, hwnd, Msg, wParam, lParam)
End Function

' 处理菜单高度和宽度
Private Sub MeasureItem(ByVal hwnd As Long, ByVal lParam As Long)
    Dim TextSize As Size, hdc As Long
    hdc = GetDC(hwnd)
    CopyMemory MeasureInfo, ByVal lParam, Len(MeasureInfo)
    If MeasureInfo.CtlType And ODT_MENU Then
        MeasureInfo.itemWidth = lstrlen(MyItemInfo(MeasureInfo.itemID).itemText) * (GetSystemMetrics(SM_CYMENU) / 2.5) + BarWidth
        If MyItemInfo(MeasureInfo.itemID).itemType <> MIT_SEPARATOR Then
            MeasureInfo.itemHeight = GetSystemMetrics(SM_CYMENU)
        Else
            MeasureInfo.itemHeight = 6
        End If
    End If
    CopyMemory ByVal lParam, MeasureInfo, Len(MeasureInfo)
    ReleaseDC hwnd, hdc
End Sub

' 绘制菜单项
Private Sub DrawItem(ByVal lParam As Long)
    Dim hPen As Long, hBrush As Long
    Dim itemRect As RECT, barRect As RECT, iconRect As RECT, textRect As RECT
    Dim i As Long
    CopyMemory DrawInfo, ByVal lParam, Len(DrawInfo)
    If DrawInfo.CtlType = ODT_MENU Then
        SetBkMode DrawInfo.hdc, TRANSPARENT
       
        ' 初始化菜单项矩形, 图标矩形, 文字矩形
        itemRect = DrawInfo.rcItem
        iconRect = DrawInfo.rcItem
        textRect = DrawInfo.rcItem
       
        ' 设置菜单附加条矩形
        With barRect
            .Left = 0
            .Top = 0
            .Right = BarWidth - 1
            For i = 0 To GetMenuItemCount(hMenu) - 1
                If MyItemInfo(i).itemType = MIT_SEPARATOR Then
                    .Bottom = .Bottom + 6
                Else
                    .Bottom = .Bottom + MeasureInfo.itemHeight
                End If
            Next i
            .Bottom = .Bottom - 1
        End With
       
        ' 设置图标矩形, 文字矩形
        If BarStyle <> LBS_NONE Then iconRect.Left = barRect.Right + 2
        iconRect.Right = iconRect.Left + 20
        textRect.Left = iconRect.Right + 3
       
        With DrawInfo
       
            ' 画菜单背景
            itemRect.Left = barRect.Right
            hBrush = CreateSolidBrush(BkColor)
            FillRect .hdc, itemRect, hBrush
            DeleteObject hBrush

       
            ' 画菜单左边的附加条
            Dim RedArea As Long, GreenArea As Long, BlueArea As Long
            Dim red As Long, green As Long, blue As Long
            Select Case BarStyle
                Case LBS_NONE                                           ' 无附加条

                Case LBS_SOLIDCOLOR                                     ' 实色填充

                    hBrush = CreateSolidBrush(BarStartColor)
                    FillRect .hdc, barRect, hBrush
                    DeleteObject hBrush

                Case LBS_HORIZONTALCOLOR                                ' 水平过渡色

                    BlueArea = Int(BarEndColor / &H10000) - Int(BarStartColor / &H10000)
                    GreenArea = (Int(BarEndColor / &H100) And &HFF) - (Int(BarStartColor / &H100) And &HFF)
                    RedArea = (BarEndColor And &HFF) - (BarStartColor And &HFF)

                    For i = 0 To BarWidth - 1
                        red = Int(BarStartColor And &HFF) + Int(i / BarWidth * RedArea)
                        green = (Int(BarStartColor / &H100) And &HFF) + Int(i / BarWidth * GreenArea)
                        blue = Int(BarStartColor / &H10000) + Int(i / BarWidth * BlueArea)
                        hPen = CreatePen(PS_SOLID, 1, RGB(red, green, blue))
                        Call SelectObject(.hdc, hPen)
                        Call MoveToEx(.hdc, i, 0, 0)
                        Call LineTo(.hdc, i, barRect.Bottom)
                        Call DeleteObject(hPen)
                    Next i

                Case LBS_VERTICALCOLOR                                  ' 垂直过渡色

                    BlueArea = Int(BarEndColor / &H10000) - Int(BarStartColor / &H10000)
                    GreenArea = (Int(BarEndColor / &H100) And &HFF) - (Int(BarStartColor / &H100) And &HFF)
                    RedArea = (BarEndColor And &HFF) - (BarStartColor And &HFF)

                    For i = 0 To barRect.Bottom
                        red = Int(BarStartColor And &HFF) + Int(i / (barRect.Bottom + 1) * RedArea)
                        green = (Int(BarStartColor / &H100) And &HFF) + Int(i / (barRect.Bottom + 1) * GreenArea)
                        blue = Int(BarStartColor / &H10000) + Int(i / (barRect.Bottom + 1) * BlueArea)
                        hPen = CreatePen(PS_SOLID, 1, RGB(red, green, blue))
                        Call SelectObject(.hdc, hPen)
                        Call MoveToEx(.hdc, 0, i, 0)
                        Call LineTo(.hdc, barRect.Right, i)
                        Call DeleteObject(hPen)
                    Next i

                Case LBS_IMAGE                                          ' 图像

                    If BarImage.Handle <> 0 Then
                        Dim barhDC As Long
                        barhDC = CreateCompatibleDC(GetDC(0))
                        SelectObject barhDC, BarImage.Handle
                        BitBlt .hdc, 0, 0, BarWidth, barRect.Bottom - barRect.Top + 1, barhDC, 0, 0, vbSrcCopy
                        DeleteDC barhDC
                    End If

            End Select
           
           
            ' 画菜单项
            If MyItemInfo(.itemID).itemType = MIT_SEPARATOR Then
                ' 画菜单分隔条(MIT_SEPARATOR)
                If MyItemInfo(.itemID).itemType = MIT_SEPARATOR Then
                    itemRect.Top = itemRect.Top + 2
                    itemRect.Bottom = itemRect.Top + 1
                    itemRect.Left = barRect.Right + 5
                    Select Case SepStyle
                        Case MSS_NONE                                       ' 无分隔条
                       
                        Case MSS_DEFAULT                                    ' 默认样式
                            DrawEdge .hdc, itemRect, EDGE_ETCHED, BF_TOP
                        Case Else                                           ' 其它
                            hPen = CreatePen(SepStyle, 0, SepColor)
                            hBrush = CreateSolidBrush(BkColor)
                            SelectObject .hdc, hPen
                            SelectObject .hdc, hBrush
                            Rectangle .hdc, itemRect.Left, itemRect.Top, itemRect.Right, itemRect.Bottom
                            DeleteObject hPen
                            DeleteObject hBrush
                    End Select
                End If
            Else
                If Not CBool(MyItemInfo(.itemID).itemState And MIS_DISABLED) Then   ' 当菜单项可用时
                    If .itemState And ODS_SELECTED Then                         ' 当鼠标移动到菜单项时
                   
                        ' 设置菜单项高亮范围
                        If SelectScope And ISS_ICON_TEXT Then
                            itemRect.Left = iconRect.Left
                        ElseIf SelectScope And ISS_TEXT Then
                            itemRect.Left = textRect.Left - 2
                        Else
                            itemRect.Left = .rcItem.Left
                        End If
                       
                       
                        ' 处理菜单项无图标或为CHECKBOX时的情况
                        If (MyItemInfo(.itemID).itemType = MIT_CHECKBOX Or MyItemInfo(.itemID).itemIcon = 0) And SelectScope <> ISS_LEFTBAR_ICON_TEXT Then
                            itemRect.Left = iconRect.Left
                        End If
                       
                       
                        ' 画菜单项边框
                        Select Case EdgeStyle
                            Case ISES_NONE                                          ' 无边框
                           
                            Case ISES_SUNKEN                                        ' 凹进
                                DrawEdge .hdc, itemRect, BDR_SUNKENOUTER, BF_RECT
                            Case ISES_RAISED                                        ' 凸起
                                DrawEdge .hdc, itemRect, BDR_RAISEDINNER, BF_RECT
                            Case Else                                               ' 其它
                                hPen = CreatePen(EdgeStyle, 0, EdgeColor)
                                hBrush = CreateSolidBrush(BkColor)
                                SelectObject .hdc, hPen
                                SelectObject .hdc, hBrush
                                Rectangle .hdc, itemRect.Left, itemRect.Top, itemRect.Right, itemRect.Bottom
                                DeleteObject hPen
                                DeleteObject hBrush
                        End Select
                       
                       
                        ' 画菜单项背景
                        InflateRect itemRect, -1, -1
                        Select Case FillStyle
                            Case ISFS_NONE                                  ' 无背景
                           
                            Case ISFS_HORIZONTALCOLOR                       ' 水平渐变色
                               
                                BlueArea = Int(FillEndColor / &H10000) - Int(FillStartColor / &H10000)
                                GreenArea = (Int(FillEndColor / &H100) And &HFF) - (Int(FillStartColor / &H100) And &HFF)
                                RedArea = (FillEndColor And &HFF) - (FillStartColor And &HFF)
           
                                For i = itemRect.Left To itemRect.Right - 1
                                    red = Int(FillStartColor And &HFF) + Int((i - itemRect.Left) / (itemRect.Right - itemRect.Left + 1) * RedArea)
                                    green = (Int(FillStartColor / &H100) And &HFF) + Int((i - itemRect.Left) / (itemRect.Right - itemRect.Left + 1) * GreenArea)
                                    blue = Int(FillStartColor / &H10000) + Int((i - itemRect.Left) / (itemRect.Right - itemRect.Left + 1) * BlueArea)
                                    hPen = CreatePen(PS_SOLID, 1, RGB(red, green, blue))
                                    Call SelectObject(.hdc, hPen)
                                    Call MoveToEx(.hdc, i, itemRect.Top, 0)
                                    Call LineTo(.hdc, i, itemRect.Bottom)
                                    Call DeleteObject(hPen)
                                Next i
                               
                            Case ISFS_VERTICALCOLOR                         ' 垂直渐变色
                               
                                BlueArea = Int(FillEndColor / &H10000) - Int(FillStartColor / &H10000)
                                GreenArea = (Int(FillEndColor / &H100) And &HFF) - (Int(FillStartColor / &H100) And &HFF)
                                RedArea = (FillEndColor And &HFF) - (FillStartColor And &HFF)
                               
                                For i = itemRect.Top To itemRect.Bottom - 1
                                    red = Int(FillStartColor And &HFF) + Int((i - itemRect.Top) / (itemRect.Bottom - itemRect.Top + 1) * RedArea)
                                    green = (Int(FillStartColor / &H100) And &HFF) + Int((i - itemRect.Top) / (itemRect.Bottom - itemRect.Top + 1) * GreenArea)
                                    blue = Int(FillStartColor / &H10000) + Int((i - itemRect.Top) / (itemRect.Bottom - itemRect.Top + 1) * BlueArea)
                                    hPen = CreatePen(PS_SOLID, 1, RGB(red, green, blue))
                                    Call SelectObject(.hdc, hPen)
                                    Call MoveToEx(.hdc, itemRect.Left, i, 0)
                                    Call LineTo(.hdc, itemRect.Right, i)
                                    Call DeleteObject(hPen)
                                Next i
                               
                            Case ISFS_SOLIDCOLOR                            ' 实色填充
                               
                                hPen = CreatePen(PS_SOLID, 0, FillStartColor)
                                hBrush = CreateSolidBrush(FillStartColor)
                                SelectObject .hdc, hPen
                                SelectObject .hdc, hBrush
                                Rectangle .hdc, itemRect.Left, itemRect.Top, itemRect.Right, itemRect.Bottom
                                DeleteObject hPen
                                DeleteObject hBrush
                       
                        End Select
                       
                       
                        ' 画菜单项文字
                        SetTextColor .hdc, TextSelectColor
                        DrawText .hdc, MyItemInfo(.itemID).itemText, -1, textRect, DT_SINGLELINE Or DT_LEFT Or DT_VCENTER
                       
                       
                        ' 画菜单项图标
                        If MyItemInfo(.itemID).itemType <> MIT_CHECKBOX Then
                            DrawIconEx .hdc, iconRect.Left + 2, iconRect.Top + (iconRect.Bottom - iconRect.Top + 1 - 16) / 2, MyItemInfo(.itemID).itemIcon, 16, 16, 0, 0, DI_NORMAL
                            Select Case IconStyle
                                Case IIS_NONE                                               ' 无效果
                               
                                Case IIS_SUNKEN                                             ' 凹进
                                    If MyItemInfo(.itemID).itemIcon <> 0 Then
                                        DrawEdge .hdc, iconRect, BDR_SUNKENOUTER, BF_RECT
                                    End If
                                Case IIS_RAISED                                             ' 凸起
                                    If MyItemInfo(.itemID).itemIcon <> 0 Then
                                        DrawEdge .hdc, iconRect, BDR_RAISEDINNER, BF_RECT
                                    End If
                                Case IIS_SHADOW                                             ' 阴影
                                    hBrush = CreateSolidBrush(RGB(128, 128, 128))
                                    DrawState .hdc, hBrush, 0, MyItemInfo(.itemID).itemIcon, 0, iconRect.Left + 3, iconRect.Top + (iconRect.Bottom - iconRect.Top + 1 - 16) / 2 + 1, 0, 0, DST_ICON Or DSS_MONO
                                    DeleteObject hBrush
                                    DrawIconEx .hdc, iconRect.Left + 1, iconRect.Top + (iconRect.Bottom - iconRect.Top + 1 - 16) / 2 - 1, MyItemInfo(.itemID).itemIcon, 16, 16, 0, 0, DI_NORMAL
                            End Select
                        Else
                            ' CHECKBOX型菜单项图标效果
                            If MyItemInfo(.itemID).itemState And MIS_CHECKED Then
                                DrawIconEx .hdc, iconRect.Left + 2, iconRect.Top + (iconRect.Bottom - iconRect.Top + 1 - 16) / 2, MyItemInfo(.itemID).itemIcon, 16, 16, 0, 0, DI_NORMAL
                            End If
                        End If
                   
                    Else                                                        ' 当鼠标移开菜单项时
                       
                        ' 画菜单项边框和背景(清除)
                        If BarStyle <> LBS_NONE Then
                            itemRect.Left = barRect.Right + 1
                        Else
                            itemRect.Left = 0
                        End If
                        hBrush = CreateSolidBrush(BkColor)
                        FillRect .hdc, itemRect, hBrush
                        DeleteObject hBrush
                       
                       
                        ' 画菜单项文字
                        SetTextColor .hdc, TextEnabledColor
                        DrawText .hdc, MyItemInfo(.itemID).itemText, -1, textRect, DT_SINGLELINE Or DT_LEFT Or DT_VCENTER
                       
                       
                        ' 画菜单项图标
                        If MyItemInfo(.itemID).itemType <> MIT_CHECKBOX Then
                            DrawIconEx .hdc, iconRect.Left + 2, iconRect.Top + (iconRect.Bottom - iconRect.Top + 1 - 16) / 2, MyItemInfo(.itemID).itemIcon, 16, 16, 0, 0, DI_NORMAL
                        Else
                            If MyItemInfo(.itemID).itemState And MIS_CHECKED Then
                                DrawIconEx .hdc, iconRect.Left + 2, iconRect.Top + (iconRect.Bottom - iconRect.Top + 1 - 16) / 2, MyItemInfo(.itemID).itemIcon, 16, 16, 0, 0, DI_NORMAL
                            End If
                        End If
                   
                    End If
                Else                                                                 ' 当菜单项不可用时
                   
                    ' 画菜单项文字
                    SetTextColor .hdc, TextDisabledColor
                    DrawText .hdc, MyItemInfo(.itemID).itemText, -1, textRect, DT_SINGLELINE Or DT_LEFT Or DT_VCENTER
                   
                    ' 画菜单项图标
                    If MyItemInfo(.itemID).itemType <> MIT_CHECKBOX Then
                        DrawState .hdc, 0, 0, MyItemInfo(.itemID).itemIcon, 0, iconRect.Left + 2, iconRect.Top + (iconRect.Bottom - iconRect.Top + 1 - 16) / 2, 0, 0, DST_ICON Or DSS_DISABLED
                    Else
                        If MyItemInfo(.itemID).itemState And MIS_CHECKED Then
                            DrawState .hdc, 0, 0, MyItemInfo(.itemID).itemIcon, 0, iconRect.Left + 2, iconRect.Top + (iconRect.Bottom - iconRect.Top + 1 - 16) / 2, 0, 0, DST_ICON Or DSS_DISABLED
                        End If
                    End If
                   
                End If
            End If
           
        End With
    End If
End Sub

' 菜单项事件响应(单击菜单项)
Private Sub MenuItemSelected(ByVal itemID As Long)
    Debug.Print "鼠标单击了:" & MyItemInfo(itemID).itemText
    Select Case MyItemInfo(itemID).itemAlias
        Case "exit"
            Dim frm As Form
            For Each frm In Forms
                Unload frm
            Next
    End Select
End Sub

' 菜单项事件响应(选择菜单项)
Private Sub MenuItemSelecting(ByVal itemID As Long)
    Debug.Print "鼠标移动到:" & MyItemInfo(itemID).itemText
End Sub

 

    到此为止,我们就完成了菜单类的编写,且还包括一个测试窗体。现在,完整的工程里应该包括两个窗体:frmMain和frmMenu;一个标准模块:mMenu;一个类模块:cMenu。按F5编译运行一下,在窗体空白处单击鼠标右键。怎么样,出现弹出式菜单了吗?换个风格再试试。
    看完这个系列的文章后,我想你应该已经对采用物主绘图技术的自绘菜单有了一定的了解,再看看MS Office 2003的菜单,其实也没什么难的嘛。
    该程序在Windows XP、VB6下调试通过。
    源代码下载地址:
http://y365.com/ses518/soft/samplecsdn.zip

(全文完)

 

****************************************************************

* 转载请通知作者并注明出处,谢谢。

* 作者:goodname008(卢培培)

* 邮箱:goodname008@163.com

****************************************************************

 

相关链接:
VB打造超酷个性化菜单(一)
VB打造超酷个性化菜单(二)
VB打造超酷个性化菜单(三)
VB打造超酷个性化菜单(四)
VB打造超酷个性化菜单(五)
VB打造超酷个性化菜单(六)




相关文章

相关软件




月光软件源码下载编程文档电脑教程网站优化网址导航网络文学游戏天地生活休闲写作范文安妮宝贝站内搜索
电脑技术编程开发网络专区谈天说地情感世界游戏元素分类游戏热门游戏体育运动手机专区业余爱好影视沙龙
音乐天地数码广场教育园地科学大观古今纵横谈股论金人文艺术医学保健动漫图酷二手专区地方风情各行各业

月光软件站·版权所有