locked
Opaque Controls in a Transparent Form

    Question

  • I would like to make a transparent form with opaque controls.  It tried setting the opacity setting, but that makes the controls transparent, also.  Is there any for them to remain opaque?

    Thanks for you help.
    Thursday, November 15, 2007 2:42 AM

Answers

  • Make the form's backcolor a unique color.

    Make the forms tramsparency key property that color.

    Make the form's FormBorderStyle = none.

     

    Have fun.

     

    Friday, November 16, 2007 7:47 AM
  • Hi Jupiter13,

     

    Based on your post, my understanding of your question is that you need to make the form semi-transparent and the control opaque.

     

    As far as I know, when you set the form opaque property the child controls will show the same property. I think we can create a tranparent control and paint its background with the background of the screen.  We make the form's backcolor a unique color, make the forms tramsparency key property that color. In this scenario the control is opaque. We use the transparent control to imitate the seme-transparent windows. Here is the transparent control and the form code. Try it. Hope this help.

    Code Block

    Imports System

    Imports System.Collections

    Imports System.ComponentModel

    Imports System.Drawing

    Imports System.Data

    Imports System.Windows.Forms

    Imports System.Drawing.Imaging

    Namespace TransControl

    Public Class TransControl

    Inherits System.Windows.Forms.Panel

    Private components As System.ComponentModel.Container = Nothing

    Private topBorder As New Label()

    Private leftBorder As New Label()

    Private bottomBorder As New Label()

    Private rightBorder As New Label()

    Public XOffset As Integer = 0

    Public YOffset As Integer = 0

    Public img As Image

    Public cm As New ColorMatrix

    Private x As Integer

    Private y As Integer

    Private pleft As Integer

    Private ptop As Integer

    Private isMouseDown As Boolean = False

    Public Sub New()

    InitializeComponent()

    End Sub

    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

    If disposing Then

    If components IsNot Nothing Then

    components.Dispose()

    img.Dispose()

    End If

    End If

    MyBase.Dispose(disposing)

    End Sub

    Protected Overloads 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

    #Region "Component Designer generated code"

    Private Sub InitializeComponent()

    Me.Name = "TransControl"

    Me.Controls.Add(topBorder)

    Me.Controls.Add(rightBorder)

    Me.Controls.Add(leftBorder)

    Me.Controls.Add(bottomBorder)

    Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True)

    img = Image.FromFile("c:\2.bmp")

    AddHandler Me.MouseDown, AddressOf this_MouseDown

    AddHandler Me.MouseMove, AddressOf this_MouseMove

    AddHandler Me.MouseUp, AddressOf this_MouseUp

    AddBorders()

    cm.Matrix33 = 0.5

    End Sub

    #End Region

    Protected Overloads Overrides Sub OnPaint(ByVal e As PaintEventArgs)

    AddBorders()

    End Sub

    Protected Overloads Overrides Sub OnPaintBackground(ByVal pevent As PaintEventArgs)

    Dim ia As New ImageAttributes

    ia.SetColorMatrix(cm)

    Dim rc As New Rectangle(Point.Empty, Me.Size)

    pevent.Graphics.DrawImage(img, New Rectangle(0, 0, Me.Width, Me.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia)

    End Sub

    Protected Sub this_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)

    If isMouseDown Then

    Me.left = Me.left + (e.X - x)

    Me.Top = Me.Top + (e.Y - y)

    Me.Parent.Refresh()

    End If

    End Sub

    Protected Sub this_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)

    x = e.X

    y = e.Y

    pleft = Me.Left

    ptop = Me.Top

    isMouseDown = True

    Me.Cursor = Cursors.SizeAll

    End Sub

    Protected Sub this_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)

    isMouseDown = False

    Me.Cursor = Cursors.Default

    Me.Refresh()

    End Sub

    Private Sub AddBorders()

    topBorder.Location = New Point(0, 0)

    topBorder.Size = New Size(Me.Width, 10)

    topBorder.BackColor = Color.Black

    leftBorder.Location = New Point(0, 0)

    leftBorder.Size = New Size(1, Me.Height)

    leftBorder.BackColor = Color.Black

    rightBorder.Location = New Point(Me.Width - 1, 0)

    rightBorder.Size = New Size(1, Me.Height)

    rightBorder.BackColor = Color.Black

    bottomBorder.Location = New Point(0, Me.Height - 1)

    bottomBorder.Size = New Size(Me.Width, 1)

    bottomBorder.BackColor = Color.Black

    End Sub

    End Class

    End Namespace

     

    Imports System.Drawing.Imaging

    Public Class Form1

    Dim bmp As Bitmap

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Me.Opacity = 0

    bmp = New Bitmap(Me.Width, Me.Height, PixelFormat.Format32bppArgb)

    Dim gr As Graphics = Graphics.FromImage(bmp)

    gr.CopyFromScreen(Me.Left, Me.Top, 0, 0, Me.Size, CopyPixelOperation.SourceCopy)

    Me.TransControl1.cm.Matrix33 = 0.5

    Me.TransControl1.img = bmp

    gr.Dispose()

    Me.Timer1.Interval = 4000

    Me.Timer1.Start()

    Me.Opacity = 1.0

    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

    bmp = Nothing

    bmp = New Bitmap(Me.Width, Me.Height, PixelFormat.Format32bppArgb)

    Dim gr As Graphics = Graphics.FromImage(bmp)

    Me.Opacity = 0

    Me.Invalidate()

    gr.CopyFromScreen(Me.Left, Me.Top, 0, 0, Me.Size, CopyPixelOperation.SourceCopy)

    Me.TransControl1.img = bmp

    Me.TransControl1.cm.Matrix33 = 0.5

    Me.TransControl1.Invalidate()

    Me.Button1.BringToFront()

    Me.Button2.BringToFront()

    gr.Dispose()

    Me.Opacity = 1.0

    End Sub

    End Class

     

     

     

    Best regards,

    Riquel

    Monday, November 19, 2007 8:15 AM

