How do I make a genuinely transparent Control?
-
08-07-2019 - |
Question
I need to make a Control which shows only an outline, and I need to place it over a control that's showing a video. If I make my Control transparent, then the video is obscured, because transparent controls are painted by their parent control and the video isn't painted by the control; it's shown using DirectShow or another library, so instead the parent control paints its BackColor.
So - can I make a control that doesn't get painted at all, except where it's opaque? That way, the parent control wouldn't paint over the video.
I know I could make the border out of four controls (or more if I want it dashed) but is it possible to do what I want using just one control?
rslite is right - although you don't even need to go so far as to use PInvoke like his example does - the Control.Region property is entirely sufficient.
Solution
You could try to make a Region with a hole inside and set the control region with SetWindowRgn.
Here is an example (I couldn't find a better one). The idea is to create two regions and subtract the inner one from the outer one. I think that should give you what you need.
OTHER TIPS
I use an overridden function for that from the class control.
The
createparams
property now indicates that the control can be transparent.InvalidateEx
is necessary to invalidate the parent's region where the control is placedYou have to disable the automatic paint of the backcolor from the control (')
Imports System.Windows.Forms.Design Imports System.Reflection Public Class TransparentControl : Inherits Control Protected Overrides ReadOnly Property CreateParams As CreateParams Get Dim cp As CreateParams = MyBase.CreateParams() cp.ExStyle = cp.ExStyle Or 32 'WS_EX_TRANSPARENT Return cp End Get End Property Protected Sub InvalidateEx(rct As Rectangle) Me.Invalidate(rct) If IsNothing(Parent) Then Exit Sub Parent.Invalidate(New Rectangle(Me.Location, rct.Size), True) End Sub Protected Sub InvalidateEx() Me.Invalidate() If IsNothing(Parent) Then Exit Sub Parent.Invalidate(New Rectangle(Me.Location, Me.Size), True) End Sub Protected Overrides Sub OnPaintBackground(pevent As PaintEventArgs) 'MyBase.OnPaintBackground(pevent) End Sub Protected Overrides Sub OnPaint(e As PaintEventArgs) MyBase.OnPaint(e) 'draw the layout on e.Graphics End Sub End Class
You can extend this class to make your own control. After debugging the class will appear in the toolbox.
Hope this does the trick.
You could try setting the Form.TransparencyKey
property. Failing that, you could use DirectX to get access to the frame buffer and draw directly to it.