none
How to get IWin32Window for Show/ShowDialog in Excel

    Question

  • In 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.

    Tuesday, June 20, 2006 11:00 AM

Answers

  • 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

    Tuesday, June 20, 2006 4:15 PM
    Answerer
  • 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 12:31 AM
    Answerer

All replies

  • I'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 2:00 PM
    Moderator
  • 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

    Tuesday, June 20, 2006 4:15 PM
    Answerer
  • I 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 11:55 AM
  • I 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.
    Wednesday, June 21, 2006 10:20 PM
  • 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 12:31 AM
    Answerer
  • Thanks Geoff,
    Finally got it
    Thursday, June 22, 2006 2:58 PM
  • 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;
    }
    }

    Tuesday, September 19, 2006 5:46 AM
  • I 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?

     

    Friday, October 26, 2007 2:21 AM

  • 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 14, 2009 2:02 PM
  • 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

    Wednesday, January 28, 2009 3:53 PM
    Answerer
  • Hi, 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
    Monday, June 15, 2009 10:28 PM
  • Hello Geoff,

    do you have any idea for my VSTO Add-In modal window problem as described at http://stackoverflow.com/questions/20688734/modal-dialog-vanishes-and-cant-be-reactivated-with-windows-taskbar?

    I'm desperate, 
    Jörg


    • Edited by jreichert Friday, January 03, 2014 2:38 PM
    Friday, January 03, 2014 2:37 PM