无边界Windows窗体上的Windows默认上下文菜单将自定义选项替换为自定义选项

时间:2016-08-10 09:34:20

标签: vb.net winforms contextmenu default user32

我创建了一个无边框Windows窗体并添加了默认系统标头的功能:

动:

Private m_blnMouseDown As Boolean = False
  Private m_utdMouseOffset As Point

  ' Left mouse button pressed
  Private Sub BorderlessMove_MouseDown(sender As Object, e As MouseEventArgs) Handles tlpHeader.MouseDown
    If e.Button = MouseButtons.Left Then
      ' Get the new position
      Dim mouseRelative As Point = Me.PointToClient(Cursor.Position)
      m_utdMouseOffset = New Point(-mouseRelative.X, -mouseRelative.Y)
      ' Set that left button is pressed
      m_blnMouseDown = True
    End If
  End Sub

  ' MouseMove used to check if mouse cursor is moving
  Private Sub BorderlessMove_MouseMove(sender As Object, e As MouseEventArgs) Handles tlpHeader.MouseMove
    If m_blnMouseDown Then
      Dim mousePos As Point = Control.MousePosition
      ' Get the new form position
      mousePos.Offset(m_utdMouseOffset.X, m_utdMouseOffset.Y)
      Me.Location = mousePos
    End If
  End Sub

  ' Left mouse button released, form should stop moving
  Private Sub BorderlessMove_MouseUp(sender As Object, e As MouseEventArgs) Handles tlpHeader.MouseUp
    If e.Button = MouseButtons.Left Then
      m_blnMouseDown = False
    End If
  End Sub

调整大小:

