6

EZShellExtensions.NETを使用して C# で Windows シェル拡張機能を作成しています。

ダイアログを表示するコンテキスト メニューを提供します。

エクスプローラ ウィンドウ (A) を表示するとします。次に、コンテキスト メニューを使用して、非モーダル ウィンドウ (B) を表示します。

Windows XP と Windows Vista では、A を閉じると B が閉じられます (この動作が必要です)。ただし、Windows 7 では、A を閉じると、B は閉じられませんが、イベントに応答しません。私の質問は次のとおりです。

  • Windows 7 が表示されたフォームを子フォームとして管理する理由を知っていますか?
  • A を閉じた場合にメッセージ ループを維持する方法はありますか?

編集: A を B の所有者として設定すると、A を閉じると、B も閉じられます。しかし、それは新たな問題を生み出します。B は常に A の上にあります。

4

1 に答える 1

0

最後に、次のように実装しました。ダイアログはを使用して表示ShowDialog()されますが、起動されます(そしてスレッドで作成されます)。ShowDialog()独自のメッセージループを実装しているため、フォームがスレッドで起動されると、メインフォームはイベントに応答します。また、メインフォームを閉じても、子フォームは引き続きイベントに応答します。これは、ShellExtensionアプリケーションに非常に役立ちます。

スレッドとシェル拡張スレッドを解放するために、すべてをフォームに破棄することを忘れないでください(各シェル拡張ウィンドウと子はスレッドで実行されます)。

次のコードは私の問題を修正しました:

    protected virtual void SetupViewControl()
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(DoSetupViewControl));

        while (!mViewControlCreated)
        {
            // wait for view control created
            Thread.Sleep(100);
        }
    }

    private bool mViewControlCreated = false;

    protected virtual void DoSetupViewControl(object state)
    {
        mViewControl = ViewControlFactory.CreateViewControl();

        mViewControl.Dock = DockStyle.Fill;
        mViewControl.Initialize();

        this.Controls.Clear();
        this.Controls.Add(mViewControl);

        IntPtr wHnd = GetActiveWindow();
        IWin32Window owner = GetOwner(wHnd);

        mViewControlCreated = true;

        ShowDialog(owner);

        this.Dispose();
    }

    private IWin32Window GetOwner(IntPtr wHnd)
    {
        if (wHnd == IntPtr.Zero) return null;

        return new WindowWrapper(wHnd);
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    private static extern IntPtr GetActiveWindow();

    private class WindowWrapper : IWin32Window
    {
        private IntPtr mHwnd;

        public WindowWrapper(IntPtr handle)
        {
            mHwnd = handle;
        }

        public IntPtr Handle
        {
            get { return mHwnd; }
        }
    }
于 2011-08-11T08:11:10.813 に答える