Problem when showing MdiChild form

G

Guest

I've noticed that child forms always seem to show their title bar when they
are first shown in an MdiClient. This is a problem for me because I am
implementing a custom look which requires me to hide the system's title bar
in order to draw my own. I've created a sample that demonstrates the issue:


Public Class Form1
Inherits Windows.Forms.Form

Protected WithEvents Button1 As Windows.Forms.Button
Protected ChildForms() As Windows.Forms.Form

Public Sub New()
MyBase.New()
Me.IsMdiContainer = True
Me.Size = New Drawing.Size(800, 600)

Const n As Integer = 4
Const uBound As Integer = (n - 1)
Dim childForms(uBound) As Windows.Forms.Form
Dim position As Integer = 0
Const delta As Integer = 24
For i As Integer = 0 To uBound
childForms(i) = New Windows.Forms.Form
childForms(i).MdiParent = Me
childForms(i).FormBorderStyle = Windows.Forms.FormBorderStyle.None
childForms(i).ControlBox = False
childForms(i).StartPosition = FormStartPosition.Manual
childForms(i).Location = New Drawing.Point(position, position)
position += delta
Next i
Me.ChildForms = childForms

Me.Button1 = New Windows.Forms.Button
Me.Button1.Text = "Click Me"

Dim topPanel As New Windows.Forms.Panel
topPanel.Height = Me.Button1.Height
topPanel.Dock = DockStyle.Top
topPanel.Controls.Add(Me.Button1)

Me.Controls.Add(topPanel)
End Sub

Private Sub Button1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Button1.Click
For i As Integer = 0 To Me.ChildForms.GetUpperBound(0)
Me.ChildForms(i).Visible = (Not Me.ChildForms(i).Visible)
Next i
End Sub

Protected Overrides Sub OnMdiChildActivate(ByVal e As System.EventArgs)
' The following simulates code that might be executed when an MdiChild
is activated, such as merging menus.
Dim duration As New System.TimeSpan(0, 0, 1)
Dim startTime As System.DateTime = System.DateTime.Now
While ((System.DateTime.Now - startTime) < duration)
End While
MyBase.OnMdiChildActivate(e)
End Sub

End Class


Is there any way to prevent the title bar of the MdiChild forms from
appearing when the child forms are first shown?

Thanks for any help!
Lance
 
J

Jeffrey Tan[MSFT]

Hi Lance,

Yes, by using your code snippet, I can reproduce this behavior.

Further debugging shows that this behavior is caused by the hang of main
GUI thread in OnMdiChildActivate method. That is your While loop costs too
much time in the OnMdiChildActivate method and blocks the main GUI thread.
Since the drawing code is maintained in the main GUI thread, this will
prevent the correct drawing of MDI child form.

For example, your problem can also be reproduced with the code below:
Protected Overrides Sub OnMdiChildActivate(ByVal e As System.EventArgs)
System.Threading.Thread.Sleep(5000)
MyBase.OnMdiChildActivate(e)
End Sub

If you remove this code, it should paint well.

Actually, it is not recommended to place time-consuming code in the main
GUI thread to block its drawing. If you want to perform some time-consuming
code, you'd better place it in a background non-GUI thread. In your
scenario, if you want to merge the menus of your application, I think you'd
better merge the menus before showing the MDI child forms(that is moving
the code in the OnMdiChildActivate before showing the form). Then the form
can be shown without painting block and UI should be OK.

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi Jeffrey,

Thank you for your help and you are right that removing time-consuming code
helps. But, I can still notice the system drawing the title bar briefly
(i.e., flicker) even if I have no code execute during the activate event. In
fact it was under these conditions when I first noticed the issue. I only
included the while loop to make the issue more obvious and because in a real
world app it is common to have at least some code execute in the
MdiChildActivate event. If you take out the while loop in my sample you
should still be able to notice the issue (and note that you can click the
button multiple times in order to show and hide the forms).

I was hoping to implement a fix that would prevent the system from drawing
the title bar because I consider any flicker to be unacceptable. Do you know
why the system is drawing the title bar in the first place and, more
importantly, is there any way to prevent it?