Private Enum ResizeState
    North
    NE
    East
    SE
    South
    SW
    West
    NW
    None
  End Enum

  Private m_utdResizeState As ResizeState = ResizeState.None

  Private Const GRIP_SIZE As Int32 = 5

  Private Sub BorderlessResize_FormLoad(sender As Object, e As EventArgs) Handles Me.Load

    Const DGRIP_SIZE As Int32 = GRIP_SIZE * 2

    Dim Sizes As New Dictionary(Of String, Size)
    Sizes.Add("Horizontal", New Size(Me.Width - DGRIP_SIZE * 2, GRIP_SIZE))
    Sizes.Add("Vertical", New Size(GRIP_SIZE, Me.Height - DGRIP_SIZE * 2))
    Sizes.Add("HEdge", New Size(DGRIP_SIZE, GRIP_SIZE))
    Sizes.Add("VEdge", New Size(GRIP_SIZE, DGRIP_SIZE))

    GenerateTransparentPanel("pnlResizeNorth", ResizeState.North, Sizes.Item("Horizontal"), New Point(DGRIP_SIZE, 0), (AnchorStyles.Top Or AnchorStyles.Right) Or AnchorStyles.Left)
    GenerateTransparentPanel("pnlResizeNE_H", ResizeState.NE, Sizes.Item("HEdge"), New Point(Me.Width - DGRIP_SIZE, 0), AnchorStyles.Top Or AnchorStyles.Right)
    GenerateTransparentPanel("pnlResizeNE_V", ResizeState.NE, Sizes.Item("VEdge"), New Point(Me.Width - GRIP_SIZE, 0), AnchorStyles.Top Or AnchorStyles.Right)
    GenerateTransparentPanel("pnlResizeEast", ResizeState.East, Sizes.Item("Vertical"), New Point(Me.Width - GRIP_SIZE, DGRIP_SIZE), (AnchorStyles.Top Or AnchorStyles.Right) Or AnchorStyles.Bottom)
    GenerateTransparentPanel("pnlResizeSE_H", ResizeState.SE, Sizes.Item("HEdge"), New Point(Me.Width - DGRIP_SIZE, Me.Height - GRIP_SIZE), AnchorStyles.Right Or AnchorStyles.Bottom)
    GenerateTransparentPanel("pnlResizeSE_V", ResizeState.SE, Sizes.Item("VEdge"), New Point(Me.Width - GRIP_SIZE, Me.Height - DGRIP_SIZE), AnchorStyles.Right Or AnchorStyles.Bottom)
    GenerateTransparentPanel("pnlResizeSouth", ResizeState.South, Sizes.Item("Horizontal"), New Point(DGRIP_SIZE, Me.Height - GRIP_SIZE), (AnchorStyles.Bottom Or AnchorStyles.Right) Or AnchorStyles.Left)
    GenerateTransparentPanel("pnlResizeSW_H", ResizeState.SW, Sizes.Item("HEdge"), New Point(0, Me.Height - GRIP_SIZE), AnchorStyles.Bottom Or AnchorStyles.Left)
    GenerateTransparentPanel("pnlResizeSW_V", ResizeState.SW, Sizes.Item("VEdge"), New Point(0, Me.Height - DGRIP_SIZE), AnchorStyles.Bottom Or AnchorStyles.Left)
    GenerateTransparentPanel("pnlResizeWest", ResizeState.West, Sizes.Item("Vertical"), New Point(0, DGRIP_SIZE), (AnchorStyles.Top Or AnchorStyles.Left) Or AnchorStyles.Bottom)
    GenerateTransparentPanel("pnlResizeNW_H", ResizeState.NW, Sizes.Item("HEdge"), New Point(0, 0), AnchorStyles.Top Or AnchorStyles.Left)
    GenerateTransparentPanel("pnlResizeNW_V", ResizeState.NW, Sizes.Item("VEdge"), New Point(0, 0), AnchorStyles.Top Or AnchorStyles.Left)

  End Sub

  Private Sub GenerateTransparentPanel(name As String, tag As ResizeState, size As Size, location As Point, anchors As AnchorStyles)
    Dim panel As TransparentPanel = New TransparentPanel()
    panel.Anchor = anchors
    panel.Location = location
    panel.Name = name
    panel.Size = size
    panel.Tag = tag
    AddHandler panel.MouseDown, AddressOf BorderlessResize_MouseDown
    AddHandler panel.MouseMove, AddressOf BorderlessResize_MouseMove
    AddHandler panel.MouseUp, AddressOf BorderlessResize_MouseUp
    AddHandler panel.MouseEnter, AddressOf BorderlessResize_MouseEnter
    AddHandler panel.MouseLeave, AddressOf BorderlessResize_MouseLeave
    Me.Controls.Add(panel)
    panel.BringToFront()
  End Sub

  Private Sub BorderlessResize_MouseDown(sender As Object, e As MouseEventArgs)
    Debug.Write("MouseDown")
    If e.Button = MouseButtons.Left Then
      m_utdResizeState = DirectCast(sender, Control).Tag
    End If
  End Sub

  Protected Sub BorderlessResize_MouseMove(sender As Object, e As MouseEventArgs)
    If m_utdResizeState <> ResizeState.None Then
      BorderlessResize_ResizeForm(m_utdResizeState)
      Refresh()
    End If
  End Sub
  Protected Sub BorderlessResize_MouseEnter(sender As Object, e As EventArgs)
    BorderlessResize_UpdateCursor(DirectCast(sender, Control).Tag)
  End Sub
  Protected Sub BorderlessResize_MouseLeave(sender As Object, e As EventArgs)
    Me.Cursor = Cursors.Default
  End Sub

  Private Sub BorderlessResize_UpdateCursor(state As ResizeState)
    If (state = ResizeState.East OrElse state = ResizeState.West) Then
      Me.Cursor = Cursors.SizeWE
    ElseIf (state = ResizeState.North OrElse state = ResizeState.South) Then
      Me.Cursor = Cursors.SizeNS
    ElseIf (state = ResizeState.SE OrElse state = ResizeState.NW) Then
      Me.Cursor = Cursors.SizeNWSE
    ElseIf (state = ResizeState.NE OrElse state = ResizeState.SW) Then
      Me.Cursor = Cursors.SizeNESW
    Else Me.Cursor = Cursors.Default
    End If
  End Sub

  Private Sub BorderlessResize_ResizeForm(ResizeVal As ResizeState)
    Dim Location As Point = New Point(Cursor.Position.X - Me.Left, Cursor.Position.Y - Me.Top)
    Select Case ResizeVal
      Case ResizeState.North
        If Me.Height - Location.Y <= Me.MinimumSize.Height Then Return
        Me.Height = Me.Height - Location.Y
        Me.Top = Me.Top + Location.Y
        Exit Select
      Case ResizeState.South
        Me.Height = Location.Y
        Exit Select
      Case ResizeState.East
        Me.Width = Location.X
        Exit Select
      Case ResizeState.West
        If Me.Width - Location.X <= Me.MinimumSize.Width Then Return
        Me.Width = Me.Width - Location.X
        Me.Left = Me.Left + Location.X
        Exit Select
      Case ResizeState.NE
        BorderlessResize_ResizeForm(ResizeState.North)
        BorderlessResize_ResizeForm(ResizeState.East)
        Exit Select
      Case ResizeState.SE
        BorderlessResize_ResizeForm(ResizeState.South)
        BorderlessResize_ResizeForm(ResizeState.East)
        Exit Select
      Case ResizeState.SW
        BorderlessResize_ResizeForm(ResizeState.South)
        BorderlessResize_ResizeForm(ResizeState.West)
        Exit Select
      Case ResizeState.NW
        BorderlessResize_ResizeForm(ResizeState.North)
        BorderlessResize_ResizeForm(ResizeState.West)
        Exit Select
    End Select
  End Sub

  Protected Sub BorderlessResize_MouseUp(sender As Object, e As MouseEventArgs)
    If e.Button = MouseButtons.Left Then
      m_utdResizeState = ResizeState.None
    End If
  End Sub

