Мое приложение имеет графический интерфейс на основе 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 () каждую секунду в потоке пользовательского интерфейса.Очевидно, это нелепый хак, но он работает до тех пор, пока я приостанавливаю фокусировку каждый раз, когда пользователь открывает комбо и т. Д. (Иначе они закрываются каждую секунду).
Что я делаю не так или что может вызвать это несколько непредсказуемое поведение?