'问题:如何将一个菜单下的菜单项移到另一个菜单里面?'利用菜单编辑器在窗体上建立两个菜单 mnu_1 和 mnu_2,
'然后在 mnu_1 下建立 mnuItem 菜单项,设置其索引为 0'问题:如何将一个菜单下的菜单项移到另一个菜单里面?
'比如:在程序运行时单击 mnu_1 里面的 mnuItem(5) 菜单项时,就将 mnuItem(5) 移进 mnu_2 里面。Private Sub Form_Load()
    '初始化菜单并动态生成菜单项    Dim I As Integer    mnu_1.Caption = "菜单一"
    mnu_2.Caption = "菜单二"
    mnuItem(0).Caption = "菜单项 " & I    '生成十个菜单项
    For I = 1 To 10
        Load mnuItem(I)
        mnuItem(I).Caption = "菜单项 " & I
        mnuItem(I).Visible = True
    Next
End Sub
这里为了省事使用了动态生成的菜单项,其实菜单是否动态不重要,
重要的是 将一个菜单下的菜单项放到另一个菜单里面 ,这个我不会 ,呵呵请高手帮忙实现一下,谢谢大家!!!!!怎样将“菜单一”中的“菜单项 5”移到“菜单二”中去??
程序运行图:

解决方案 »

  1.   

    还在鼓捣菜单呢!这股执著劲儿是不错,不过千万不要囿于 VB 给我们设好的圈子,这样一来好多操作不但费周折,还不一定能实现。
    打开你的 MSDN 6.0 帮助,转到 URL 地址:
    "mk:@MSITStore:E:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/newmenus_7uur.htm"
    这里是 API 菜单函数的总目录,要想实现你所希望的功能,就得靠它们了。
      

  2.   

    注意"E:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98"是 MSDN 安装根目录,视具体环境需要改变。
      

  3.   

    Soyokaze 您好,我前天要获得菜单项句柄就是为了想用SetParent API函数实现上述功能,呵呵,
    您后来告诉我菜单项是没有自己的句柄的,谢谢您,
    我没办法实现了,就又来发帖麻烦你们来了,呵呵
      

  4.   

    亲爱的 Soyokaze,我安装的是 VB6MSDN,不是完全版的,~~~~55555555555~~~~~
    你有没有真正完全版MSDN的下载地址给我啊,谢谢 Soyokaze 了!
      

  5.   

    专门把 MSDN 中有关菜单的这一部分提取出来打包放在了 Mofile 上。
    网址:www.mofile.com
    文件名:Menu.rar
    提取码:7995191007591785
      

  6.   

    谢谢 Soyokaze,我去下来看看,呵呵其它人继续啊 
      

  7.   

    再放一个自画菜单类吧,呵呵,已经改进了 n 长时间和 n 多版本了,逐渐趋于完善。
    支持图标、图片菜单,选中项可以使用圆角矩形带 Alpha 过渡色填充......
    具体的风格可以按自己爱好自定义,这个只定义了两个。
    [img=http://farm4.static.flickr.com/3252/2533865034_3bc5ac068b_o.gif]
    使用上还需要窗口子类化一下,用来处理 WM_MEASUREITEM、WM_DRAWITEM、WM_COMMAND 等菜单消息。
    其实在 http://www.vbaccelerator.com/home/VB/Code/Controls/Menus/Popup_Menu_ActiveX_DLL/article.asp 有一个非常完善的菜单类(已经封装成了控件)。但是代码数千行,分析起来相当费神。你可以先从我这个着手。
    提取码:3943703839668500
      

  8.   

    谢谢 Soyokaze 的热情回复,我去下载看看.楼下的继续!!!!!!!
      

  9.   

    请 Soyokaze 发个如何使用那个类的窗体代码的例子好嘛???不然我实在不知道该怎么创建出来个菜单,谢谢 Soyokaze !
      

  10.   

    要么一咬牙,改用第三方菜单控件。
    要么一切齿,钻到API里钻研一番。
    其实移动菜单项如2楼所说很简单,先删除,再添加。如何添加删除?这里有个动态菜单类你看看。Option Explicit
    Private Declare Function GetLastError Lib "kernel32.dll" () As Long
    ' Exposed Enumeration
    Public Enum mceItemStates
        mceDisabled = 1
        mceGrayed = 2
    End Enum' Property variables
    Private psCaption As String ' Caption of menu item (with the arrow >) if this is submenu
    Private piHwnd As Long ' Handle to Menu' Supporting API code
    Private Const GW_CHILD = 5
    Private Const GW_HWNDNEXT = 2
    Private Const GW_HWNDFIRST = 0
    Private Const MF_BYCOMMAND = &H0&
    Private Const MF_BYPOSITION = &H400
    Private Const MF_CHECKED = &H8&
    Private Const MF_DISABLED = &H2&
    Private Const MF_GRAYED = &H1&
    Private Const MF_MENUBARBREAK = &H20&
    Private Const MF_MENUBREAK = &H40&
    Private Const MF_POPUP = &H10&
    Private Const MF_SEPARATOR = &H800&
    Private Const MF_STRING = &H0&
    Private Const MIIM_ID = &H2
    Private Const MIIM_SUBMENU = &H4
    Private Const MIIM_TYPE = &H10
    Private Const TPM_LEFTALIGN = &H0&
    Private Const TPM_RETURNCMD = &H100&
    Private Const TPM_RIGHTBUTTON = &H2Private Type POINT
        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 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
    Private Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, lpNewItem As String) As Long
    Private Declare Function DestroyMenu Lib "user32" (ByVal hMenu As Long) As Long
    Private Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal uFlags As Long) As Long
    Private Declare Function CreatePopupMenu Lib "user32" () As Long
    Private Declare Function EnableMenuItem Lib "user32" (ByVal hMenu As Long, ByVal wIDEnableItem As Long, ByVal wEnable As Long) As Long
    Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINT) As Long
    Private Declare Function GetDesktopWindow Lib "user32" () As Long
    Private Declare Function GetWindow Lib "user32" (ByVal Hwnd As Long, ByVal wCmd As Long) As Long
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal Hwnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
    Private Declare Function GetWindowRect Lib "user32" (ByVal Hwnd As Long, lpRect As RECT) As Long
    Private Declare Function GetMenuItemInfo Lib "user32" Alias "GetMenuItemInfoA" (ByVal hMenu As Long, ByVal un As Long, ByVal b As Boolean, lpMenuItemInfo As MENUITEMINFO) As Boolean
    Private Declare Function GetFocus Lib "user32" () As Long
    Private Declare Function GetForegroundWindow Lib "user32" () As Long
    Private Declare Function SetMenuDefaultItem Lib "user32" (ByVal hMenu As Long, ByVal uItem As Long, ByVal fByPos As Long) As Long
    Private Declare Function TrackPopupMenuEx Lib "user32" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal X As Long, ByVal Y As Long, ByVal Hwnd As Long, ByVal lptpm As Any) As Long
    Private Declare Function SetMenuItemBitmaps Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal hBitmapUnchecked As Long, ByVal hBitmapChecked As Long) As Long
    Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
    Public Property Let Caption(ByVal sCaption As String)    psCaption = sCaption
       
    End PropertyPublic Property Get Caption() As String    Caption = psCaption
       
    End Property
    Public Sub Remove(ByVal iMenuPosition As Long)
       
        DeleteMenu piHwnd, iMenuPosition, MF_BYPOSITION
       
    End SubPrivate Sub Class_Initialize()
        piHwnd = CreatePopupMenu()
    End SubPrivate Sub Class_Terminate()
        DestroyMenu piHwnd
    End SubPublic Property Get Hwnd() As Long
       
        Hwnd = piHwndEnd PropertyPublic Sub Add(ByVal iMenuID As Long, vMenuItem As Variant, Optional bDefault As Boolean = False, Optional bChecked As Boolean = False, Optional eItemState As mceItemStates, Optional ByVal imgUnchecked As Long = 0, Optional ByVal imgChecked As Long = 0)
       
        ' Check to see if it's a menu item (a string) or a submenu (a class).
        If TypeName(vMenuItem) = "String" Then
           
            If vMenuItem = "-" Then ' Make a seperator
                AppendMenu piHwnd, MF_STRING Or MF_SEPARATOR, iMenuID, ByVal vbNullString
            Else
                AppendMenu piHwnd, MF_STRING Or -bChecked * MF_CHECKED, iMenuID, ByVal vMenuItem
            End If
       
            ' Menu Icons
            If imgChecked = 0 Then imgChecked = imgChecked ' Need a value for both
            SetMenuItemBitmaps piHwnd, iMenuID, MF_BYCOMMAND, imgUnchecked, imgChecked
           
            ' Default item
            If bDefault Then SetMenuDefaultItem piHwnd, iMenuID, 0
           
            ' Disabled (Regular color text)
            If eItemState = mceDisabled Then EnableMenuItem piHwnd, iMenuID, MF_BYCOMMAND Or MF_DISABLED
            ' Disabled (disabled color text)
            If eItemState = mceGrayed Then EnableMenuItem piHwnd, iMenuID, MF_BYCOMMAND Or MF_GRAYED
       
        ' Add a submenu
        ElseIf TypeOf vMenuItem Is mcPopupMenu Then
            Dim oSubmenu As mcPopupMenu: Set oSubmenu = vMenuItem
            AppendMenu piHwnd, MF_STRING Or MF_POPUP, oSubmenu.Hwnd, ByVal oSubmenu.Caption
            Set oSubmenu = Nothing
        End IfEnd SubPublic Function Show(Optional ByVal iFormHwnd As Long = -1, Optional ByVal X As Long = -1, Optional ByVal Y As Long = -1, Optional ByVal iControlHwnd As Long = -1) As Long
    Dim iHwnd As Long, iX As Long, iY As Long
       
        ' If no form is passed, use the current window
        If iFormHwnd = -1 Or iFormHwnd = 0 Then
           
            Dim iDesktopHwnd As Long, iChildHwnd As Long, iCurrentID As Long, iChildID As Long
           
            iDesktopHwnd = GetDesktopWindow()
            iChildHwnd = GetWindow(iDesktopHwnd, GW_CHILD)
            iCurrentID = GetCurrentProcessId()
            Do While iChildHwnd
                GetWindowThreadProcessId iChildHwnd, iChildID
                If iChildID = iCurrentID Then Exit Do ' Snagged
                iChildHwnd = GetWindow(iChildHwnd, GW_HWNDNEXT)
            Loop
           
            If iChildHwnd = 0 Then ' Can't resolve a form handle. Bail out.
                Show = -1
                Exit Function
            End If
            iHwnd = iChildHwnd
        Else
            iHwnd = iFormHwnd
        End If
       
        ' If passed a control handle, left-bottom orient to the control.
        If iControlHwnd <> -1 Then
            Dim rt As RECT
            GetWindowRect iControlHwnd, rt
            iX = rt.Left
            iY = rt.Bottom
        Else
            Dim pt As POINT
            GetCursorPos pt
            If X = -1 Then iX = pt.X Else: iX = X
            If Y = -1 Then iY = pt.Y Else: iY = Y
        End If
        Show = TrackPopupMenuEx(piHwnd, TPM_RETURNCMD Or TPM_RIGHTBUTTON, iX, iY, iHwnd, ByVal 0&)
       
    End Function
      

  11.   

    简单来说,获取需要移动的菜单的MENUITEMINFO,保存下来,再插入到需要的地方.
    需要用到getmenu\getsubmenu\GetMenuItemInfo这几个API来获取对应的MENUITEMINFO
    然后用InsertMenuItem循环插入到需要的地方.再用DeleteMenu或基本等量的API删除原来的即可
      

  12.   

    十三楼 hpygzhx520 的说法看起来挺接近我的要求,还有哪位朋友有更好的方法????
    楼下继续!!!!