locked
Retaining original opacity property when form added as control. RRS feed

  • Question

  • In this segment of code the control 'Background' is a custom panel.

    Dim F As New Confirm_Exit
    F.TopLevel = False
    Me.Controls.Add(F)
    F.Opacity = 1
    F.Location = New Point(Background.Width / 2 - F.Width / 2, Background.Height / 2 - F.Height / 2)
    F.BringToFront()
    F.Visible = True

    When the form 'Confirm_Exit' is added as a control to the 'Main', I noticed it retains the opacity property of form 'Main'.

    Is it possible to add 'Confirm_Exit' (with opacity 1) to the form 'Main' (with opacity .5).

    I've tried using MDI but have been unsuccessful.

    Thanks.
    Sunday, December 16, 2007 11:27 PM

Answers

  • Hi halfazner,

     

    I tested it. The Opacity property can be applied to top-level form, but cannot be applied to child form. Child form will have the same opacity as parent form. 

    Code Block

    Public Class Form1

     

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

            Me.Opacity = 0.8 ‘ This will take effect at top-level form.

        End Sub

     

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            Dim F As New Form2

            F.TopLevel = False

            Me.Controls.Add(F)

            F.Opacity = 0.2  ‘ This will not take effect at the child form.It will be ignored and keep the same opacity as parent form.

            F.Location = New Point(10, 10)

            F.BringToFront()

            F.Visible = True

        End Sub

     

    End Class

     

     

    Similar issue: Opacity and MDI form

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=23940&SiteID=1

    Tuesday, December 18, 2007 3:21 PM
  • The answer is:  you can't!  Not with GDI. 

     

    It's quite simple using WPF, however.

     

     

    Thursday, December 20, 2007 5:38 PM

All replies

  • Hi halfazner,

     

    The Opacity just calls the Layered Windows API. The Opacity only works with top-level windows. it won't work with an mdi child window.

     

    Please check: http://msdn2.microsoft.com/en-us/library/7aw8zc76(VS.80).aspx

    The MDI child form is a standard Windows Form. As such, it has an Opacity property, which enables you to control the transparency of the form. However, the Opacity property was designed for top-level windows. Do not use it with MDI child forms, as painting problems can occur.

     

    In addition, you should assign value to Form.Opacity in the form of a decimal.

        e.g.     Me.Opacity = 0.5

     

     

    Regards,

    Martin

    Tuesday, December 18, 2007 7:14 AM
  • Martin Xie,

    I'm not sure if you've tested this but the opacity property applies to MDI child windows. It says in that article you provided that it was designed for top-level windows, however it doesn't mean it can't be used with MDI child forms although it warns not to.

    So unfortunately adding the form as a control and using MDI doesn't work.

    I'm thinking perhaps a paint override however I'm not sure.
    Tuesday, December 18, 2007 12:48 PM
  • Hi halfazner,

     

    I tested it. The Opacity property can be applied to top-level form, but cannot be applied to child form. Child form will have the same opacity as parent form. 

    Code Block

    Public Class Form1

     

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

            Me.Opacity = 0.8 ‘ This will take effect at top-level form.

        End Sub

     

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            Dim F As New Form2

            F.TopLevel = False

            Me.Controls.Add(F)

            F.Opacity = 0.2  ‘ This will not take effect at the child form.It will be ignored and keep the same opacity as parent form.

            F.Location = New Point(10, 10)

            F.BringToFront()

            F.Visible = True

        End Sub

     

    End Class

     

     

    Similar issue: Opacity and MDI form

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=23940&SiteID=1

    Tuesday, December 18, 2007 3:21 PM
  • In addition, based on the following sample (VB6) which sets opacity using Windows API

    http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=44695&lngWId=1

    I convert the VB6 project to VB.NET project by VS 2008 Upgrade Wizard, then I use Windows API to set opacity for individual Form2, and it will work fine.

    Code Block

     

    Public Class Form2

        Private Const GWL_EXSTYLE As Short = (-20)

        Private Const WS_EX_LAYERED As Integer = &H80000

        Private Const WS_EX_TRANSPARENT As Integer = &H20

        Private Const LWA_ALPHA As Integer = &H2

     

        Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Integer, ByVal nIndex As Integer) As Integer

        Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer

        Private Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hwnd As Integer, ByVal crey As Byte, ByVal bAlpha As Byte, ByVal dwFlags As Integer) As Integer

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

     

            System.Windows.Forms.Application.DoEvents()

            Dim NormalWindowStyle As Integer

            NormalWindowStyle = GetWindowLong(Me.Handle.ToInt32, GWL_EXSTYLE)

            SetWindowLong(Me.Handle.ToInt32, GWL_EXSTYLE, NormalWindowStyle Or WS_EX_LAYERED)

     

            'sets the transparency level

            Dim opacity As Single = 0.8

            SetLayeredWindowAttributes(Me.Handle.ToInt32, 0, 255 * opacity, LWA_ALPHA)

        End Sub

    End Class

    But if Form2 is opened as a child form, then setting opacity using Windows API will not take effect.

    Code Block

    Public Class Form1

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            Dim F As New Form2

            F.TopLevel = False

            Me.Controls.Add(F)

            'F.Opacity = 0.2

            F.Location = New Point(10, 10)

            F.BringToFront()

            F.Visible = True

        End Sub

    End Class

     

    Opacity setting on the Child form is ignored, which may be is by design.

    Tuesday, December 18, 2007 3:42 PM
  • I ran into a similar issue when trying to create a partially transparent form with fully opaque controls.  It doesn't work with Windows Forms but is very simple with WPF, so you might try that.

     

    Chris

     

    Tuesday, December 18, 2007 7:00 PM
  • Thanks to both for your help,

    I tried the example you gave, inserted the first code block to the form which is wish to be the child, and the second code block to the parent. No errors found in the code.

    But I still receive a child form which still has the opacity of the parent and this isn't what i intend.

    Any suggestions.
    Tuesday, December 18, 2007 11:24 PM
  • The answer is:  you can't!  Not with GDI. 

     

    It's quite simple using WPF, however.

     

     

    Thursday, December 20, 2007 5:38 PM