2013-12-16 48 views
2

我设法创建了一个类,允许我在任何表单的系统菜单中添加“关于...”按钮。这部分工作正常,该按钮是由表格的load事件添加的,但是如何处理该按钮的点击?谢谢。在系统菜单中处理点击自定义按钮

这里是我如何添加按钮 -

Private Sub mainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 

    {More code....} 
    Dim SysMenu = New SystemMenu(Me) 
    {More code....} 

End Sub 

这里是SystemMenu类 -

Imports System.Windows.Forms 

Public Class SystemMenu 

    Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As IntPtr, ByVal bRevert As Boolean) As IntPtr 
    Private Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As IntPtr, ByVal uFlags As Int32, ByVal uIDNewItem As IntPtr, ByVal lpNewItem As String) As Boolean 
    Private Const MF_STRING As Integer = &H0 
    Private Const MF_SEPARATOR As Integer = &H800 

    Private m_hSysMenu As IntPtr 
    Private Property hSysMenu() As IntPtr 
     Get 
      Return Me.m_hSysMenu 
     End Get 
     Set(ByVal Value As IntPtr) 
      Me.m_hSysMenu = Value 
     End Set 
    End Property 

    '** 
    ' Constructor 
    '* 
    Protected Friend Sub New(ByRef Form As Form) 
     Me.hSysMenu = GetSystemMenu(Form.Handle, False) 
     AddAbout(Form) 
    End Sub 

    '** 
    ' Add an 'About' button to the system menu of the given form 
    '* 
    Private Sub AddAbout(ByRef Form As Form) 
     AppendMenu(Me.hSysMenu, MF_SEPARATOR, 1000, Nothing) 
     AppendMenu(Me.hSysMenu, MF_STRING, 1001, "About...") 
    End Sub 

End Class 
+0

http://www.codeproject.com/文章/ 6122/Subclassed-System-Menu – Jeff

+0

我发现早些时候。即使包含'Imports System.Windows.Forms.NativeWindow',我仍然得到'Type'SubclassedSystemMenu'未定义的错误。“谢谢。 –

回答

1

Check this out。该SubclassedSystemMenu.vb文件添加到项目,并添加到您的主要形式

Private WithEvents sysMenu As SubclassedSystemMenu 

Protected Overrides Sub OnLoad(e As System.EventArgs) 
    sysMenu = New SubclassedSystemMenu(Me.Handle.ToInt32, "&About...") 
End Sub 

然后订阅其LaunchDialog事件,并打开窗体

Private Sub sysMenu_LaunchDialog() Handles sysMenu.LaunchDialog 
    Dim f as New frmAbout 
    f.ShowDialog(Me) 
End Sub 

这里是SubclassedSystemMenu

Public Class SubclassedSystemMenu 
Inherits System.Windows.Forms.NativeWindow 
Implements IDisposable 

Private Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Int32, _ 
                ByVal bRevert As Boolean) As Int32 

Private Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Int32, _ 
                     ByVal wFlags As Int32, _ 
                     ByVal wIDNewItem As Int32, _ 
                     ByVal lpNewItem As String) As Int32 

Private Const MF_STRING As Int32 = &H0  ' Menu string format 
Private Const MF_SEPARATOR As Int32 = &H800 ' Menu separator 
Private Const WM_SYSCOMMAND As Int32 = &H112 ' System menu 
Private Const ID_ABOUT As Int32 = 1000  ' Our ID for the new menu item 

Private mintSystemMenu As Int32 = 0     ' Parent system menu handle 
Private mintHandle As Int32 = 0      ' Local parent window handle 
Private mstrMenuItemText As String = String.Empty ' New menu item text 

Public Event LaunchDialog() 

Public Sub New(ByVal intWindowHandle As Int32, _ 
       ByVal strMenuItemText As String) 

    Me.AssignHandle(New IntPtr(intWindowHandle)) 

    mintHandle = intWindowHandle 
    mstrMenuItemText = strMenuItemText 

    ' Retrieve the system menu handle 
    mintSystemMenu = GetSystemMenu(mintHandle, 0) 

    If AddNewSystemMenuItem() = False Then 
     Throw New Exception("Unable to add new system menu items") 
    End If 

End Sub 

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) 

    Select Case m.Msg 
     Case WM_SYSCOMMAND 

      MyBase.WndProc(m) 

      If m.WParam.ToInt32 = ID_ABOUT Then 
       If mintSystemMenu <> 0 Then 
        RaiseEvent LaunchDialog() 
       End If 
      End If 

     Case Else 
      MyBase.WndProc(m) 
    End Select 

End Sub 

Public Sub Dispose() Implements System.IDisposable.Dispose 

    If Not Me.Handle.Equals(IntPtr.Zero) Then 
     Me.ReleaseHandle() 
    End If 

End Sub 

Private Function AddNewSystemMenuItem() As Boolean 
    Try 
     ' Append the extra system menu items 
     Return AppendToSystemMenu(mintSystemMenu, mstrMenuItemText) 

    Catch ex As Exception 
     Return False 
    End Try 
End Function 

Private Function AppendToSystemMenu(ByVal intHandle As Int32, _ 
            ByVal strText As String) As Boolean 

    Try 
     ' Add the seperator menu item 
     Dim intRet As Int32 = AppendMenu(intHandle, MF_SEPARATOR, 0, String.Empty) 

     ' Add the About... menu item 
     intRet = AppendMenu(intHandle, MF_STRING, ID_ABOUT, strText) 

     If intRet = 1 Then 
      Return True 
     Else 
      Return False 
     End If 

    Catch ex As Exception 
     Return False 
    End Try 
End Function 

结束类别

+0

感谢您的代码,但正如上面的评论中提到的,我仍然收到错误 - 类型'SubclassedSystemMenu'没有定义.'谢谢。 –

+0

啊......错过了。你在哪里得到错误?我只是将此添加到现有的winforms项目中我没有任何错误 – Jeff

+0

我在'Private WithEvents sysMenu As SubclassedSystemMenu'和'sysMenu = New SubclassedSystemMenu ...'上都出现错误。正如文章所说我必须导入'System.Windows.Forms.NativeWindow'。还有什么我失踪? –