2013-12-16 74 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'。還有什麼我失蹤? –