以前 VB 6.0 我要调一堆 API 感觉好过瘾 呵呵 现在找不到这种感觉了 哈!记得vb 6 的 时候生气用Win32写了个Clock 掉了上百个 API 连VB 6 的窗体都没用, 那个叫过瘾 一切都在控制中的感觉真好。看来我还是适合用 MASM Win32 的。哈哈 废话 到此结束。动态添加菜单在 .net 中很容易的。
首先建立一个XML 文件用来存储 菜单信息 (本例使用 DataHelper.xml) <?xml version="1.0" encoding="utf-8" ?> <DataHelper> <Menu> <IsSeparator>0</IsSeparator> <IsTopMenu>0</IsTopMenu> <TopMenuItemIndex>2</TopMenuItemIndex> <SubMenuItemIndex></SubMenuItemIndex> <MenuID>1</MenuID> <ParentID>0</ParentID> <Text>基本数据库(&B)...</Text> <Image></Image> <ToolTipText></ToolTipText> <Visible>True</Visible> <Name>DataConvert</Name> <ShortcutKeys></ShortcutKeys> </Menu> <Menu> <IsSeparator>1</IsSeparator> <IsTopMenu>0</IsTopMenu> <TopMenuItemIndex>2</TopMenuItemIndex> <SubMenuItemIndex></SubMenuItemIndex> <MenuID>2</MenuID> <ParentID>0</ParentID> </Menu>
<Menu> <IsSeparator>0</IsSeparator> <IsTopMenu>0</IsTopMenu> <TopMenuItemIndex>2</TopMenuItemIndex> <SubMenuItemIndex></SubMenuItemIndex> <MenuID>2</MenuID> <ParentID>0</ParentID> <Text>计生系统(&J)...</Text> <Image></Image> <ToolTipText></ToolTipText> <Visible></Visible> <Name>DataConvert</Name> <ShortcutKeys>131140</ShortcutKeys> </Menu>
<Menu> <IsSeparator>1</IsSeparator> <IsTopMenu>0</IsTopMenu> <TopMenuItemIndex>2</TopMenuItemIndex> <SubMenuItemIndex></SubMenuItemIndex> <MenuID>2</MenuID> <ParentID>0</ParentID> </Menu>
<Menu> <IsSeparator>0</IsSeparator> <IsTopMenu>0</IsTopMenu> <TopMenuItemIndex>2</TopMenuItemIndex> <SubMenuItemIndex></SubMenuItemIndex> <MenuID>3</MenuID> <ParentID>0</ParentID> <Text>党员系统(&D)...</Text> <Image></Image> <ToolTipText></ToolTipText> <Visible></Visible> <Name>DataConvert</Name> <ShortcutKeys></ShortcutKeys> </Menu>
<Menu> <IsSeparator>1</IsSeparator> <IsTopMenu>0</IsTopMenu> <TopMenuItemIndex>2</TopMenuItemIndex> <SubMenuItemIndex></SubMenuItemIndex> <MenuID>2</MenuID> <ParentID>0</ParentID> </Menu>
<Menu> <IsSeparator>0</IsSeparator> <IsTopMenu>0</IsTopMenu> <TopMenuItemIndex>2</TopMenuItemIndex> <SubMenuItemIndex></SubMenuItemIndex> <MenuID>4</MenuID> <ParentID>0</ParentID> <Text>民政系统(&M)...</Text> <Image></Image> <ToolTipText></ToolTipText> <Visible></Visible> <Name>DataConvert</Name> <ShortcutKeys></ShortcutKeys> </Menu> </DataHelper>
好了第一步开始,读取XML文件 我们使用 DataSet 来干这活,不过我是在 DataHerlper.Common 工程来干这事的。哇 分层阿! 这个是个结构 我用的 看取那个Table
Imports System.Drawing Imports System.Windows.Forms Namespace DataHelper Namespace DataHelper.Common Public Enum DataHelperConfigTableName Enum DataHelperConfigTableName DropDownMenu = 0 Plugins = 1 End Enum End Namespace Imports System.Data Imports DataHelper.Common.Caching Imports System.Windows.Forms Namespace DataHelper Namespace DataHelper.Common Public Class SharedClass Class SharedClass Public Shared Function GetDataHelperConfig() Function GetDataHelperConfig( Optional ByVal TableName As DataHelperConfigTableName = DataHelperConfigTableName.DropDownMenu) As DataTable Dim strDataHelperConfigFile As String Dim ds As New DataSet Dim dt As New DataTable strDataHelperConfigFile = Application.StartupPath & " ConfigDataHelper.xml " ' Application.StartupPath ds = DataCache.GetCache( " DataHelperConfig " ) If ds Is Nothing Then Dim xmlReader As XmlTextReader = New XmlTextReader(strDataHelperConfigFile) ds = New DataSet ds.ReadXml(xmlReader) dt = ds.Tables(TableName) DataCache.Insert( " DataHelperConfig " , ds, DataCache.CreateFileCacheDependency(strDataHelperConfigFile)) Else dt = ds.Tables(TableName) End If Return dt End Function End Class End Namespace 我们得到菜单信息了接下来就要动态添加菜单了 这又是一个工程(DataHelper.UserInterface) 分层吗' ********************************************************************************************************** ' Programmer By Shadow (QQ:33512603) ' User Interface MainMenu Class ' The MainMenu class create menu for localappliction ' Corpright(C) 2006 Jiang Jian '********************************************************************************************************** ' 程序设计:江建 '********************************************************************************************************** Imports System.IO Imports System.Windows.Forms Imports DataHelper.Common Imports DataHelper.PluginsInterface Namespace DataHelper Namespace DataHelper.UserInterface Public Class MainMenu Class MainMenu Private MenuClick As New MainMenuClick Public Methods #Region "Public Methods" ' ********************************************************************************************************** ' 功 能:动态创建菜单 ' 参 数:MenuScripItem - 一个MenuStrip对象 ' 返回值:NULL ' ********************************************************************************************************** Public Sub CreateMenu() Sub CreateMenu( ByVal MenuScripItem As MenuStrip) Dim IsTopMenu As Boolean Dim IsSeparator As Boolean = False Dim TopMenuItemIndex As Integer = 0 Dim SubMenuItemIndex As Integer = - 1 Dim dt As DataTable = SharedClass.GetDataHelperConfig(DataHelperConfigTableName.DropDownMenu) Dim dr As DataRow For Each dr In dt.Rows If IsNumeric (dr( " IsSeparator " )) Then IsSeparator = dr( " IsSeparator " ) End If Dim MenuItem As ToolStripMenuItem = New ToolStripMenuItem() ' 创建菜单项 AddHandler MenuItem.Click, New EventHandler( AddressOf MenuClick.MainMenu_Click) MenuItem.Text = dr( " Text " ).ToString() MenuItem.ToolTipText = dr( " ToolTipText " ).ToString MenuItem.Name = dr( " Name " ).ToString If File.Exists(dr( " Image " ).ToString) Then MenuItem.Image = Image.FromFile(dr( " Image " )) End If If dr( " Visible " ).ToString.Length > 0 Then MenuItem.Visible = Boolean .Parse(dr( " Visible " )) End If If IsNumeric (dr( " ShortcutKeys " )) Then MenuItem.ShortcutKeys = Integer .Parse(dr( " ShortcutKeys " )) End If MenuItem.ShowShortcutKeys = True If IsNumeric (dr( " IsTopMenu " )) Then IsTopMenu = CBool (dr( " IsTopMenu " )) Else IsTopMenu = False End If If IsNumeric (dr( " TopMenuItemIndex " )) Then TopMenuItemIndex = dr( " TopMenuItemIndex " ) End If If IsNumeric (dr( " SubMenuItemIndex " )) Then SubMenuItemIndex = dr( " SubMenuItemIndex " ) End If If dr( " ParentID " ) = 0 Then If IsTopMenu Then If TopMenuItemIndex < 6 Then TopMenuItemIndex = 6 End If MenuScripItem.Items.Insert(TopMenuItemIndex, MenuItem) Else Dim Sep As New ToolStripSeparator If SubMenuItemIndex = - 1 Then If IsSeparator Then CType (MenuScripItem.Items(TopMenuItemIndex), ToolStripMenuItem).DropDownItems.Add(Sep) Else CType (MenuScripItem.Items(TopMenuItemIndex), ToolStripMenuItem).DropDownItems.Add(MenuItem) End If Else If IsSeparator Then CType (MenuScripItem.Items(TopMenuItemIndex), ToolStripMenuItem).DropDownItems.Insert(SubMenuItemIndex, Sep) Else CType (MenuScripItem.Items(TopMenuItemIndex), ToolStripMenuItem).DropDownItems.Insert(SubMenuItemIndex, MenuItem) End If End If End If CreateSubMenu(MenuItem, Convert.ToInt32(dr(" MenuID " )), dt) End If Next End Sub #End Region Private Methods #Region "Private Methods" ' ********************************************************************************************************** ' 功 能:动态创建子菜单 ' 参 数:MenuItem - 一个ToolStripMenuItem对象,MenuID - 父菜单的 MenuID,dt - 一个 DataTable 对象 ' 返回值:NULL ' ********************************************************************************************************** Private Sub CreateSubMenu() Sub CreateSubMenu( ByRef MenuItem As ToolStripMenuItem, ByVal MenuID As Integer , ByVal dt As DataTable) Dim dv As DataView = New DataView(dt) dv.RowFilter = " ParentID= " + MenuID.ToString() ' 当前父菜单下在所有子菜单 For I As Integer = 0 To dv.Count - 1 Dim SubMenuItem As ToolStripMenuItem = New ToolStripMenuItem() ' 创建子菜单项 SubMenuItem.Text = dv(I)( " Text " ).ToString() SubMenuItem.ToolTipText = dv(I)( " ToolTipText " ) SubMenuItem.Name = dv(I)( " Name " ) If File.Exists(dv(I)( " Image " )) Then SubMenuItem.Image = Image.FromFile(dv(I)( " Image " )) End If If dv(I)( " Visible " ).ToString.Length > 0 Then SubMenuItem.Visible = Boolean .Parse(dv(I)( " Visible " )) End If If IsNumeric (dv(I)( " ShortcutKeys " )) Then SubMenuItem.ShortcutKeys = Integer .Parse(dv(I)( " ShortcutKeys " )) End If MenuItem.DropDownItems.Add(SubMenuItem) CreateSubMenu(SubMenuItem, Convert.ToInt32(dv(I)(" MenuID " )), dt) ' 递归调用 Next End Sub #End Region End Class End Namespace ' ********************************************************************************************************** ' Programmer By Shadow (QQ:33512603) ' User Interface MainMenuClick Class ' The MainMenuClick class response menu click event ' Corpright(C) 2006 Jiang Jian '********************************************************************************************************** ' 程序设计:江建 '********************************************************************************************************** Imports System.Diagnostics Imports System.Windows.Forms Namespace DataHelper Namespace DataHelper.UserInterface Public Class MainMenuClick Class MainMenuClick Private Declare Function SetParent() Function SetParent Lib " user32 " Alias " SetParent " ( ByVal hWndChild As Integer , ByVal hWndNewParent As Integer ) As Integer Private Declare Function SetWindowPos() Function SetWindowPos Lib " user32 " ( ByRef hwnd As Integer , ByRef hWndInsertAfter As Integer , ByVal x As Integer , ByVal y As Integer , ByVal cx As Integer , ByVal cy As Integer , ByVal wFlags As Integer ) As Integer Private Const SWP_NOSIZE = & H1 Private Const SWP_NOMOVE = & H2 Private DataConvert As New Process Public Methods #Region "Public Methods" ' ********************************************************************************************************** ' 功 能:为动态创建的菜单提供事件相应 ' 参 数:sender - 引发事件的一个对象 e - EventArgs 是包含事件数据的类的基类 ' 返回值:NULL ' ********************************************************************************************************** Public Sub MainMenu_Click() Sub MainMenu_Click( ByVal sender As Object , ByVal e As System.EventArgs) Select Case CType (sender, ToolStripMenuItem).Name Case Is = " DataConvert " DataConvert.StartInfo.FileName = (Application.StartupPath & " PluginsDTSWIZdtswiz.exe " ) DataConvert.StartInfo.WindowStyle = ProcessWindowStyle.Minimized DataConvert.Start() DataConvert.WaitForExit( 1000 ) SetParent(DataConvert.MainWindowHandle, Process.GetCurrentProcess.MainWindowHandle) End Select End Sub #End Region Overrides Methods #Region "Overrides Methods" ' ********************************************************************************************************** ' 功 能:垃圾回收 ' 参 数:NULL ' 返回值:NULL ' ********************************************************************************************************** Protected Overrides Sub Finalize() Sub Finalize() MyBase .Finalize() If Not DataConvert.HasExited Then DataConvert.Refresh() DataConvert.CloseMainWindow() DataConvert.Kill() End If End Sub #End Region End Class End Namespace
最后是测试 哈哈 终于完了 在你的主窗体下 加入一个 MenuScript 控件 名称为 MainMenu 这次测试未添加 顶级菜单 如果要添加顶级菜单 请修改XML文件 IsTopMenu 为1
Private Sub frmMain_Load() Sub frmMain_Load( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase .Load Dim test As New MainMenu test.CreateMenu( Me .MainMenu) End Sub