【问题标题】:Handle clicks to custom buttons in the System Menu处理对系统菜单中自定义按钮的点击
【发布时间】:2013-12-16 17:47:23
【问题描述】:

我已经设法创建了一个类,它允许我将“关于...”按钮添加到任何形式的系统菜单。这部分工作正常,按钮由表单的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

【问题讨论】:

标签: vb.net events systemmenu


【解决方案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

结束类

【讨论】:

  • 感谢代码,但正如上面 cmets 中提到的,我仍然收到错误 - Type 'SubclassedSystemMenu' is not defined. 谢谢。
  • 啊……错过了。你在哪里得到错误?我刚刚将此添加到现有的 winforms 项目中,我没有错误
  • 我在Private WithEvents sysMenu As SubclassedSystemMenusysMenu = New SubclassedSystemMenu... 上都遇到了错误。正如文章所说,我必须导入System.Windows.Forms.NativeWindow。我还有什么遗漏的吗?
  • 您是否下载了项目并将SubclassedSystemMenu.vb 文件添加到您的项目中?这就是定义SubclassedSystemMenu 的地方。
  • 啊哈,看来我完全失去了阅读能力。我没有在顶部发现下载,因此假设imports 行将确保包含SubclassedSystemMenu!感谢您的帮助,现在一切正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-03
  • 1970-01-01
  • 2010-12-21
  • 1970-01-01
  • 2017-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多