2009-07-18 22 views
1

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は親がエラーを検出したと言って現れます。

NativeWindowを使用するよりも、親のWndProcをオーバーライドする別の方法はありますか?あるいは、このコードにはうまくいくバグがありますか?

ありがとうございました。

答えて

2

なぜそれがクラッシュするのかは私にはっきりと分かりません。 Debug + Exception、Thrownフラグを使用して、ThreadAbort例外がどこから来ているかを調べます。 1つのことは間違っている間違いです、あなたはウィンドウが破壊されたときにハンドルを取り外す必要があります。あなたは、WM_NCDESTROYメッセージを見て、これを行うことができます:

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

私はちょうどそれをやってみました。私は親からWM_NCDESTROYを取得することはありません。私が最後に受けるメッセージはWM_PARENTNOTIFYです。私はシャットダウンコードでハンドルを解放していましたが、ここではそれを忘れました。私はThrowとUser-Unhandledの例外をDebugging-> Exceptionsメニューに置きました。それはあなたが正しいことを意味していますか?私は例外が親から来ているように感じる。私はこれが私が持っている大きなプログラムの裸のコードであることに注意してください(しかし、これはスタンドアロンバージョンです)、このコードは間違いなくエラーを引き起こしています。親にAssignHandleがなければ、エラーは発生しません。 – Max

+0

WM_CLOSEを捕まえてそこのハンドルを解放すると、Windowsフォームからのスレッドの中止の例外が回避されます。 ありがとうございます。 – Max

+0

保存されていないドキュメントがある可能性があるため、WM_CLOSEがキャッチされているときにハンドルを解放すると危険です。ユーザーが操作を中止することを決定した場合、Officeアプリケーションは有効になります。 – jreichert

1

マイクロソフトでは、この問題に対処します。ここ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.

は、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

関連する問題