Problem with the shadow of my form.

Hi,

I decided to have a shadow with my form so I used this property in my form:

    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim cp As System.Windows.Forms.CreateParams = MyBase.CreateParams
            cp.ClassStyle = cp.ClassStyle Or &H20000
            Return cp
        End Get
    End Property

It is working perfectly if I open my form using ".show()"
But if I open the form as a modal dialog box using ".showDialog(owner)", the shadow (over the owner form) disapear if I move the form or if the form lose focus.

Does someone know how to solve this problem?
slabrie99Asked:
Who is Participating?
 
Bob LearnedConnect With a Mentor Commented:
It might be possible to accomplish the same thing without actually using a modal form, but simulating it by disabling the other visible forms, since this problem doesn't occur until you have a modal form.

Bob
0
 
strickddCommented:
You may need to do a Application.DoEvents() when the form is moved. That should redraw everything including the shadow i would think.
0
 
slabrie99Author Commented:
I've tried "Application.DoEvents()" in the "LocationChanged" event but it does'nt work.
The shadow is still missing over the owner form... but it is showing over the desktop.
0
Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

 
Bob LearnedCommented:
1) .NET version?

2) I set up a small test with 2003, and everything worked for me, even with ShowDialog(owner)

3) Maybe there is something else going on, but what?

Bob
0
 
strickddCommented:
do you need the parent form visible at this time?  You could just hide it.
0
 
strickddCommented:
You could also try setting on the new form: Form.TopMost = true;
0
 
slabrie99Author Commented:
I'm using .NET 2005.

TheLearnedOne: If you move the location of the new form, you still have the shadow over the owner form?

strickdd: With Form.TopMost = true ... Still the same!
0
 
Bob LearnedCommented:
Yep, even with 2005:

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Form2.ShowDialog(Me)
    End Sub
End Class

Public Class Form2

    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ClassStyle = cp.ClassStyle Or &H20000
            Return cp
        End Get
    End Property

End Class

I can drag the form all over the place, and the shadow doesn't disappear.

Bob
0
 
slabrie99Author Commented:
I am using Framework 2.0…  And you?

I've tried my compilation on another computer, hoping it was the version of windows XP I’m using, but the problem is still there.

0
 
Bob LearnedCommented:
I created that example above on 2005 on Windows XP Professional SP2.  Did you try creating a small test application to see where the problem lies?

Bob
0
 
slabrie99Author Commented:
Yes.
I have used your example above on a small test application on a Windows XP Professional SP2 + Framework 2.0.

The portion of the shadow over Form1 only appears when Form2 is just loaded. If I move Form2... The shadow disappears like if Form1 paint over the shadow.

0
 
slabrie99Author Commented:
Or maybe the shadow appears bellow Form1!!
The Z-Order of the shadow of Form2 must fall under Form1!!!
0
 
Bob LearnedCommented:
Here is a place that you can upload screen shots, zip files, PDF documents, etc. that might prove to be helpful here:

http://ee-stuff.com/Expert/Upload/upload.php?Question=<qid>

Example:
http://ee-stuff.com/Expert/Upload/upload.php?Question=21868120

Bob
0
 
slabrie99Author Commented:
Thanks Bob!
I just sent the screenshot to the question ID 21868120
0
 
Bob LearnedCommented:
Here is my result:

   https://filedb.experts-exchange.com/incoming/ee-stuff/146-Shadowed-Form.PNG

Can you show me how you came up with that test?

Bob
0
 
slabrie99Author Commented:
I created a new project with the 2 forms:

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Form2.ShowDialog(Me)
    End Sub
End Class

Public Class Form2
    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ClassStyle = cp.ClassStyle Or &H20000
            Return cp
        End Get
    End Property
End Class


I think the shadow comes from Windows XP.
So I'm using : XP Professional 5.1.2600 SP2 Build 2600

Microsoft Visual Studio 2005
Version 8.0.50727.42  (RTM.050727-4200)
Microsoft .NET Framework
Version 2.0.50727

Installed Edition: Professional

Microsoft Visual Basic 2005   77626-009-0923034-41742
Microsoft Visual Basic 2005
...


Do you see something different compare to your system?

Thanks!!!
0
 
Bob LearnedCommented:
Now, that's more like it.  

I was experimenting with so many things, and I noticed with the last iteration that I only had Form2.Show().  When I changed to Form2.ShowDialog(Me), the shadow went away over the owner.

Bob
0
 
Bob LearnedCommented:
The strange thing, though, is that the shadow doesn't disappear right away.  If it is visible, and I drag Form2 and drop it over the Form1, then the shadow disappears, and it doesn't come back unless I drag it completely away from Form1.

Bob
0
 
Bob LearnedCommented:
If I drag Form2 without letting go of the mouse, then the shadow doesn't disappear.

Bob
0
 
Bob LearnedCommented:
I discovered the &H20000 is CS_DROPSHADOW.  For documentation purposes, I would override this way:

    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Const CS_DROPSHADOW As Integer = &H20000
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ClassStyle = cp.ClassStyle Or CS_DROPSHADOW
            Return cp
        End Get
    End Property

Bob
0
 
