Transparent Form Problem- Solved (kind of!!)

vis781

Well-known member
Joined
Aug 30, 2005
Messages
2,016
Location
Cambridge, UK
Programming Experience
5-10
For a while now, in my spare time, i have been looking for a way to create a transparent form, but not using the transparency key or the forms opactiy property, and i think i may have found it. It was purely by chance as i was messing around with a couple of API's. The Idea is this.... get the underlying window below the form you want to display. Run through the pixels in that underlying window and paint them pixel by pixel onto the from you want to display. So the resulting form looks transparent, it actually isn't, what is happening is the it is just painting the form exactly like the form below within it's client area. It works fine so long as you dont move the form, which, i know, is a bit restricive. But the result is a 'fake' transparent form on which you can draw anything. Anyway here is the code. Paste it into the OnPaintBackGround Event of any form and see for yourself....

These bit just go into the form class as separate functions...
VB.NET:
[SIZE=2]<DllImport("user32.dll")> _
[/SIZE]Private Shared Function GetDesktopWindow() As IntPtr
End Function
<DllImport("gdi32.dll")> _
Private Shared Function GetPixel(ByVal hdc As IntPtr, ByVal x As Integer, ByVal y As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowDC(ByVal hwnd As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _
Private Shared Function GetWindowRect(ByVal hWnd As IntPtr, <Out()> ByRef rect As Tester.RECT) As Boolean
End Function
<DllImport("user32.dll", EntryPoint:="ReleaseDC", CharSet:=CharSet.Auto, ExactSpelling:=True)> _
Private Shared Function IntReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer
End Function
<DllImport("gdi32.dll")> _
Private Shared Function SetPixel(ByVal hdc As IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal color As Integer) As Integer
End Function
<DllImport("User32.Dll")> _
Public Shared Function ReleaseDC(ByVal Hwnd As IntPtr, ByVal Hdc As IntPtr) As Integer
End Function
[SIZE=2]<StructLayout(LayoutKind.Sequential)> _
[/SIZE][SIZE=2][COLOR=#0000ff]Friend [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Structure[/COLOR][/SIZE][SIZE=2] RECT
[/SIZE][SIZE=2][COLOR=#0000ff]Public[/COLOR][/SIZE][SIZE=2] Left [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Integer
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Public[/COLOR][/SIZE][SIZE=2] Top [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Integer
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Public[/COLOR][/SIZE][SIZE=2] Right [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Integer
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Public[/COLOR][/SIZE][SIZE=2] Bottom [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Integer
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]End [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Structure
[/COLOR][/SIZE]

Then this bit goes into the OnPaintBackGroundEvent...

VB.NET:
Dim rect1 As RECT
Dim hdc As IntPtr = GetWindowDC(GetDesktopWindow)
Dim GraphicsPtr As IntPtr = pevent.Graphics.GetHdc
GetWindowRect(MyBase.Handle, rect1)
Dim width1 As Integer = (rect1.Right - rect1.Left)
Dim height1 As Integer = (rect1.Bottom - rect1.Top)
Dim Int4 As Integer = 0
Do While (Int4< width1)
Dim color1 As Integer = GetPixel(hdc, (width1 - Int4), Int4)
SetPixel(hdc, (width1 - Int4), Int4, color1)
Int4 += 1
Loop
pevent.Graphics.ReleaseHdc(GraphicsPtr)
Tester.IntReleaseDC(Tester.GetDesktopWindow, hdc)

I suppose you could call it a bit of a hack, but it works.
 
Back
Top