Надстройка C # для приложения (через COM) зависает при добавлении элемента управления в форму? - PullRequest
8 голосов
/ 05 января 2012

Я разрабатываю расширение для существующего приложения через COM.

Текущий интерфейс расширяемого приложения позволяет создавать собственные окна свойств и использовать их внутри этого приложения.


Теперь я использую .NET для этой цели и у меня странные проблемы:

    extensionForm = new Form();
    extensionForm.SetBounds(0, 0, 100, 100);
    extensionForm.Controls.Add(new Button());

    ExApplAPI.AddCustomPropertyWindow(extensionForm.Handle.ToInt32(), "Ololo");

Как вы можете видеть ниже, листы свойств фактически расширяются , но после этого начинает происходить что-то странное.

enter image description here

Обычно, если я переключаюсь на вкладку Ololo, затем возвращаюсь к любой из 3 других вкладок (Attributes, Drawing или Services), приложение зависает. Я также знаю, что зависание происходит внутри некоторого неуправляемого блока кода.


Еще один интересный факт заключается в том, что если я не пишу extensionForm.Controls.Add(new Button()) (с вызовами макета приостановки / возобновления или без них) , , то все работает нормально. Итак, если Недавно построенная форма не имеет элементов управления (кнопок или любых других), она не останавливается.

Вот журнал Spy++ в окне Ololo прямо перед остановкой (последнее сообщение - WM_CTLCOLORBTN, сразу после этого приложение стало замороженным):

enter image description here


Объединяем все вместе:

  • Замораживание происходит только в том случае, если я переключаюсь с Ololo на другую вкладку, а затем снова переключаюсь на вкладку Ololo.
  • Замораживание происходит только в том случае, если на интегрированной форме есть хотя бы один элемент управления, формы без элементов управления не замирают.
  • В настоящее время приложение не выполняет какой-либо управляемый код и не тратит процессорное время.

Итак, какие-нибудь идеи / подобные проблемы решены / и т.д., чтобы помочь мне в этом случае?

Ответы [ 4 ]

4 голосов
/ 11 января 2012

Дескрипторы Win32 HWND для форм в .NET инициализируются лениво.И я думаю, что это может быть проблемой здесь.

Вы можете утверждать, что дескриптор создан в вашей строке ExApplAPI.AddCustomPropertyWindow(extensionForm.Handle.ToInt32(), "Ololo"); из-за доступа к свойству Handle.Это правда и то, что документация признает.

Однако он создает дескриптор для самого Form, но дескрипторы для дочерних элементов управления (в данном случае Button) не создаются.Это можно принудительно вызвать, вызвав метод CreateControl.См. дополнительную документацию .

Я не знаю, может ли отсутствие проблемы с ручкой для кнопки стать причиной вашей проблемы, но я определенно это исследую.* Подводя итог, я предлагаю изменить ваш код на:

extensionForm = new Form();
extensionForm.SetBounds(0, 0, 100, 100);
extensionForm.Controls.Add(new Button());

extensionForm.CreateControl();
ExApplAPI.AddCustomPropertyWindow(extensionForm.Handle.ToInt32(), "Ololo");
1 голос
/ 11 января 2012

Есть ли исключения? У нас было похожее поведение при использовании WPF и COM, оно решалось вызовом метода вычисления двойного сброса с использованием

[DllImport ("msvcr70.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int _fpreset ();

0 голосов
/ 12 января 2012

Чтобы понять, почему приложение зависает, есть две вещи, которые могут помочь:

  1. Можете ли вы опубликовать трассировку стека потока пользовательского интерфейса, пока приложение зависло?
  2. Какой поток вызывает ваш код и фактически создает окна?
0 голосов
/ 11 января 2012

Возможно, дескриптор ресурса не прав. Как вы упомянули, это происходит только тогда, когда в интегрированной форме есть хотя бы один элемент управления, вкладка Ololo не может найти свои ресурсы, когда снова активна. Пожалуйста, попробуйте сначала сохранить дескриптор ресурса, а затем восстанавливать его каждый раз, когда вкладка активна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...