5

.NET WebBrowser タイプの Close イベントを取得しようとしていますが、そのままでは機能しないようです。(編集:このイベントはwindow.close()、ブラウザで実行されているスクリプトで呼び出しが発行されたときに発生します。)

私が見た 1 つの解決策は、クラスとメソッドを拡張することですWebBrowseroverrideWndProc

私の拡張コードは次のとおりです。

type internal ExtendedBrowser () = class
    inherit System.Windows.Forms.WebBrowser()

    let WM_PARENTNOTIFY : int = 0x0210
    let WM_DESTROY      : int = 0x0002

    let closed : Event<unit> = new Event<unit>()

    do ()

    [<System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")>]
    override this.WndProc (msg : Message byref) =
        match msg.Msg with
        | wm when wm = WM_PARENTNOTIFY ->
            if (not base.DesignMode) && (msg.WParam.ToInt32() = WM_DESTROY)
            then closed.Trigger()
            base.DefWndProc(ref msg)
        | _ ->
            base.WndProc(ref msg)

    member this.Closed = closed.Publish
end

これにより、型のインスタンスがアクセスされたときに例外がスローされます。

Unhandled Exception: System.Reflection.TargetInvocationException: Unable to get the window handle for the 'ExtendedBrowser' control. Windowless ActiveX controls are not supported. ---> System.ComponentModel.Win32Exception: Error creating window handle.
   at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
   at System.Windows.Forms.Control.CreateHandle()
   at System.Windows.Forms.Control.get_Handle()
   at System.Windows.Forms.WebBrowserBase.DoVerb(Int32 verb)
   at System.Windows.Forms.WebBrowserBase.TransitionFromRunningToInPlaceActive()

   --- End of inner exception stack trace ---
   at System.Windows.Forms.WebBrowserBase.TransitionFromRunningToInPlaceActive()

   at System.Windows.Forms.WebBrowserBase.TransitionUpTo(AXState state)
   at System.Windows.Forms.WebBrowser.get_AxIWebBrowser2()
   at System.Windows.Forms.WebBrowser.PerformNavigate2(Object& URL, Object& flag
s, Object& targetFrameName, Object& postData, Object& headers)
   at System.Windows.Forms.WebBrowser.Navigate(String urlString)
   at [PRODUCT].Application.WebBrowser..ctor() in C:\[PATH]\WebBrowser.fs:line 107
   at Program.Main.main(String[] args) in C:\[PATH]\Program.fs:line 79
Press any key to continue . . .

Navigate("about:blank")現在、(インスタンスの構築後の最初のアクセス) への呼び出しでエラーが発生しています。オーバーライドをコメントアウトすると、WndProc正常に動作します (閉じるイベントがないことを除いて)。

オーバーライドにセキュリティ属性をWndProc設定する必要があると誰かが言ったので、それを実行しましたが、問題は解決しませんでした。

他の誰かがDEP を無効にできると言っていましたが、試してみましたが、EXE を免除することはできませんでした。

拡張機能のインスタンスはブラウザー (WebBrowser とも呼ばれます) のラッパーで作成され、このインスタンスはmain[STAThread] で実行されている my で作成されています (これも必要と思われます)。

誰が何がうまくいかないのか知っていますか?

(私が本当に求めているのは、クローズイベントの通知を受け取る方法です。そのため、誰かがその別のルートを知っていれば、喜んで聞いてくれます。)

4

2 に答える 2

1

他の誰かがF# で WndProc メソッドをオーバーライドするという同じ問題を抱えていた投稿を見つけましたが、そこでの解決策は私にとってはうまくいきました。作業コードは次のとおりです。

type ExtendedWebBrowser () = class
    inherit System.Windows.Forms.WebBrowser()

    let WM_PARENTNOTIFY : int = 0x0210
    let WM_DESTROY      : int = 0x0002

    let closed : Event<unit> = new Event<unit>()

    do ()

    override this.WndProc (msg : Message byref) =
        match msg.Msg with
        | wm when wm = WM_PARENTNOTIFY ->
            if (not base.DesignMode) && (msg.WParam.ToInt32() = WM_DESTROY)
            then closed.Trigger()
            base.DefWndProc(&msg)
        | _ ->
            base.WndProc(&msg)

    member this.Closed = closed.Publish
end

refF# はC# とは少し違った扱いをしているようです: F# でパラメーターと引数を読み取る-- 参照渡しのセクションを参照してください --ref呼び出しは引数をコピーし、そのコピーを参照セルの値として使用しているようです。msgそのため、私が渡していたのは、オリジナルへの参照ではなく、内容のコピーを含む参照セルでした。address-of 演算子 ( ) は値のアドレスを取得するため、とメソッド&への引数をsでラップするのではなく、それが必要でした。DefWndProcWndProcref

于 2013-01-11T17:08:56.313 に答える
1

コントロールが閉じられたときに通知を受けたいWebBrowser場合は、通常のWebBrowserクラスのインスタンスを作成し、イベントにイベント ハンドラーを追加することができます。これはHandleDestroyed、インスタンスを含むフォーム/コントロールWebBrowserが閉じられたときに発生します。

それでもうまくいかない場合は、ParentプロパティをキャストしてイベントFormをフックしてみてください。FormClosing両方の手法の例については、こちらを参照してください: userControl の HandleDestroyed イベント

于 2013-01-09T22:01:32.800 に答える