在 .NET 中子类化 Excel 2010 时出现异常

发布于 2024-12-19 23:15:18 字数 2199 浏览 1 评论 0原文

我尝试从 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

I tried to subclass the main window of Excel 2010 from a VSTO add-in. This results in an exception and a crash of Excel when the program closes.

So I created a small example that reproduces the error on my machine. Obviously the call to CallWindowProc throws a ThreadAbortException when called for WM_CLOSE.

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

Is this just happening on my machine or am I doing something wrong?

BTW, it makes no difference if I restore the WndProc in the WM_CLOSE or WM_DESTROY event, Excel crashes all the same.

Excel 2010, Windows XP, VS 2008

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文