All replies

  • Make the form's backcolor a unique color.

    Make the forms tramsparency key property that color.

    Make the form's FormBorderStyle = none.

     

    Have fun.

     

    Friday, November 16, 2007 7:47 AM
  • I apologize, i meant to say that I want the form to be semitransparent.
    Saturday, November 17, 2007 2:04 AM
  • Hi Jupiter13,

     

    Based on your post, my understanding of your question is that you need to make the form semi-transparent and the control opaque.

     

    As far as I know, when you set the form opaque property the child controls will show the same property. I think we can create a tranparent control and paint its background with the background of the screen.  We make the form's backcolor a unique color, make the forms tramsparency key property that color. In this scenario the control is opaque. We use the transparent control to imitate the seme-transparent windows. Here is the transparent control and the form code. Try it. Hope this help.

    Code Block

    Imports System

    Imports System.Collections

    Imports System.ComponentModel

    Imports System.Drawing

    Imports System.Data

    Imports System.Windows.Forms

    Imports System.Drawing.Imaging

    Namespace TransControl

    Public Class TransControl

    Inherits System.Windows.Forms.Panel

    Private components As System.ComponentModel.Container = Nothing

    Private topBorder As New Label()

    Private leftBorder As New Label()

    Private bottomBorder As New Label()

    Private rightBorder As New Label()

    Public XOffset As Integer = 0

    Public YOffset As Integer = 0

    Public img As Image

    Public cm As New ColorMatrix

    Private x As Integer

    Private y As Integer

    Private pleft As Integer

    Private ptop As Integer

    Private isMouseDown As Boolean = False

    Public Sub New()

    InitializeComponent()

    End Sub

    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

    If disposing Then

    If components IsNot Nothing Then

    components.Dispose()

    img.Dispose()

    End If

    End If

    MyBase.Dispose(disposing)

    End Sub

    Protected Overloads 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

    #Region "Component Designer generated code"

    Private Sub InitializeComponent()

    Me.Name = "TransControl"

    Me.Controls.Add(topBorder)

    Me.Controls.Add(rightBorder)

    Me.Controls.Add(leftBorder)

    Me.Controls.Add(bottomBorder)

    Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True)

    img = Image.FromFile("c:\2.bmp")

    AddHandler Me.MouseDown, AddressOf this_MouseDown

    AddHandler Me.MouseMove, AddressOf this_MouseMove

    AddHandler Me.MouseUp, AddressOf this_MouseUp

    AddBorders()

    cm.Matrix33 = 0.5

    End Sub

    #End Region

    Protected Overloads Overrides Sub OnPaint(ByVal e As PaintEventArgs)

    AddBorders()

    End Sub

    Protected Overloads Overrides Sub OnPaintBackground(ByVal pevent As PaintEventArgs)

    Dim ia As New ImageAttributes

    ia.SetColorMatrix(cm)

    Dim rc As New Rectangle(Point.Empty, Me.Size)

    pevent.Graphics.DrawImage(img, New Rectangle(0, 0, Me.Width, Me.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia)

    End Sub

    Protected Sub this_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)

    If isMouseDown Then

    Me.left = Me.left + (e.X - x)

    Me.Top = Me.Top + (e.Y - y)

    Me.Parent.Refresh()

    End If

    End Sub

    Protected Sub this_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)

    x = e.X

    y = e.Y

    pleft = Me.Left

    ptop = Me.Top

    isMouseDown = True

    Me.Cursor = Cursors.SizeAll

    End Sub

    Protected Sub this_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)

    isMouseDown = False

    Me.Cursor = Cursors.Default

    Me.Refresh()

    End Sub

    Private Sub AddBorders()

    topBorder.Location = New Point(0, 0)

    topBorder.Size = New Size(Me.Width, 10)

    topBorder.BackColor = Color.Black

    leftBorder.Location = New Point(0, 0)

    leftBorder.Size = New Size(1, Me.Height)

    leftBorder.BackColor = Color.Black

    rightBorder.Location = New Point(Me.Width - 1, 0)

    rightBorder.Size = New Size(1, Me.Height)

    rightBorder.BackColor = Color.Black

    bottomBorder.Location = New Point(0, Me.Height - 1)

    bottomBorder.Size = New Size(Me.Width, 1)

    bottomBorder.BackColor = Color.Black

    End Sub

    End Class

    End Namespace

     

    Imports System.Drawing.Imaging

    Public Class Form1

    Dim bmp As Bitmap

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Me.Opacity = 0

    bmp = New Bitmap(Me.Width, Me.Height, PixelFormat.Format32bppArgb)

    Dim gr As Graphics = Graphics.FromImage(bmp)

    gr.CopyFromScreen(Me.Left, Me.Top, 0, 0, Me.Size, CopyPixelOperation.SourceCopy)

    Me.TransControl1.cm.Matrix33 = 0.5

    Me.TransControl1.img = bmp

    gr.Dispose()

    Me.Timer1.Interval = 4000

    Me.Timer1.Start()

    Me.Opacity = 1.0

    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

    bmp = Nothing

    bmp = New Bitmap(Me.Width, Me.Height, PixelFormat.Format32bppArgb)

    Dim gr As Graphics = Graphics.FromImage(bmp)

    Me.Opacity = 0

    Me.Invalidate()

    gr.CopyFromScreen(Me.Left, Me.Top, 0, 0, Me.Size, CopyPixelOperation.SourceCopy)

    Me.TransControl1.img = bmp

    Me.TransControl1.cm.Matrix33 = 0.5

    Me.TransControl1.Invalidate()

    Me.Button1.BringToFront()

    Me.Button2.BringToFront()

    gr.Dispose()

    Me.Opacity = 1.0

    End Sub

    End Class

     

     

     

    Best regards,

    Riquel

    Monday, November 19, 2007 8:15 AM
  • Copying the screen to the form backgound will achieve a pseudo transparency effect.  But, what about when the form is moved, or more importantly, the screen behide the form changes due an application being closed, resized, moved, or an another application launched?

     

    How can you determine when the screen behide your form has changed?

    Friday, November 30, 2007 8:01 PM
  • Okay,

     

    Try out this VB express solution and tell me

    what you think.

     

    http://www.filecrunch.com/file/~86rdkt

     

    Monday, December 03, 2007 3:46 AM
  • Hi ThomasNichols,

     

    I use the Timer component continuously to repaint the background of the form. So this can handle these problems.

     

    Best regards,

    Riquel

    Tuesday, December 04, 2007 12:13 PM
  • Riquel Dong - MSFT,

     

    The snippet your provided isn't really efficient as it flickers when moved or when the timer ticks.

     

    Are there any ways you could make the painting more efficient?

     

    I've tried a graphics double buffer although it seems to do more harm than good.

     

    Regards,

    Alvin K.N. Tan

    Tuesday, April 15, 2008 7:19 AM
  • There is a third party control library called SemitranparentForm.dll. By referring this assembly and inheriting the StForm we can get Opaque controls on Semitransparent form. A demo application is also available. Try applications StPlayer and StNotepad also. Use the below link for more information.


    http://stforms.net
    Monday, April 27, 2009 8:13 AM