Альтернативы NativeWindow для создания подклассов

Я подклассифицировать окно Win32 в управляемом коде, используя NativeWindow. Тем не менее, я сталкиваюсь с ошибкой в ​​моем коде или в NativeWindow, которая выдает исключение при закрытии родителя. Код, который я использую, это:

public partial class ThisAddIn
{
    private VisioWindow visioWindow;
    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        visioWindow = new VisioWindow();
        visioWindow.AssignHandle(new IntPtr(this.Application.Window.WindowHandle32));
    }

    private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
    {
        visioWindow.ReleaseHandle();
    }

    #region VSTO generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InternalStartup()
    {
        this.Startup += new System.EventHandler(ThisAddIn_Startup);
        this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
    }

    #endregion

    public class VisioWindow : NativeWindow
    {
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
        }
    }
}

При выходе из основной программы я получаю эту ошибку:

A first chance exception of type 'System.Threading.ThreadAbortException' occurred in System.Windows.Forms.dll
A first chance exception of type 'System.Threading.ThreadAbortException' occurred in System.Windows.Forms.dll

И This program has encountered an error показывает, что родитель столкнулся с ошибкой

Есть ли другой способ переопределить родительский WndProc, чем с помощью NativeWindow? Или в этом коде есть ошибка, которая может быть исправлена?

Благодарю.

2 ответа

Решение

Мне не совсем понятно, почему это обрушится. Используйте Debug + Exception, флаг Thrown, чтобы выяснить, откуда исходит исключение ThreadAbort. Одна вещь определенно не так, вы должны отсоединить ручку, когда окно разрушено. Вы можете сделать это, наблюдая за сообщением WM_NCDESTROY:

protected override void WndProc(ref Message m) {
  base.WndProc(ref m);
  if (m.Msg == 0x82) this.ReleaseHandle();
}

Microsoft решает эту проблему: https://blogs.msdn.microsoft.com/anandgeorge/2010/04/10/usage-of-nativewindow-assignhandlereleasehandle-when-unmanaged-code-is-involved/

когда мы вызываем NativeWindow.ReleaseHandle, вызов заменит winproc на User32!DefWindowProc[this] будет вызывать сбой приложения большую часть времени.

Вот решение Microsoft: https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/99/38/21/Sample.zip

Справочная информация о том, почему это предпочтительный способ решения этой проблемы: https://blogs.msdn.microsoft.com/oldnewthing/20031111-00/?p=41883

Другие вопросы по тегам