Can I get the WinForms form owner setup behavior using hwnd / NativeWindow?

My application is vb6 executable, but some new forms in the system are written in C #. I would like to be able to set the owner property of a C # form using a handle in the main application window so that the dialogs stay on top when you add a tab between my application and other applications.

I can get hwnd of the main application window. I'm not sure what I can do from there?


UPDATE October 20, 2008 at 17:06:

Scott

Thanks for the answer. I overlooked that the parameter of the Show / ShowDialog method was not of type Form - I was looking only at the Owner property.

I changed the code that I use from the above a bit - we have a component that basically loads our forms and calls ShowDialog. My code is as follows:

Form launchTarget = FormFactory.GetForm(xxx); // psuedo-code for generic form loader launchTarget.StartPosition = FormStartPosition.CenterParent; IWin32Window parentWindow = GetWindowFromHwnd(hwnd); launchTarget.ShowDialog(parentWindow); 

GetWindowFromHwnd is the version of your code:

 private IWin32Window GetWindowFromHost(int hwnd) { IWin32Window window = null; IntPtr handle = new IntPtr(hwnd); try { NativeWindow nativeWindow = new NativeWindow(); nativeWindow.AssignHandle(handle); window = nativeWindow; } finally { handle = IntPtr.Zero; } return window; } 

Unfortunately, this is not what I was hoping for. The form is displayed modally, but it does not appear in the correct position and does not stay on top when I leave and return to the parent window. Our modals do not display tasks on the taskbar, so the window would seem to β€œdisappear” (although it is still on the Alt-Tab window list). This means that I may not have a suitable hwnd. If you have any other suggestions, please respond. Thanks again.


UPDATE November 10, 2008 at 16:25

One note - if you include it in a method call in an attempt to /, finally, as in Scott's second post, the call in the finally block should be:

 parentWindow.ReleaseHandle(); 
+6
c # winforms hwnd
source share
2 answers

So, you are calling the C # Windows Form class from VB6, which means you are probably using either Show() or ShowDialog() , right? Both of these methods also accept the IWin32Window parameter, which simply defines an object that returns an IntPtr property called Handle.

So ... you need to add an overloaded constructor (or ShowDialog method) for your Windows Forms classes that take long as a parameter so that you can pass hwnd VB6 to the form. After inside the C # code, you need to create an IntPtr from hwnd and assign it to a NativeWindow , and then pass it as the owner.

Something like this should work, although it has not been verified:

 public DialogResult ShowDialog(long hwnd) { IntPtr handle = new IntPtr(hwnd); try { NativeWindow nativeWindow = new NativeWindow(); nativeWindow.AssignHandle(handle); return this.ShowDialog(nativeWindow); } finally { handle = IntPtr.Zero; } } 
+9
source share

It's too long to post a comment ...

I think the problem you are working with is how you wrapped the code that I presented in the ShowDialog overload. If you follow what your GetWindowFromHost code GetWindowFromHost , it performs the following steps:

  • Creates a new IntPtr from the provided hwnd.
  • Creates a new NativeWindow object and assigns it an IntPtr handle.
  • Sets IntPtr (in the finally block) as IntPtr.Zero.

I think this is finally the block that causes you problems. In my code, the finally block will work after the call to this.ShowDialog(nativeWindow) . At this point, the handle (IntPtr) was no longer used. In your code, you return IWin32Window , which should still contain a reference to this IntPtr, which at the time you call launchTarget.ShowDialog(parentWindow) , is IntPtr.Zero.

Try changing the code to look like this:

 private NativeWindow GetWindowFromHost(int hwnd) { IntPtr handle = new IntPtr(hwnd); NativeWindow nativeWindow = new NativeWindow(); nativeWindow.AssignHandle(handle); return window; } 

And then change your calling code like this:

 Form launchTarget = FormFactory.GetForm(xxx); // psuedo-code for generic form loaderlaunchTarget.StartPosition = FormStartPosition.CenterParent; NativeWindow parentWindow = GetWindowFromHwnd(hwnd); try { launchTarget.ShowDialog(parentWindow); } finally { parentWindow.DestroyHandle(); } 

These changes should work, but again this is not verified.

+2
source share

All Articles