Есть поток, который содержит класс-обертка (CDialog-а). Есть несколько других потоков (плагинов для программы), в которых создаются аналогичные классы, которые передаются в первый поток. Далее в первом потоке с ними производятся базовые операции (Создать, открыть, закрыть, послать сообщение — все через класс-обертку)
Здесь возникает проблема — в debug режиме программа генерит Assertion Failed в wincore.cpp line 892 — в описании ассерта говорится, что нельзя передавать объекты CDialog между потоками.
В release версии программа работает нормально, за одним исключением — если открыть диалог во второй раз — все дочерние диалоги становятся disabled и ни на что не реагируют (с главным диалогом все нормально). Если диалог закрыть и открыть в третий (и т.д.) раз, то все работает нормально.
Какие могут быть пути решения?
The Creator had a lot of remarkably good ideas when he put the world together, but making it understandable hadn't been one of them. (c) Terry Pratchett
Здравствуйте, ZZmiy, Вы писали:
ZZ>Возникла такая проблема:
ZZ>Есть поток, который содержит класс-обертка (CDialog-а). Есть несколько других потоков (плагинов для программы), в которых создаются аналогичные классы, которые передаются в первый поток. Далее в первом потоке с ними производятся базовые операции (Создать, открыть, закрыть, послать сообщение — все через класс-обертку)
Послать сообщение — это понятно. А открыть, закрыть — это что? По любому связь между ними лучше тогда делать через сообщения, но посылать их через PostMessage.
Здравствуйте, rus-k, Вы писали:
RK>Послать сообщение — это понятно. А открыть, закрыть — это что? По любому связь между ними лучше тогда делать через сообщения, но посылать их через PostMessage.
Извиняюсь, я нечетко описал ситуацию — все потоки — разные плагины одной и той же программы. Чтобы корректно открыть (и закрыть) диалог нужно еще несколько дополнительных действий — зарегистрировать окно в главной программе и проч. именно этим занимается класс-wrapper, который мы передаем. И именно поэтому я не очень понимаю как можно здесь использовать предлагаемое в описании ассерта решение — передавать только HWND (Очень хочется, чтобы "общение" между плагинами ограничилось передачей одного объекта).
The Creator had a lot of remarkably good ideas when he put the world together, but making it understandable hadn't been one of them. (c) Terry Pratchett
Здравствуйте, ZZmiy, Вы писали: ZZ>И именно поэтому я не очень понимаю как можно здесь использовать предлагаемое в описании ассерта решение — передавать только HWND (Очень хочется, чтобы "общение" между плагинами ограничилось передачей одного объекта).
Каждый диалог — это своя очередь сообщений, отдельная задача. У тебя таких задач несколько. Как тебеих связать?
1. Диалог 1 посылает Дилогу 2 сообщение через SendMessage. Большинство методов CDialog в конечном итоге превращаются в вызов различных SendMessage. Вызов SendMessage чреват блокировкой (deadlock), т.к. вызывающий диалог блокируется до завершения обработки сообщения.
2. Диалог 1 посылает Дилогу 2 сообщение через PostMessage. Это сообщение будет обработано когда-нибудь и Диалог 1 не будет ждать этого момента. Если тебе нужна ответная реакция — пусть Диалог 2 делает PostMessage Диалогу 1. Можно использовать пользовательские сообщения (см. WM_USER).
3. Диалог 1 вызывает методы обертки Диалога 2, т.к. он знает, что это не просто диалог, а обертка. Тут уже все зависит от методов обертки: блокируются ли они, как они обеспечивают синхронизацию достуа к данным и т.п.