马修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
感谢您的回答,但你肯定是没有功能的Windows DLL将一个按钮添加到标题栏?我看过使用这些API的代码,但不能很好地工作!请帮我出 – 2011-05-30 05:19:22
+1它的快速和好方法 – Shahin 2011-05-30 05:22:38
第二种方法是非常聪明的。辉煌的笑xD – NightHowler 2017-06-12 11:59:21