Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: VB.NET
I am trying to attach my VB .net userform to an existing application (CATIA) such that when the parent application window is minimized, so is my userform. And when the parent application is active, I want my userform to stay on top. I have achieved this by using the SetParent windows API but would prefer that my userform not be restricted inside the parent application window border. Basically I would like my form to behave just like a VBA form.
 
I have considered creating an out process to monitor the parent application window and control my userform based on its activation state, but this seems overly complicated.
 
I would appreciate any help anyone can offer.
Posted 30-Nov-12 8:42am
Comments
Sergey Alexandrovich Kryukov at 30-Nov-12 14:48pm
   
Why? All your development well-being depends on how well can you avoid any behavior like VBA, VB6 and the like. :-)
--SA
Daniel Husted at 30-Nov-12 16:06pm
   
Sergey, Thanks so much for your prompt reply.
I think perhaps I misled you with my question. I my case the parent application is an off the shelf CAD package (CATIA) for which I writing a companion application. I want my application to appear to be an extension of CATIA, but I have no access to their code.
 
I am now working on trying to attach my userform to CATIA's main window using an IWin32Window parameter in the "Show" method call. But I an having mixed results perhaps because of some of the things you were cautioning me about. I will report back when I have more definitive results.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Don't do it! By using VB.NET, you are partially entering the world of applications behaving consistently and according to proper UI style.
 
In .NET, child-parent relationships between forms are intentionally rendered defunct. A Form is a Control, and for Controls, you can make another a Control a parent; this is a basis of control hierarchy. However, it you would-be-a-child Control is a Form, exception will be thrown, for a good reason.
 
Now, you can override this behavior by setting the property Form.TopLevel to true. It will make this form able to become a child, but — don't do it!. You will getg an ugly result of the form, with all its non-client areas, "restricted inside the parent application window border".
 
Please see:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.aspx[^],
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.toplevel.aspx[^].
 
To achieve proper UI look and behavior, do the following: make what you has as a candidate for a child Form a non-Form Control, typically Panel. If can host all the content you Form had. And then, make this Panel a child of some Form or another Panel. Are you getting the point? Ideally, all your application can be just one main form, and all the rest would be the children of this form. Another good but simple possibility is using the class System.Windows.Forms.TabPage which is a part of System.Windows.Forms.TabControl:
http://msdn.microsoft.com/en-us/library/system.windows.forms.tabpage.aspx[^],
http://msdn.microsoft.com/en-us/library/system.windows.forms.tabcontrol.aspx[^].
 
In the TabControl approach, each TabPage will play the role of what you pictured as a child form.
 
And finally, one big warning! One other solution is MDI, MDI parents and MDI children. Don't go this way, stay out of trouble and avoid scaring off your customers. Some motivation here:
http://en.wikipedia.org/wiki/Multiple_document_interface#Disadvantages[^],
How to Create MDI Parent Window in WPF?[^].
 
Also, some motivation in my past answers:
How to Create MDI Parent Window in WPF? [Solution 2],
Question on using MDI windows in WPF[^],
MDIContainer giving error[^],
How to set child forms maximized, last childform minimized[^].
 
Good luck, stay out of trouble,
—SA
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

The problem was easier than I thought. I just needed to write a class to convert an IntPtr to IWin32Window
Public Class WindowWrapper
    Implements System.Windows.Forms.IWin32Window
 
    Private _hwnd As IntPtr
 
    Public Sub New(ByVal handle As IntPtr)
        _hwnd = handle
    End Sub
 
    Public ReadOnly Property Handle() As IntPtr Implements System.Windows.Forms.IWin32Window.Handle
        Get
            Return _hwnd
        End Get
    End Property
 
End Class
 
Then implement it when I show my userform. I added this line to the end of my "New" sub in the form class:
Me.Show(New WindowWrapper(Application.Hwnd)
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Advertise | Privacy | Mobile
Web01 | 2.8.140926.1 | Last Updated 5 Dec 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100