How to get IWin32Window for Show/ShowDialog in Excel
-
Tuesday, June 20, 2006 11:00 AMIn my workbook.cs file I am trying to open a form, I need a handle to excel to pass into the Show/ShowDialog method for the IWin32Window parameter so that the dialog doesn't get hidden.
All Replies
-
Tuesday, June 20, 2006 2:00 PMModeratorI'm not 100% sure on this one, but I think you may be looking for XLMAIN (OpusApp for Word, OMain for Office, PPFrameClass for PowerPoint) - the "parent names" for the application windows.
-
Tuesday, June 20, 2006 4:15 PMAnswerer
Hi,
Excel exposes the window handle of the application via the Hwnd property. It is returned as an integer, so you will need to wrap an IntPtr around it in order to use it.
Form form = new Form(); NativeWindow xlMain = new NativeWindow();xlMain.AssignHandle(
new IntPtr(Application.Hwnd));form.ShowDialog(xlMain);
form.Dispose();
xlMain.ReleaseHandle();
Sincerely,
Geoff Darst
Microsoft VSTO Team
-
Wednesday, June 21, 2006 11:55 AMI seem to be getting a unhandled exception when Excel is closing. "An unhandled exception ('System.AppDomainUnloadedException') occured in EXCEL.EXE[1028]
I got this from debugging EXCEL.exe
Unhandled exception at 0x7c81eb33 in EXCEL.EXE: 0xE0434F4D: 0xe0434f4d.
I am calling the dispose method on all forms that use xlMain and the xlMain.ReleaseHandle() in the ThisWorkbook_Shutdown method
removing all xlMain stuff from the code solves the problem. -
Wednesday, June 21, 2006 10:20 PMI have this same problem, but with Outlook. Can I get a handle to the Outlook main window to pass to the Show method of a form. Otherwise, my form gets hidden when the form that created it is closed.
-
Thursday, June 22, 2006 12:31 AMAnswerer
Yes, unfortunately that is expected. You must release your subclass on the main Excel window prior to Shutdown. The reason for this is that the loader calls shutdown in response to the main Excel window closing. So if you have not called ReleaseHandle prior to Excel's main window closing, the WM_CLOSE will first get dispatched to the NativeWindow's managed WndProc. This puts managed code on the stack below the loader shutdown code. So the loader calls shutdown and unloads the AppDomain, but then the stack continues to unwind and it encounters managed code. Since the AppDomain has been unloaded, an AppDomainUnloadedException is thrown, but since there is no handler available, Excel crashes.
To work around this, I think you are just going to want to AssignHandle/ReleaseHandle for xlmain around each call to Form.ShowDialog. This is probably the best solution since I can't think of a replacement event that would work for you (Workbook_BeforeClose is tied to WM_CLOSE and will exhibit the same crash).
Sincerely,
Geoff Darst
Microsoft VSTO Team
-
Thursday, June 22, 2006 2:58 PMThanks Geoff,
Finally got it -
Tuesday, September 19, 2006 5:46 AM
Try this
public static class DialogService
{
public static DialogResult ShowDialog(Form dialog)
{
NativeWindow mainWindow = new NativeWindow();
mainWindow.AssignHandle(Process.GetCurrentProcess().MainWindowHandle);
DialogResult dialogResult = dialog.ShowDialog(mainWindow);
mainWindow.ReleaseHandle();
return dialogResult;
}
} -
Friday, October 26, 2007 2:21 AMI am also trying to display a c# form from excel. It all works fine. However, when I move the form around, it leaves a trace behind. What is the best way to handle this?
-
Wednesday, January 14, 2009 2:02 PM
Hi
I've seen here a solution for ShowDialog but what about Show. What is the best solution to release the handle?
Is it good to release the handle after Show
Form form = new Form(); NativeWindow xlMain = new NativeWindow(); xlMain.AssignHandle(new IntPtr(Application.Hwnd)); form.Show(xlMain); xlMain.ReleaseHandle(); -
Wednesday, January 28, 2009 3:53 PMAnswerer
Hi,
In the context of a NativeWindow, you probably want to relase the handle. What the NativeWindow class does is it subclasses the window identified by the passed in handle. If you are not familiar with subclassing, what this means is that NativeWindow is installing its own window procecedure and handling windows messages for that window (and delegating as necessary to the window procedure of the subclassed window). The situation that you want to avoid is a case where the NativeWindow is destroyed, but the window being subclassed is still alive. If that ever happened, the next attempt to dispatch a windows message to the window would crash when attempting to call the NativeWindow's subclass procedure which no longer exists in memory. NativeWindow attempts to mitigate this by preventing garbage collection as long as it has a handle associated with it. However, I suspect that if you tear down the AppDomain (i.e. when closing the customization) without first relasing the handle, you would be risking a crash (depending on shutdown ordering and whether the window you are subclassing is still around at that point). Also, if the window being subclassed is destroyed (assuming the NativeWindow object is still around) then NativeWindow will automatically release the handle.
If you don't need to subclass, you may be better off providing your own IWin32Window implementation. That way you can avoid all of the issues around subclassing.
Sincerely,
Geoff Darst
Microsoft VSTO Team
-
Monday, June 15, 2009 10:28 PMHi, In the ThisWorkbook_Shutdown is it safe to still create the new NativeWindow and then release it before Shutdown returns? In the case of an error occurring in my code in ThisWorkbook_Shutdown, I show an error dialog using the code snippets above. After the user closes it, I release the handle. So far it seems to be OK but I'm worried that it's just been the case where it "happens" to have worked.
And would it be safe for the extension class to keep a static reference to the Application object (set at ThisWorkbook_Startup) to create the NativeWindow with?
Thanks!- Edited by sleepp Tuesday, June 16, 2009 1:53 PM

