2009-07-18 1 views
1

Je sous-classe une fenêtre Win32 dans le code managé en utilisant NativeWindow. Cependant, je rencontre un bogue dans mon code ou avec NativeWindow qui déclenche une exception lorsque le parent est fermé. Le code J'utilise est le suivant:Alternatives à NativeWindow pour la sous-classe

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 la sortie du programme principal, je reçois cette erreur:

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 

Et le This program has encountered an error montre en disant le parent a rencontré une erreur.

Existe-t-il une autre manière de remplacer le WndProc du parent que d'utiliser NativeWindow? Ou y a-t-il un bug dans ce code qui pourrait être résolu?

Merci.

Répondre

2

Il n'est pas vraiment clair pour moi pourquoi il tomberait en panne. Utilisez l'option Debug + Exception, Thrown flag pour savoir d'où provient l'exception ThreadAbort. Une chose est définitivement fausse, vous devriez détacher la poignée lorsque la fenêtre est détruite. Vous pouvez le faire en regardant le message WM_NCDESTROY:

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

J'ai essayé de faire exactement cela. Je ne reçois jamais WM_NCDESTROY du parent. Le dernier message que je reçois est WM_PARENTNOTIFY. J'avais relâché la poignée dans mon code d'arrêt, je l'ai juste oublié ici. J'ai placé les exceptions Thrown et User-Unhandled dans le menu Debugging-> Exceptions, c'est ce que vous vouliez dire? J'ai l'impression que l'exception vient du parent. Je devrais noter que ceci est le code nu d'un plus grand programme que j'ai (mais c'est une version autonome), et ce code cause définitivement l'erreur. Sans AssignHandle au parent, je ne reçois jamais l'erreur. – Max

+0

Si j'attrape WM_CLOSE et puis relâchez le handle là, j'évite l'exception d'abandon de thread des formulaires Windows. Merci. – Max

+0

Il peut être dangereux de libérer le handle lorsque WM_CLOSE est intercepté, car il peut y avoir des documents non sauvegardés. Si l'utilisateur décide d'abandonner l'opération de fermeture, l'application Office reste active ... – jreichert

1

Microsoft résout ce problème: 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.

ici est la solution de Microsoft: https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/99/38/21/Sample.zip

fond pourquoi c'est le meilleur moyen de résoudre ce problème: https://blogs.msdn.microsoft.com/oldnewthing/20031111-00/?p=41883