slabrie99Author Commented:
You're right. And when the shadow disappears, I suspect the shadow to be under Form1!

I think the owner Form1 is called because Form2 is modal. When it's called, it raises his Z-order(something like that!) and Form2 forgets to put its shadow on top of form1.

I just don't know how to correct this bug!?!
0
 
Bob LearnedCommented:
Yeah, I found out that the problem is with the call to ReleaseCapture in the ShowModal method, but I haven't found a workaround yet.

Bob
0
 
slabrie99Author Commented:
Great!! Let me know if you find the workaround.  I will take a look at the ReleaseCapture.
0
 
Bob LearnedCommented:
Here is the code from the framework, generated by Reflector:

Public Function ShowDialog(ByVal owner As IWin32Window) As DialogResult
      If (owner Is Me) Then
            Throw New ArgumentException(SR.GetString("OwnsSelfOrOwner", New Object() { "showDialog" }), "owner")
      End If
      If MyBase.Visible Then
            Throw New InvalidOperationException(SR.GetString("ShowDialogOnVisible", New Object() { "showDialog" }))
      End If
      If Not MyBase.Enabled Then
            Throw New InvalidOperationException(SR.GetString("ShowDialogOnDisabled", New Object() { "showDialog" }))
      End If
      If Not Me.TopLevel Then
            Throw New InvalidOperationException(SR.GetString("ShowDialogOnNonTopLevel", New Object() { "showDialog" }))
      End If
      If Me.Modal Then
            Throw New InvalidOperationException(SR.GetString("ShowDialogOnModal", New Object() { "showDialog" }))
      End If
      If Not SystemInformation.UserInteractive Then
            Throw New InvalidOperationException(SR.GetString("CantShowModalOnNonInteractive"))
      End If
      If (((Not owner Is Nothing) AndAlso ((CInt(UnsafeNativeMethods.GetWindowLong(New HandleRef(owner, owner.Handle), -20)) And 8) = 0)) AndAlso TypeOf owner Is Control) Then
            owner = DirectCast(owner, Control).TopLevelControl
      End If
      Me.calledOnLoad = False
      Me.calledMakeVisible = False
      Dim ptr1 As IntPtr = UnsafeNativeMethods.GetCapture
      If (ptr1 <> IntPtr.Zero) Then
            UnsafeNativeMethods.SendMessage(New HandleRef(Nothing, ptr1), 31, IntPtr.Zero, IntPtr.Zero)
            SafeNativeMethods.ReleaseCapture
      End If
      Dim ptr2 As IntPtr = UnsafeNativeMethods.GetActiveWindow
      Dim ptr3 As IntPtr = IIf((owner Is Nothing), ptr2, owner.Handle)
      Dim ptr4 As IntPtr = IntPtr.Zero
      MyBase.Properties.SetObject(Form.PropDialogOwner, owner)
      Dim form1 As Form = Me.OwnerInternal
      If (TypeOf owner Is Form AndAlso (Not owner Is form1)) Then
            Me.Owner = DirectCast(owner, Form)
      End If
      Try
            MyBase.SetState(32, True)
            Me.dialogResult = DialogResult.None
            MyBase.CreateControl
            If ((ptr3 <> IntPtr.Zero) AndAlso (ptr3 <> MyBase.Handle)) Then
                  If (UnsafeNativeMethods.GetWindowLong(New HandleRef(owner, ptr3), -8) = MyBase.Handle) Then
                        Throw New ArgumentException(SR.GetString("OwnsSelfOrOwner", New Object() { "showDialog" }), "owner")
                  End If
                  UnsafeNativeMethods.GetWindowLong(New HandleRef(Me, MyBase.Handle), -8)
                  UnsafeNativeMethods.SetWindowLong(New HandleRef(Me, MyBase.Handle), -8, New HandleRef(owner, ptr3))
            End If
            Try
                  MyBase.Visible = True
                  If (Me.dialogResult = DialogResult.None) Then
                        Application.RunDialog(Me)
                  End If
            Finally
                  If Not UnsafeNativeMethods.IsWindow(New HandleRef(Nothing, ptr2)) Then
                        ptr2 = ptr3
                  End If
                  If (UnsafeNativeMethods.IsWindow(New HandleRef(Nothing, ptr2)) AndAlso SafeNativeMethods.IsWindowVisible(New HandleRef(Nothing, ptr2))) Then
                        UnsafeNativeMethods.SetActiveWindow(New HandleRef(Nothing, ptr2))
                  End If
                  Me.SetVisibleCore(False)
                  If MyBase.IsHandleCreated Then
                        IntSecurity.ManipulateWndProcAndHandles.Assert
                        Try
                              Me.DestroyHandle
                        Finally
                              CodeAccessPermission.RevertAssert
                        End Try
                  End If
                  MyBase.SetState(32, False)
            End Try
      Finally
            Me.Owner = form1
            MyBase.Properties.SetObject(Form.PropDialogOwner, Nothing)
      End Try
      Return Me.DialogResult
End Function


You can see this line half way down the method:

SafeNativeMethods.ReleaseCapture

Bob
0
 
slabrie99Author Commented:
I can't find other solution than simulating a modal form.
Thanks.
0
All Courses

From novice to tech pro — start learning today.