Ошибка создания дескриптора окна в приложении .NET MDI - PullRequest
1 голос
/ 21 апреля 2011

У меня есть приложение MDI с элементами управления вкладками.На некоторых машинах я получаю исключение «Ошибка создания дескриптора окна» при открытии новой вкладки.Это происходит только на некоторых машинах, в основном на медленных машинах.Используется .NET Framework 4.0.

Я исследую эту проблему последние пару дней, и это сводит меня с ума!Я нашел следующее на форумах MSDN Решение от Ханса Пассанта на этом форуме MSDN И, согласно ответу, это как-то связано с активным дочерним MDI, находящимся в развернутом состоянии.Данное решение состоит в том, чтобы установить активный дочерний элемент в нормальное состояние окна перед отображением новой вкладки, а затем восстановить его.Это решение работает, но мне очень не нравится мерцание, которое вызывает обходной путь.

Трассировка стека выглядит следующим образом:

Ошибка создания дескриптора окна:

   at System.Windows.Forms.NativeWindow.WindowClass.Callback(IntPtr hWnd, Int32 msg, 
   at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
   at System.Windows.Forms.Control.CreateHandle()
   at System.Windows.Forms.Form.CreateHandle()
   at System.Windows.Forms.Control.get_Handle()
   at System.Windows.Forms.Form.SetVisibleCore(Boolean value)
   at System.Windows.Forms.Control.Show()
   at Client.UI.WinForms.Controls.TabManager.OpenNewTab(BaseTab2 tab) in WinForms\Forms\Tabs\TabManager.cs:line 82
   at Client.UI.WinForms.Controls.TabManager.OpenTab(BaseTab2 tab) in WinForms\Forms\Tabs\TabManager.cs:line 183
   at Client.UI.WinForms.MainForm.buttonLicenses_Click(Object sender, EventArgs e) in WinForms\Forms\MainForm.cs:line 4372

Код:

    private void OpenNewTab(BaseTab2 tab)
    {
        tab.MdiParent = MainForm.Instance;
        tab.WindowState = FormWindowState.Maximized;
        tab.Show(); <----- [EXCEPTION THROWN HERE]

        if (tab.Path != String.Empty)
        {
            RecentManager.Add(tab.Path);
            RecentManager.SetOpen(tab.Path, true);
        }
    }

ОБНОВЛЕНИЕ: Обнаружено в Поддержка Microsoft
Это может произойти, если выполняются оба следующих условия.

  1. Дочерняя форма MDI содержитуправляйте родительскими элементами других элементов управления.
  2. Родительский элемент управления в дочерней форме MDI удаляет дочерний элемент управления из его коллекции Controls в обработчике событий для событий Layout или Resize.

1 Ответ

3 голосов
/ 21 апреля 2011

В статье службы поддержки Microsoft используется тот же сценарий, что и в найденном вами сообщении на форуме MSDN. Это не очень хорошо с тобой. Диагностируйте это с помощью Taskmgr.exe, вкладка «Процессы». View + Select Columns и отметьте маркеры, объекты USER и объекты GDI. Соблюдайте эти значения для вашего процесса, пока вы его используете.

Скорее всего, вы увидите, что значение объектов USER будет расти без ограничений. Windows вытаскивает ковер, когда достигает 10000, это слишком много окон, чтобы быть созданным одним процессом.

Это вызвано удалением элементов управления из их родительского элемента в вашем коде без вызова их метода Dispose (). Если Taskmgr.exe не помогает вам найти его, найдите в своем коде «Controls.Remove» или «Controls.Clear». Может быть, вы удаляете вкладку. Элементы управления, которые вы удаляете, временно переименовываются в «окно парковки». Они застрянут там навсегда, если вы не предоставите им другого родителя или не вызовете их метод Dispose (). Это утечка. Код, который бомбит, не тот код, который вызвал проблему.

...