Единственный способ сделать это - использовать UpdateLayeredWindow
функцию UpdateLayeredWindow . Эта функция устанавливает 32-битное растровое изображение для вашей оконной формы. Может использоваться и для дочерних окон после windows 8:
Windows 8: стиль WS_EX_LAYERED поддерживается для окон верхнего уровня и дочерних окон. Предыдущие версии Windows поддерживают WS_EX_LAYERED только для окон верхнего уровня.
Использование этой функции означает, что вы можете иметь полное прозрачное окно и рисовать графику , но ни одна краска, которую любое окно или вы делаете, не может быть видна! Вы должны сделать все рисунки для 32-битного растрового изображения и вызвать UpdateLayeredWindow
, чтобы увидеть результаты. Если у вас есть несколько дочерних окон, вы получаете все события, но только если мышь находится над незавершенным прозрачным пикселем. Небольшая хитрость состоит в том, чтобы установить alpha
на самое низкое 1
, чтобы у вас была прозрачность, но вы также можете получать все события из ваших окон. Потому что вы хотите форму клика через это не имеет значения. Теперь код:
Создайте класс для хранения всех ваших API
Public Class APIHelp
Public Const WS_EX_LAYERED As Int32 = &H80000
Public Const WS_EX_TRANSPARENT As Int32 = &H20
Public Const ULW_ALPHA As Int32 = 2
Public Const AC_SRC_OVER As Byte = 0
Public Const AC_SRC_ALPHA As Byte = 1
<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
Public Declare Auto Function GetTickCount Lib "kernel32.dll" () As Double
<DllImport("User32", SetLastError:=True)> Friend Shared Function ReleaseCapture() As Boolean
End Function
End Class
Вызовите эту функцию, чтобы увидеть графику:
Public Sub UpdateLayeredBitmap(ByVal bitmap As Bitmap)
'Does this bitmap contain an alpha channel?
If bitmap.PixelFormat <> PixelFormat.Format32bppArgb Then
Throw New ApplicationException("The bitmap must be 32bpp with alpha-channel.")
End If
'Get device contexts
Dim screenDc As IntPtr = APIHelp.GetDC(IntPtr.Zero)
Dim memDc As IntPtr = APIHelp.CreateCompatibleDC(screenDc)
Dim hBitmap As IntPtr = IntPtr.Zero
Dim hOldBitmap As IntPtr = IntPtr.Zero
Try
' Get handle to the new bitmap and select it into the current device context
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0))
hOldBitmap = APIHelp.SelectObject(memDc, hBitmap)
Dim blend As APIHelp.BLENDFUNCTION = New APIHelp.BLENDFUNCTION()
' 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
Dim sourceLocation As New APIHelp.Point(0, 0)
Dim newLocation As New APIHelp.Point(Me.Location.X, Me.Location.Y)
Dim newSize As New APIHelp.Size(bitmap.Width, bitmap.Height)
'Update the window
APIHelp.UpdateLayeredWindow(Handle, IntPtr.Zero, newLocation, newSize, memDc, sourceLocation,
0, Blend, APIHelp.ULW_ALPHA)
Finally
' Release device context
'APIHelp.ReleaseDC(IntPtr.Zero, screenDc)
If hBitmap <> IntPtr.Zero Then
APIHelp.SelectObject(memDc, hOldBitmap)
' Remove bitmap resources
APIHelp.DeleteObject(hBitmap)
End If
APIHelp.DeleteDC(memDc)
APIHelp.DeleteDC(screenDc)
End Try
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 APIHelp.WS_EX_LAYERED Or APIHelp.WS_EX_TRANSPARENT
Return createParam
End Get
End Property
Пример того, как вы это делаете, это единственный способ рисовать графику:
Private backBitmapEmpty As Bitmap 'it is better to keep it private so to use it over and over
'create a 32 bit bitmap
backBitmapEmpty = New Bitmap(Me.Size.Width, Me.Size.Height, PixelFormat.Format32bppArgb)
Dim g As Graphics = Graphics.FromImage(backBitmapEmpty)
With g
.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias '.ClearTypeGridFit
.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
End With
'make bitmap completely transparent
g.Clear(Color.FromArgb(0, 0, 0, 0))
g.DrawString("Some text", Me.Font, Brushes.Green, New PointF(150.0F, 150.0F))
g.Dispose()
'inform system that bitmap has changed
UpdateLayeredBitmap(backBitmapEmpty)