默认上下文菜单

  Private Const WS_SYSMENU As Integer = &H80000
  Private Const WS_MINIMIZEBOX As Integer = &H20000
  Private Const WS_MAXIMIZEBOX As Integer = &H10000
  Protected Overrides ReadOnly Property CreateParams As System.Windows.Forms.CreateParams
    Get
      Dim p = MyBase.CreateParams
      p.Style = WS_SYSMENU + WS_MINIMIZEBOX + WS_MAXIMIZEBOX
      Return p
    End Get
  End Property

  <DllImport("user32.dll")>
  Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer,
      ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
  End Function
  Private Const WM_POPUPSYSTEMMENU = &H313
  Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
    MyBase.OnMouseDown(e)
    Dim p = MousePosition.X + (MousePosition.Y * &H10000)
    SendMessage(Me.Handle, WM_POPUPSYSTEMMENU, 0, p)
  End Sub

移动和调整大小的工作正常,但我的上下文菜单始终显示在左上角,MOVESIZE选项不起作用,因为它们需要我删除的默认窗口框架。 / p>

那么有可能实现我的移动和调整大小进入上下文菜单的解决方案吗?

1 个答案:

答案 0 :(得分:0)

解决方案1 ​​

使用WndPrc覆盖

<div ng-app="myApp" ng-controller="myCtrl">
   <input type="text" my-ng-init="myFunc"><br>
</div>

<script>
var app = angular.module('myApp', []);
app.directive('myNgInit', function() {
  return {
    scope: {
     myNgInit: '&'
    },
    link: function(scope, element, attributes) {
    scope.myNgInit()(element);
    }
  };
});

app.controller('myCtrl', function($scope) {
   $scope.myFunc= function($element) {
    console.log($element);
   }
});
</script>

解决方案2

使用TrackMenuBar

Private Sub Header_MouseDown(sender As Object, ByVal e As MouseEventArgs)
    If e.Button = MouseButtons.Right Then
      Dim p As IntPtr = ((MousePosition.Y * WindowStyles.WS_MAXIMIZEBOX) + (MousePosition.X And &HFFFF))
      Dim test As IntPtr = SendMessage(Me.Handle, WindowMessages.WM_POPUPSYSMENU, 0, p)
    End If
  End Sub

Protected Overrides Sub WndProc(ByRef m As Message)
    If (m.Msg = WindowMessages.WM_SYSCOMMAND)
        'Do SOmething with m.wParam
    Else
      MyBase.WndProc(m)
    End If
  End Sub