Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Visual Studio.NET / Extensibility / February 2005

Tip: Looking for answers? Try searching our database.

How to create a non-modal dialog that stays on top of the IDE in an add-in?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Matthew Korth - 15 Feb 2005 15:40 GMT
I've been wrestling with this one for a while now.

The add-in I'm working on builds several solutions in sequence.  I'd
like to have a "master status" dialog that updates as each build is
completed, so that the user can keep track of how far along the entire
build is.  The dialog needs to be displayed non-modally, to allow the
build to proceed while it's being displayed.

Problem is, I can't figure out how to get this to happen.  I'm working
in C# and VS.NET 2003.

In the class that invokes this (BuildConversion), I've got this:

private BuildStatus m_Status;

In the BuildConversion.Build member function, the dialog is shown using
this code:

m_Status = new BuildStatus();
m_Status.Show();

The problem is that the window thus created vanishes (that is, is no
longer on top of the IDE) when this line is executed:

m_DTE.Solution.Open(SolutionName);

The information I've found says that I need to set m_Status.Owner to
the form I want m_Status to stay on top of.  My attempts to set
m_Status.Owner have been, shall we say, less than successful.
m_DTE.MainWindow can't be used directly (as EnvDTE.Window and
System.Windows.Forms.Form are incompatible types), so I tried this:

System.Windows.Forms.Form MainForm =
    (Form)Form.FromHandle(new IntPtr(m_DTE.MainWindow.HWnd));
m_Status.Owner = MainForm;

The problem here is that Form.FromHandle() appears to always be
returning a null reference.  (Form.FromChildHandle() does the same.)
I've also tried going through System.Diagnostics.Process to get the
handle for the main devenv window, with similar (lack of) success.

Any suggestions or alternative approaches would be greatly
appreciated...

--M
Carlos J. Quintero [.NET MVP] - 16 Feb 2005 10:22 GMT
Non modal forms of .NET don´t work well with VS.NET (focus problems and
others). The only (recommended) way to have non-modal forms in VS.NET is
through toolwindows, created with CreateToolWindow function and using an
ActiveX shim control to host your .NET user control. See the Files section
of http://groups.yahoo.com/group/vsnetaddin/ about shim controls.

Signature

Carlos J. Quintero

MZ-Tools 4.0: Productivity add-ins for Visual Studio .NET
You can code, design and document much faster.
http://www.mztools.com

> I've been wrestling with this one for a while now.
>
[quoted text clipped - 41 lines]
>
> --M
Matthew Korth - 16 Feb 2005 14:55 GMT
> Non modal forms of .NET don4t work well with VS.NET (focus problems
> and others). The only (recommended) way to have non-modal forms in
> VS.NET is through toolwindows, created with CreateToolWindow function
> and using an ActiveX shim control to host your .NET user control. See
> the Files section of http://groups.yahoo.com/group/vsnetaddin/ about
> shim controls.

Hmm.  Okay, then, according to the readme in VSUserControlHost.zip:

    "Because .NET UserControls are not ActiveX controls, a
    UserControl cannot be directly hosted on a tool window."

The question I'd then have is, why can a UserControl not be hosted
directly on a tool window?  (Or is that just another Microsoftism that
I'll have to learn to live without an explanation for?)

Regardless, I found a workaround.  I'd been trying to have my builder
code spawn off a non-modal dialog.  My workaround was to create the
dialog as a modal dialog, then have the dialog spawn the builder code.
That seems to do almost exactly what I want.  I don't seem to be able
to set the focus to the dialog with the mouse, but it stays on top of
the IDE and that's what's important in this case.

Oh, and thanks. :)

--M
Carlos J. Quintero [.NET MVP] - 16 Feb 2005 16:34 GMT
> "Because .NET UserControls are not ActiveX controls, a UserControl cannot
> be directly hosted on a tool window."
> The question I'd then have is, why can a UserControl not be hosted
> directly on a tool window?  (Or is that just another Microsoftism that
> I'll have to learn to live without an explanation for?)

Don´t get me started about the damned shim controls...

Signature

Carlos J. Quintero

MZ-Tools 4.0: Productivity add-ins for Visual Studio .NET
You can code, design and document much faster.
http://www.mztools.com

Matthew Korth - 16 Feb 2005 18:42 GMT
> > "Because .NET UserControls are not ActiveX controls, a UserControl
> > cannot be directly hosted on a tool window."
[quoted text clipped - 3 lines]
>
> Don4t get me started about the damned shim controls...

Ah.  One of THOSE things. :)
"Ed Dore [MSFT]" - 16 Feb 2005 21:34 GMT
Heh heh, I think I like Carlos's answer better<g>.

There isn't a good interop story with respect to hosting .net
controls/winforms, in native Win32 applications. The VS .Net IDE is almost
completely a creature of C++, ATL, and COM. This is primarily due to the
fact that when the IDE was initially created, large portions of .NET were
still on a white board.

The good news is that for VS 2005 (aka Whidbey) that shim control will be
history.

One other suggestion would be to kick off a 2nd thread that displayed your
modeless dialog, and use PInvoke to call the SetParent API to parent the
dialog on the main IDE window. That could be a bit tricky though, as you'll
have to find a way to get the HWND of the main IDE window. It isn't exposed
through the VS automation stuff, so you'd probably have to use some
additional Win32 API's like FindWindow, GetCurrentProcess, and
GetWindowProcessID to retrieve the HWND. You'd also need to come up with a
way to communicate across the thread boundary, via messaging or mashalling
interfaces.

Sincerely,
Ed Dore [MSFT]

This post is 'AS IS' with no warranties, and confers no rights.
Matthew Korth - 18 Feb 2005 17:16 GMT
> One other suggestion would be to kick off a 2nd thread that displayed
> your modeless dialog, and use PInvoke to call the SetParent API to
[quoted text clipped - 5 lines]
> also need to come up with a way to communicate across the thread
> boundary, via messaging or mashalling interfaces.

I tried creating the dialog in a separate thread, but as I've never
done multithreaded programming before I'm pretty sure I screwed it up.
:P

And if the HWND for the main IDE window isn't exposed, what's
EnvDTE.MainWindow.HWnd?

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.