我尝试从VSTO加载项继承Excel 2010的主窗口。当程序关闭时,这会导致异常和Excel崩溃。
所以我创建了一个小例子来重现我机器上的错误。显然,当调用WM_CLOSE时,对CallWindowProc的调用会抛出一个ThreadAbortException。
Public Class ThisAddIn
Private Const GWL_WNDPROC As Integer = -4
Private Delegate Function WndProcDelegate( _
ByVal hWnd As IntPtr, _
ByVal msg As Int32, _
ByVal wParam As Int32, _
ByVal lParam As Int32) As Int32
Private Declare Function SetWindowLong _
Lib "user32.dll" Alias "SetWindowLongA" ( _
ByVal hWnd As IntPtr, _
ByVal nIndex As Int32, _
ByVal dwNewLong As IntPtr) As Int32
Private Declare Function SetWindowLong _
Lib "user32.dll" Alias "SetWindowLongA" ( _
ByVal hWnd As IntPtr, _
ByVal nIndex As Int32, _
ByVal dwNewLong As WndProcDelegate) As IntPtr
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As IntPtr, ByVal hWnd As IntPtr, ByVal msg As Integer, _
ByVal wParam As Integer, ByVal lParam As Integer) As Integer
<System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.FunctionPtr)> _
Private mWndProc As WndProcDelegate
Private mPrevWindowProc As IntPtr
Private Sub ThisAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup
mWndProc = New WndProcDelegate(AddressOf SubWndProc)
mPrevWindowProc = SetWindowLong(New IntPtr(Application.Hwnd), GWL_WNDPROC, mWndProc)
End Sub
Private Sub ThisAddIn_Shutdown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shutdown
SetWindowLong(New IntPtr(Application.Hwnd), GWL_WNDPROC, mPrevWindowProc)
End Sub
Private Function SubWndProc( _
ByVal hWnd As IntPtr, _
ByVal msg As Int32, _
ByVal wParam As Int32, _
ByVal lParam As Int32) As Int32
Try
Return CallWindowProc(mPrevWindowProc, hWnd, msg, wParam, lParam)
Catch ex As Exception
Windows.Forms.MessageBox.Show(ex.ToString)
End Try
End Function
End Class
这是发生在我的机器上还是我做错了什么?
顺便说一句,如果我在WM_CLOSE或WM_DESTROY事件中恢复WndProc没有任何区别,Excel会崩溃。Excel 2010,Windows XP,VS 2008