Thanks again!
Lance
 
J

Jeffrey Tan[MSFT]

Hi Lance,

Sorry for the late response. I am out of office yesterday.

Yes, I see your concern. I have searched the internal database for this
issue, however, I did not find any similar record yet.

I will try to contact the .Net Winform team for this issue, I hope they can
provide some insight for it.

I will get back to you ASAP. Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Lance,

Since the US is in National Holiday, I still did not get any response from
the Winform team yet.

Anyway, I have officially filed a bug to the .Net Winform team for this
issue internally. This may take some time for them to response. I will post
any progress here ASAP. Thanks for your patient.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi Jeffrey,

Thank you for the update and for continuing to look into this issue. I am
glad to hear that you are working with the .NET WinForm team and I greatly
appreciate your help.

Lance
 
G

Guest

Hi all i'm having the exact same problem ...

it does flicker a bit, and i'm using vs 2003.
 
J

Jeffrey Tan[MSFT]

Hi Lance,

Sorry for the late response.

Due to the US holiday and internal bug database update, we got a lot delay
on contacting the Winform team. Now, I can find the bug record to the
Winform team. I am working with them on this issue.

I will get back to you ASAP. Thanks for your patient.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Lance,

During the discussion, the Winform confirmed that there is some painting
logic order wrong in showing the MDI child form. It seems that the
problematic drawing embeded deep in the Layout code. After spending a lot
effect to find a workaround, one Winform developer is able to find a
workaround. The workaround logic is like this:
"Basically, when you create the childform, set its position to (-1000,
-1000) (outside the screen). After it is set to visible, then you put it
back in the correct spot. When you set it to visible=false, then set it
outiside the screen again."
The modified repro sample is listed below, you may give it a try:

Public Class Form1
Inherits Windows.Forms.Form

Protected WithEvents Button1 As Windows.Forms.Button
Protected ChildForms() As Windows.Forms.Form

Public Sub New()
MyBase.New()
Me.IsMdiContainer = True
Me.Size = New Drawing.Size(800, 600)

Const n As Integer = 4
Const uBound As Integer = (n - 1)
Dim childForms(uBound) As Windows.Forms.Form
Dim position As Integer = 0
Const delta As Integer = 24
For i As Integer = 0 To uBound
childForms(i) = New Windows.Forms.Form
childForms(i).MdiParent = Me
childForms(i).FormBorderStyle = Windows.Forms.FormBorderStyle.None
childForms(i).ControlBox = False
childForms(i).StartPosition = FormStartPosition.Manual
childForms(i).Location = New Drawing.Point(position-1000, position-1000)
position += delta
Next i
Me.ChildForms = childForms

Me.Button1 = New Windows.Forms.Button
Me.Button1.Text = "Click Me"

Dim topPanel As New Windows.Forms.Panel
topPanel.Height = Me.Button1.Height
topPanel.Dock = DockStyle.Top
topPanel.Controls.Add(Me.Button1)

Me.Controls.Add(topPanel)
End Sub

Private Sub Button1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Button1.Click
For i As Integer = 0 To Me.ChildForms.GetUpperBound(0)
Me.ChildForms(i).Visible = (Not Me.ChildForms(i).Visible)
If Me.ChildForms(i).Visible Then
Me.ChildForms(i).Location = New Drawing.Point(Me.ChildForms(i).Location.X +
1000, Me.ChildForms(i).Location.Y + 1000)
Else
Me.ChildForms(i).Location = New Drawing.Point(Me.ChildForms(i).Location.X -
1000, Me.ChildForms(i).Location.Y - 1000)
End If
Next i
End Sub

Protected Overrides Sub OnMdiChildActivate(ByVal e As System.EventArgs)
' The following simulates code that might be executed when an MdiChild is
activated, such as merging menus.
Dim duration As New System.TimeSpan(0, 0, 1)
Dim startTime As System.DateTime = System.DateTime.Now
While ((System.DateTime.Now - startTime) < duration)
End While
MyBase.OnMdiChildActivate(e)
End Sub

End Class

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top