2009-07-18 9 views
1

Ich untergliedere ein Win32-Fenster in verwaltetem Code mit NativeWindow. Ich habe jedoch einen Fehler in meinem Code oder mit NativeWindow, der eine Ausnahme auslöst, wenn der Elternteil geschlossen ist. Der Code ich verwende, ist dies:Alternativen zu NativeWindow für Unterklassen

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); 
     } 
    } 
} 

Am Ausgang des Hauptprogramms, ich diesen Fehler:

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 

Und die This program has encountered an error zeigt sich sagen die Eltern ein Fehler aufgetreten.

Gibt es eine andere Möglichkeit, den WndProc des Parents außer Kraft zu setzen als mit NativeWindow? Oder gibt es einen Fehler in diesem Code, der ausgearbeitet werden könnte?

Danke.

Antwort

2

Es ist mir nicht ganz klar, warum es stürzen würde. Verwenden Sie Debug + Exception, Thrown-Flag, um herauszufinden, woher die ThreadAbort-Ausnahme kommt. Eine Sache ist definitiv falsch, du solltest den Griff lösen, wenn das Fenster zerstört ist. Sie können dies tun, indem sie für die WM_NCDESTROY Nachricht beobachten:

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

Ich habe versucht, genau das zu tun. Ich bekomme WM_NCDESTROY niemals vom Elternteil. Die letzte Nachricht, die ich bekomme, ist WM_PARENTNOTIFY. Ich hatte den Griff in meinem Shutdown-Code freigegeben, ich habe es hier vergessen. Ich habe die Exceptions Thrown und User-Unhandled im Debugging-> Exceptions-Menü aktiviert, was meinst du damit? Ich fühle, dass die Ausnahme vom Elternteil kommt. Ich sollte beachten, dass dies der nackte Code eines größeren Programms ist, das ich habe (aber das ist eine eigenständige Version), und dieser Code verursacht definitiv den Fehler. Ohne AssignHandle zum Eltern, bekomme ich nie den Fehler. – Max

+0

Wenn ich WM_CLOSE abfangen und das Handle dort freigeben, vermeide ich die Thread-Abbruch-Ausnahme von Windows-Formularen. Danke. – Max

+0

Es kann gefährlich sein, das Handle freizugeben, wenn WM_CLOSE abgefangen wird, da möglicherweise nicht gespeicherte Dokumente vorhanden sind. Wenn der Benutzer entscheidet, den Vorgang abzubrechen, wird die Office-Anwendung auf ... – jreichert

1

Microsoft befasst sich mit diesem Problem: https://blogs.msdn.microsoft.com/anandgeorge/2010/04/10/usage-of-nativewindow-assignhandlereleasehandle-when-unmanaged-code-is-involved/

when we call NativeWindow.ReleaseHandle, the call will replace the winproc with User32!DefWindowProc[this] will cause the application crash most of the time.

hier ist Microsofts Lösung: https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/99/38/21/Sample.zip

Hintergrund auf, warum dies ist die bevorzugte Art und Weise zu löse dieses Problem: https://blogs.msdn.microsoft.com/oldnewthing/20031111-00/?p=41883