问题
I have an excel add-in and i have a form that i would like to be front of excel window. I use NativeWindow
for this purpose on excel ribbon menu button like this:
public partial class MyRibbonMenu
{
public List<Form> Forms = new List<Form>();
private void button1_Click(object sender, RibbonControlEventArgs e)
{
// initialize form
Form frm = new Form();
frm.Text = "Test Form";
Forms.Add(frm);
// create the native window handle
NativeWindow nw = new NativeWindow();
IntPtr iptr = new IntPtr(Globals.ThisAddIn.Application.Hwnd);
nw.AssignHandle(iptr);
// when close the form release the handle
frm.FormClosed += (sender2, e2) =>
{
Forms.Remove(frm);
nw.ReleaseHandle();
};
// show with owner
frm.Show(nw);
}
}
If I close my form before exit from excel everything is ok, this works very well. But if user wants to exit from excel without close the opened form then ThreadAbortException
exception occurs:
An unhandled exception of type 'System.Threading.ThreadAbortException' occurred in System.Windows.Forms.dll
Additional information: Thread was being aborted.
For resolve this problem I have tried the following code but didn't work:
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
var frms = Globals.Ribbons.MyRibbonMenu.Forms.ToArray();
foreach (var frm in frms)
{
frm.Close();
}
}
Where can I making a mistake?
回答1:
I resolve the problem with use IWin32Window
interface instead NativeWindow
:
public class Win32Window : System.Windows.Forms.IWin32Window
{
public Win32Window(int windowHandle)
{
_windowHandle = new IntPtr(windowHandle);
}
IntPtr _windowHandle;
public IntPtr Handle
{
get { return _windowHandle; }
}
}
After this I change form initialize code below:
private void button1_Click(object sender, RibbonControlEventArgs e)
{
// initialize form
var frm = new Form();
frm.FormBorderStyle = FormBorderStyle.FixedSingle;
frm.MinimizeBox = false;
frm.MaximizeBox = false;
frm.Text = "Test Form";
frm.StartPosition = FormStartPosition.CenterScreen;
Forms.Add(frm);
// create the native window handle
var nw = new Win32Window(Globals.ThisAddIn.Application.Hwnd);
// show with owner
frm.Show(nw);
}
回答2:
Edit: I'm adding my answer here b\c the user answer is a work around and not an explanation of what the problem likely is: i recommend checking out the solution microsoft put out and modify it for your needs.
see my answer here: https://stackoverflow.com/a/38157476/ depending on what window you are trying to listen in on you maybe mucking up an unmanaged window listener and unfortunately NativeWindow.ReleaseHandle does not know how to restore the subclassing window chain and instead replaces the windows wndproc you altered with User32!DefWindowProc[this] which will cause an application crash or hang.
来源:https://stackoverflow.com/questions/23519382/form-showiwin32window-method-in-excel-vsto-causing-threadabortexception-on-app