Проблемы с отправкой сообщений windows в диалоговые окна, созданные в разных потоках
Я создаю пользовательскую структуру данных, которая представляет собой двоичное дерево объектов и двоичных деревьев. т. е. каждый узел в дереве верхнего уровня может быть " объектом "или" objectContainer "(который, в свою очередь, может иметь"object "или"objectContainer" для узлов).
У меня есть насос сообщений в моем основном потоке, с помощью этого насоса я обрабатываю все сообщения Windows, предназначенные для моего главного окна (щелчки, перетаскивание и изменение размера, нажатия кнопок). А когда он не работает с сообщениями Windows, он запускает таймер и обновляет сцену. Когда главное окно получает определенное нажатие клавиши, оно (в настоящее время) запускает новый поток, этот поток затем создает новый объект (или objectContainer), и во время создания нового объекта создается модальное (блокирующее) диалоговое окно, так что пользователь может взаимодействовать с / вводить начальные значения для вновь созданного объекта. После нажатия кнопки ОК, если предоставленное имя уникально (в отношении содержимого контейнера верхнего уровня), новый объект добавляется в контейнер верхнего уровня. Наконец, если модальное диалоговое окно (порожденное изнутри еще одного потока), которое отображает содержимое контейнера (в данном случае верхнего уровня), открыто, я отправляю сообщение WM_message в указанное диалоговое окно, которое предназначено для того, чтобы сообщить ему добавить имя нового элемента в список строк. У меня проблемы с отправкой этих сообщений в диалоговые окна. Например, когда я создаю objectContainer, правильное имя появляется в списке сразу после нажатия кнопки OK, но не в том случае, если я создаю объект. Я предположил, что это может иметь какое-то отношение к потокам, но я не знаю. Каждый тип объекта использует одну и ту же функцию addObject (), в которой поле отображения контейнера проверяется на предмет того, открыто оно или нет, и отправляется сообщение.
Что я уже пробовал:
Я читал статьи, в которых говорится, что никогда не используйте резьбу... если только вам это абсолютно не нужно! И что весь пользовательский интерфейс должен быть сделан в одном потоке. Некоторые даже говорят, что нужно делать UI только через основной поток. Я попробовал варианты своего применения с некоторыми методами, которые, как мне кажется, предлагают авторы этих статей, но что-то не так.
Я сделал версию, в которой при нажатии кнопки основной поток порождает немодальный диалог, который выполняет работу по взаимодействию с вновь созданным объектом. Это работает хорошо, за исключением того, что, скажем, пользователь перетаскивает немодальное диалоговое окно в течение длительного периода времени, основной процесс останавливается. У меня есть функция после части IsDialogMessage основного насоса сообщений, которая вычисляет частоту кадров и запускается, когда пользователь щелкает и удерживает немодальное диалоговое окно. Я не думаю, что хочу, чтобы это произошло, функции, обновляющие сцену, не запускаются, пока пользователь не отпустит. (если подумать, если я перетаскиваю главное окно, обработка частоты кадров тоже останавливается ... но я подозреваю, что это неизбежно, верно? если только эта обработка не выполняется в отдельном потоке ...?)
Я также создал версию, в которой после нажатия кнопки основной поток запускает новый поток, новый поток создает новый объект или objectContainer и сразу после создания нового элемента порождает немодальное диалоговое окно для editObject (). В немодальном диалоговом окне вызывающий поток не блокируется, поэтому я добавил насос сообщений сразу после создания указанного немодального диалогового окна, и он, похоже, работает. Я еще не тестировал добавление объектов и проверку уникальности имени в контейнере верхнего уровня. Я не знаю, дойдет ли wm_messages до нужного окна и будет ли управлять списком строк диалогового окна, как я хочу.
У меня возникают проблемы с каждой из моих попыток проектирования, и я просто хотел бы знать ваши мысли о дизайне, прежде чем тратить больше времени на отладку плохого дизайна. Должен ли основной поток откручиваться от потока и вызывать модальное диалоговое окно? Или все диалоговые окна должны вызываться из основного потока, и я каким-то образом перемещаю то, что, по моему мнению, должно постоянно обрабатываться, в свой собственный поток? Или основной поток должен отделиться от потока, а затем использовать немодальные диалоговые окна?
Richard MacCutchan
Если вы решили использовать потоки, то вам нужно добавить механизм синхронизации событий при создании ваших объектов. Если поток а порождает поток в, то они запускаются независимо, но нет никакой гарантии, какой из них выполнит какую-либо из своих задач первым. Читайте об использовании семафоров для синхронизации задач.