c # — приложение зависает, когда хостинг управляется как CWnd

Мое приложение имеет графический интерфейс на основе ATL (CWnd, CDialog, …) и состоит из нескольких страниц (CDialog). В противном случае одна из этих страниц пуста, но имеет рамку-заполнитель (CWnd), размер которой изменяется вместе с диалогом. Все построено как x64.

Когда страница загружается, она запрашивает дескриптор элемента управления из управляемой (C #) стороны приложения, используя COM-взаимодействие, и добавляет элемент управления в диалог как CWnd, созданный из этого дескриптора:

Управляемая реализация упрощена:

// Class "ManagedControlProvider"private Control myUserControl;
public long CreateControl()
{
myUserControl = /*Create some new inheritant of UserControl */
myUserControl.Dock = DockStyle.Fill;
return myUserControl.Handle.ToInt64();
}

Родная сторона упрощена:

// Call the managed class. Lifetime of m_pManagedControlProvider
// is ensured elsewhere.
LONGLONG lHandle = m_pManagedControlProvider->CreateControl();

// m_pUserCtrlAsCWnd is CWnd*
m_pUserCtrlAsCWnd = CWnd::FromHandle((HWND)lHandle);
m_pUserCtrlAsCWnd->SetParent(this);

// m_ControlFrame is just a native helper-CWnd the dialog that
// resizes with it a so gives us the size we want to set for the
// managed control. This code is also call in every resize -event.
RECT winRect;
m_ControlFrame.GetWindowRect(&winRect);
ScreenToClient(&winRect);

m_pUserCtrlAsCWnd->SetWindowPos(NULL,
winRect.left, winRect.top, winRect.right - winRect.left,
winRect.bottom - winRect.top, 0);

Я сделал это несколько раз, и это обычно работает точно так, как должно. Но иногда, как и сейчас, я испытываю зависания приложений без какой-либо явной причины. С моим текущим контролем это, кажется, происходит примерно через 5 секунд после того, как фокус установлен на какое-то другое настольное приложение.

Я проверил, что проблема не в жизненном цикле управляемого элемента управления или GC. Кроме того, это воспроизводимо в отладочной сборке, так что оптимизации не виноваты. Когда происходит зависание, я могу подключить отладчик и увидеть, что какой-то цикл ATL продолжает работать, но это единственный фрагмент кода, который я могу видеть в стеке (imo это означает, что цикл сообщений каким-то образом попал в бесконечный цикл, не взаимодействуя с мой код).

Теперь для исправления грязи: я добавил отдельный поток в свой управляемый элемент управления, который вызывает this.Focus () каждую секунду в потоке пользовательского интерфейса. Очевидно, это нелепый хак, но он работает до тех пор, пока я приостанавливаю фокусировку каждый раз, когда пользователь открывает комбо и т. Д. (В противном случае они закрываются каждую секунду).

Что я делаю не так или что может вызвать это несколько непредсказуемое поведение?

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]