It has some work but can be done. Create a new class APIHelp:
Imports System.Runtime.InteropServices
Public Class APIHelp
Public Const WS_EX_LAYERED As Int32 = 524288
'Public Const HTCAPTION As Int32 = 2
'Public Const WM_NCHITTEST As Int32 = 132
Public Const ULW_ALPHA As Int32 = 2
Public Const AC_SRC_OVER As Byte = 0
Public Const AC_SRC_ALPHA As Byte = 1
Public Enum Bool
[False] = 0
[True] = 1
End Enum
<StructLayout(LayoutKind.Sequential)> _
Public Structure Point
Public x As Int32
Public y As Int32
Public Sub New(ByVal x As Int32, ByVal y As Int32)
Me.x = x
Me.y = y
End Sub
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure Size
Public cx As Int32
Public cy As Int32
Public Sub New(ByVal cx As Int32, ByVal cy As Int32)
Me.cx = cx
Me.cy = cy
End Sub
End Structure
<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Private Structure ARGB
Public Blue As Byte
Public Green As Byte
Public Red As Byte
Public Alpha As Byte
End Structure
<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Public Structure BLENDFUNCTION
Public BlendOp As Byte
Public BlendFlags As Byte
Public SourceConstantAlpha As Byte
Public AlphaFormat As Byte
End Structure
Public Declare Auto Function UpdateLayeredWindow Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal hdcDst As IntPtr, ByRef pptDst As Point, ByRef psize As Size, ByVal hdcSrc As IntPtr, ByRef pprSrc As Point, _
ByVal crKey As Int32, ByRef pblend As BLENDFUNCTION, ByVal dwFlags As Int32) As Bool
Public Declare Auto Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hDC As IntPtr) As IntPtr
Public Declare Auto Function GetDC Lib "user32.dll" (ByVal hWnd As IntPtr) As IntPtr
<DllImport("user32.dll", ExactSpelling:=True)> _
Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer
End Function
Public Declare Auto Function DeleteDC Lib "gdi32.dll" (ByVal hdc As IntPtr) As Bool
<DllImport("gdi32.dll", ExactSpelling:=True)> _
Public Shared Function SelectObject(ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
End Function
Public Declare Auto Function DeleteObject Lib "gdi32.dll" (ByVal hObject As IntPtr) As Bool
End Class
Add a new form eg Form2. Set TopMost = False, FormBorderStyle = None and
ShowInTaskbar = False. This form will be your button. Because we want to draw tranparently we set the WS_EX_LAYERED style and we draw
with UpdateLayeredWindow function. You can not draw directly on a form with WS_EX_LAYERED style.
You have to use a device context, draw in it and then call UpdateLayeredWindow:
Public Class Form2
Private sourceLocation As New APIHelp.Point(0, 0)
Private newSize As New APIHelp.Size(...., .....)
Private newLocation As APIHelp.Point
Private blend As New APIHelp.BLENDFUNCTION()
Private memDcNormal, memDcEnter, memDcDown, screenDc, hBmpNormal, hBmpNormalOld, _
hBmpEnter, hBmpEnterOld, hBmpDown, hBmpDownOld As IntPtr
Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Me.Location = New Point(Form1.Location.X + ..., Form1.Location.Y + ...) 'complete the dots
Me.Size = New Size(..., ...) 'size of button
Initialize()
End Sub
Private Sub Initialize()
' Only works with a 32bpp bitmap
blend.BlendOp = APIHelp.AC_SRC_OVER
' Always 0
blend.BlendFlags = 0
' Set to 255 for per-pixel alpha values
blend.SourceConstantAlpha = 255
' Only works when the bitmap contains an alpha channel
blend.AlphaFormat = APIHelp.AC_SRC_ALPHA
screenDc = APIHelp.GetDC(IntPtr.Zero)
Using bmp As Bitmap = CType(Bitmap.FromFile(".....Normal.png"), Bitmap)
memDcNormal = IntPtr.Zero
memDcNormal = APIHelp.CreateCompatibleDC(screenDc)
hBmpNormal = bmp.GetHbitmap(Color.FromArgb(0))
hBmpNormalOld = APIHelp.SelectObject(memDcNormal, hBmpNormal)
End Using
Using bmp As Bitmap = CType(Bitmap.FromFile("......Enter.png"), Bitmap)
memDcEnter = IntPtr.Zero
memDcEnter = APIHelp.CreateCompatibleDC(screenDc)
hBmpEnter = bmp.GetHbitmap(Color.FromArgb(0))
hBmpEnterOld = APIHelp.SelectObject(memDcEnter, hBmpEnter)
End Using
Using bmp As Bitmap = CType(Bitmap.FromFile("......Down.png"), Bitmap)
memDcDown = IntPtr.Zero
memDcDown = APIHelp.CreateCompatibleDC(screenDc)
hBmpDown= bmp.GetHbitmap(Color.FromArgb(0))
hBmpDownOld = APIHelp.SelectObject(memDcDown, hBmpDown)
End Using
APIHelp.DeleteDC(screenDc)
End Sub
Protected Overloads Overrides ReadOnly Property CreateParams() As CreateParams
Get
'Add the layered extended style (WS_EX_LAYERED) to this window
Dim createParam As CreateParams = MyBase.CreateParams
createParam.ExStyle = createParam.ExStyle Or 524288 'WS_EX_LAYERED
Return createParam
End Get
End Property
Private Sub Form2_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
newLocation = New APIHelp.Point(Me.Location.X, Me.Location.Y)
APIHelp.UpdateLayeredWindow(Handle, IntPtr.Zero, newLocation, newSize, memDcDown, sourceLocation, _
0, blend, APIHelp.ULW_ALPHA)
End Sub
Private Sub Form2_MouseEnter(sender As System.Object, e As System.EventArgs) Handles MyBase.MouseEnter
newLocation = New APIHelp.Point(Me.Location.X, Me.Location.Y)
APIHelp.UpdateLayeredWindow(Handle, IntPtr.Zero, newLocation, newSize, memDcEnter, sourceLocation, _
0, blend, APIHelp.ULW_ALPHA)
End Sub
Private Sub Form2_MouseMove(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
Static i As Integer = 1
Static j As Integer = 1
If e.Button = Windows.Forms.MouseButtons.Left Then
If e.X < 0 Or e.X > Me.Width Or e.Y < 0 Or e.Y > Me.Height Then
If i = 1 Then
newLocation = New APIHelp.Point(Me.Location.X, Me.Location.Y)
APIHelp.UpdateLayeredWindow(Handle, IntPtr.Zero, newLocation, newSize, memDcNormal, sourceLocation, _
0, blend, APIHelp.ULW_ALPHA)
i = 0
j = 1
End If
Else
If j = 1 Then
newLocation = New APIHelp.Point(Me.Location.X, Me.Location.Y)
APIHelp.UpdateLayeredWindow(Handle, IntPtr.Zero, newLocation, newSize, memDcDown, sourceLocation, _
0, blend, APIHelp.ULW_ALPHA)
j = 0
i = 1
End If
End If
End If
End Sub
Private Sub Form2_MouseLeave(sender As System.Object, e As System.EventArgs) Handles MyBase.MouseLeave
newLocation = New APIHelp.Point(Me.Location.X, Me.Location.Y)
APIHelp.UpdateLayeredWindow(Handle, IntPtr.Zero, newLocation, newSize, memDcNormal, sourceLocation, _
0, blend, APIHelp.ULW_ALPHA)
End Sub
Private Sub Form2_MouseClick(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseClick
newLocation = New APIHelp.Point(Me.Location.X, Me.Location.Y)
APIHelp.UpdateLayeredWindow(Handle, IntPtr.Zero, newLocation, newSize, memDcEnter, sourceLocation, _
0, blend, APIHelp.ULW_ALPHA)
'Do your staff
End Sub
Private Sub Form2_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
APIHelp.SelectObject(memDcNormal, hBmpNormalOld)
APIHelp.DeleteObject(hBmpNormal)
APIHelp.DeleteDC(memDcNormal)
APIHelp.SelectObject(memDcEnter, hBmpEnterOld)
APIHelp.DeleteObject(hBmpEnter)
APIHelp.DeleteDC(memDcEnter)
APIHelp.SelectObject(memDcDown, hBmpDownOld)
APIHelp.DeleteObject(hBmpDown)
APIHelp.DeleteDC(memDcDown)
End Sub
End Class
As you can see from the above code you need three png images for each state of the button.
In your initial form:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Form2.Show(Me)
End Sub
Private Sub Form1_Move(sender As System.Object, e As System.EventArgs) Handles MyBase.Move
Form2.Location = New Point(Me.Location.X + ..., Me.Location.Y + ...)
End Sub
valter