Закрытие дочерних диалогов при закрытии родителя - PullRequest
6 голосов
/ 09 августа 2011

Я пишу расширение оболочки Windows на C #, используя EZShellExtensions.NET .

Я предоставляю контекстное меню, которое показывает диалоги.

Предположим, я показываю окно проводника (A).Затем я использую контекстное меню, чтобы показать немодальное окно (B).

В Windows XP и Windows Vista, когда я закрываю A, B закрывается (я хочу это поведение).Однако в Windows 7, когда я закрываю A, B не закрывается, но не реагирует на события.Мои вопросы:

  • Знаете ли вы, почему Windows 7 управляет показанной формой как дочерней формой?
  • Есть ли способ сохранить цикл сообщений, если я закрою A?

РЕДАКТИРОВАТЬ : Если я устанавливаю A как владельца B, когда я закрываю A, B также закрывается.Но это создает новый выпуск .B всегда больше A.

1 Ответ

0 голосов
/ 11 августа 2011

Наконец я реализовал это следующим образом.Диалог отображается с использованием ShowDialog(), но запускается (и создается в потоке).ShowDialog() реализует свой собственный цикл сообщений, так как форма запускается в потоке, основная форма реагирует на события, а также вы можете закрыть основную форму, а дочерняя форма по-прежнему реагирует на события.Это очень полезно для приложения ShellExtension.

Не забудьте избавиться от всех в вашей форме, чтобы освободить поток, а также поток расширения оболочки (каждое окно расширения оболочки и дочерние элементы выполняются в потоке).1005 *

Следующий код исправил мою проблему:

    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; }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...