2011-05-30 48 views
2

我只是想知道是否有一种可能的方法来添加自定义按钮到标题栏使用VB.NET。我在Stack Overflow上看到过很多这样的问题,但没有得到一个确定的答案和一个可行的答案。在标题栏添加一个自定义按钮VB.NET

任何人都可以帮助我解决这个问题吗?我也检查过Google和其他网站,但它无法呈现。我希望代码能够在Windows XP,Windows Vista和Windows 7上工作。

我会感谢如果您能够提供工作代码并且该按钮甚至必须能够接受点击事件并发布它以某种行动的形式出现。

在此先感谢

回答

4

如果你指的WinForms,我能想到的两种方法可以做到这一点:

  • 隐藏标题栏,并用自己的,我不建议更换。
  • 将按钮构建为非常小的窗体,每次窗口移动时都保持停靠在正确的位置。
+0

感谢您的回答,但你肯定是没有功能的Windows DLL将一个按钮添加到标题栏?我看过使用这些API的代码,但不能很好地工作!请帮我出 – 2011-05-30 05:19:22

+1

+1它的快速和好方法 – Shahin 2011-05-30 05:22:38

+0

第二种方法是非常聪明的。辉煌的笑xD – NightHowler 2017-06-12 11:59:21

1

马修Scharley中写道his answer here

下面将在XP的工作,我没有Vista的机器方便的测试 ,但我觉得你的问题是从一个不正确的hWnd steming不知何故。无论如何,与评论不好的代码。

我觉得这并不在Vista图形显示和7马修的代码翻译版本如下:

' The state of our little button 
Private _buttState As ButtonState = ButtonState.Normal 
Private _buttPosition As New Rectangle() 

<DllImport("user32.dll")> _ 
Private Shared Function GetWindowDC(hWnd As IntPtr) As IntPtr 
End Function 
<DllImport("user32.dll")> _ 
Private Shared Function GetWindowRect(hWnd As IntPtr, ByRef lpRect As Rectangle) As Integer 
End Function 
<DllImport("user32.dll")> _ 
Private Shared Function ReleaseDC(hWnd As IntPtr, hDC As IntPtr) As Integer 
End Function 
Protected Overrides Sub WndProc(ByRef m As Message) 
    Dim x As Integer, y As Integer 
    Dim windowRect As New Rectangle() 
    GetWindowRect(m.HWnd, windowRect) 

    Select Case m.Msg 
     ' WM_NCPAINT 
     ' WM_PAINT 
     Case &H85, &Ha 
      MyBase.WndProc(m) 

      DrawButton(m.HWnd) 

      m.Result = IntPtr.Zero 

      Exit Select 

     ' WM_ACTIVATE 
     Case &H86 
      MyBase.WndProc(m) 
      DrawButton(m.HWnd) 

      Exit Select 

     ' WM_NCMOUSEMOVE 
     Case &Ha0 
      ' Extract the least significant 16 bits 
      x = (CInt(m.LParam) << 16) >> 16 
      ' Extract the most significant 16 bits 
      y = CInt(m.LParam) >> 16 

      x -= windowRect.Left 
      y -= windowRect.Top 

      MyBase.WndProc(m) 

      If Not _buttPosition.Contains(New Point(x, y)) AndAlso _buttState = ButtonState.Pushed Then 
       _buttState = ButtonState.Normal 
       DrawButton(m.HWnd) 
      End If 

      Exit Select 

     ' WM_NCLBUTTONDOWN 
     Case &Ha1 
      ' Extract the least significant 16 bits 
      x = (CInt(m.LParam) << 16) >> 16 
      ' Extract the most significant 16 bits 
      y = CInt(m.LParam) >> 16 

      x -= windowRect.Left 
      y -= windowRect.Top 

      If _buttPosition.Contains(New Point(x, y)) Then 
       _buttState = ButtonState.Pushed 
       DrawButton(m.HWnd) 
      Else 
       MyBase.WndProc(m) 
      End If 

      Exit Select 

     ' WM_NCLBUTTONUP 
     Case &Ha2 
      ' Extract the least significant 16 bits 
      x = (CInt(m.LParam) << 16) >> 16 
      ' Extract the most significant 16 bits 
      y = CInt(m.LParam) >> 16 

      x -= windowRect.Left 
      y -= windowRect.Top 

      If _buttPosition.Contains(New Point(x, y)) AndAlso _buttState = ButtonState.Pushed Then 
       _buttState = ButtonState.Normal 
       ' [[TODO]]: Fire a click event for your button 
       '   however you want to do it. 
       DrawButton(m.HWnd) 
      Else 
       MyBase.WndProc(m) 
      End If 

      Exit Select 

     ' WM_NCHITTEST 
     Case &H84 
      ' Extract the least significant 16 bits 
      x = (CInt(m.LParam) << 16) >> 16 
      ' Extract the most significant 16 bits 
      y = CInt(m.LParam) >> 16 

      x -= windowRect.Left 
      y -= windowRect.Top 

      If _buttPosition.Contains(New Point(x, y)) Then 
       m.Result = DirectCast(18, IntPtr) 
      Else 
       ' HTBORDER 
       MyBase.WndProc(m) 
      End If 

      Exit Select 
     Case Else 

      MyBase.WndProc(m) 
      Exit Select 
    End Select 
End Sub 

Private Sub DrawButton(hwnd As IntPtr) 
    Dim hDC As IntPtr = GetWindowDC(hwnd) 
    Dim x As Integer, y As Integer 

    Using g As Graphics = Graphics.FromHdc(hDC) 
     ' Work out size and positioning 
     Dim CaptionHeight As Integer = Bounds.Height - ClientRectangle.Height 
     Dim ButtonSize As Size = SystemInformation.CaptionButtonSize 
     x = Bounds.Width - 4 * ButtonSize.Width 
     y = (CaptionHeight - ButtonSize.Height) \ 2 
     _buttPosition.Location = New Point(x, y) 

     ' Work out color 
     Dim color As Brush 
     If _buttState = ButtonState.Pushed Then 
      color = Brushes.LightGreen 
     Else 
      color = Brushes.Red 
     End If 

     ' Draw our "button" 
     g.FillRectangle(color, x, y, ButtonSize.Width, ButtonSize.Height) 
    End Using 

    ReleaseDC(hwnd, hDC) 
End Sub 

Private Sub Form1_Load(sender As Object, e As EventArgs) 
    _buttPosition.Size = SystemInformation.CaptionButtonSize 
End Sub 
+1

我很高兴你可以提前给我一个代码段来帮助我。我目前有Windows 7,它无法呈现。我在Windows XP上没有真正尝试过。但再次感谢您的帮助!下面的代码似乎给出了一个错误,指出18不能转换为IntPtr:“m.Result = DirectCast(18,IntPtr)”。再次感谢您的帮助!干杯 – 2011-05-30 06:06:55

+0

欢迎您:) 老实说,我在c#中试过这段代码,它工作,所以我没有将它转换为VB.NET。祝你好运 – Shahin 2011-05-30 11:29:51

相关问题