| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Visual C++/MFC/WTL > Обмен данными между окнами |
| Автор: 13dreams 18.7.2010, 17:12 |
| Имеется дочернее диалоговое окно которое вызывается нажатием кнопки главного окна с помощью метода DoModal(). В дочернем окне есть кнопка которой хотелось бы менять иконку на кнопке главного окна. В классе дочернего окна я создал объект класса главного окна и через написанную мной функцию пытаюсь передать в главное окно данные. Всё компилируется нормально, но когда я нажимаю на кнопку, которая должна отправить данные в главное окно, вылетает какое-то сообщение об ошибке. Что я не так делаю? И как в моём случае организовать эту передачу данных? |
| Автор: Earnest 19.7.2010, 08:06 |
Замечательное описание ошибки! Не надо гадать на кофейной гуще - у тебя есть отладчик. Поставь точку прерывания и посмотри, откуда ошибка. |
| Автор: 13dreams 19.7.2010, 20:53 |
| немного изменил код: из дочернего окна вызываю функцию главного окна которая меняет только флаг. В главном окне вызываю таймер который в соответствии с этим флагом меняет битмап на кнопке. Посоветуйте плз, можно ли оставить так или проверку флагов реализовать в отдельном потоке т.к. кнопок с картинками будет очень большое количество ps И можно ли считать таймер отдельным потоком? |
| Автор: 13dreams 20.7.2010, 22:35 | ||||||
добил код в котором рабочий поток отправляет сообщение главному окну из класса которого он создан
как реализовать отправку сообщения из этого потока в дочернее окно? я пробовал объявить и написать
|
| Автор: Earnest 21.7.2010, 07:23 |
| Я как-то путаюсь: то у тебя главное окно, то дочернее, кто есть кто в конце концов? Из кода вижу, что диалог запускает поток, который должен послать ему сообщение. Вроде все нормально, только динамически создавать phObjectHandle совершенно не нужно - HWND вполне влезет в LPARAM. Что касается "ничего не выходит", то поясни, что сие значит: ты не видишь результат? Или не попадаешь в обработчик? Второе вряд ли, все вроде верно. Поставь точку прерывания в обработчике и проверь код. Возможно у тебя UpdateData ничего не делает (т.к. не вижу кода, который связывает переменные с контролами, но может ты его просто не привел). Добавлено через 2 минуты и 42 секунды Да, кстати, логичнее в потоковую процедуру предать указатель на диалог, а не HWND, а переменную m_WrStr1 устанавливать непосредственно перед отправкой сообщения через соответствующий метод диалога - все эти динамические переменные, создаваемые в одном месте, а освобождаемые в другом, дурно пахнут. А сообщение может быть просто сигналом. |
| Автор: 13dreams 21.7.2010, 08:17 |
| Прошу прощения, что так выражаюсь. этот код, который я написал выше, работает корректно. Созданный поток отправляет главному окну CString и эта строка отображается в контроле этого главного окна но есть ещё одно дочернее окно которое вызывается кнопкой из этого главного окна(методом DoModal() ). И я хочу чтоб та же строка CString отсылалась и этому дочернему окну как это реализовать? |
| Автор: Earnest 21.7.2010, 11:58 |
| Очевидно, нужно ему что-нибудь тоже послать. Вопрос, откуда удобнее это сделать - и тут возможны варианты. Если есть HWND этого дочернего диалога, то нет проблем, не так ли? Значит, надо его получить (HWND). Мне кажется, проще это сделать прямо в обработчике главного окна (если оно по прежнему должно получать это сообщение). Определить HWND можно, например, с помощью функции GetLastActivePopup. Еще вариант: если главное окно хранит ссылку на дочерний диалог (а не создает его как автоматическую переменную в обработчике, где делается DoModal), то можно сделать обновление не через сообщение, а через функцию дочернего диалога. Только перед вызовом тогда нужно проверять, что окно валидно (т.к. оно валидно только в течении вызова DoModal). Вариант определения HWND через GetLastActivePopup можно скомбинировать с вызовом функции дочернего диалога (а не посылкой ему сообщения), получив указатель на диалог с помощью функции FromHandlePermanent. Только этот вызов должен находиться в главном потоке. Наконец, можно разослать сообщение всем окнам системы через PostMessage (HWND_BROADCAST, ...), только тогда нужно гарантировать, что никто чужой случайно не обработает сообщение WM_UPDATE_CONTROL. Такую гарантию могут дать только зарегистрированные сообщения (RegisterWindowMessage, подключение обработчика - ON_REGISTERED_MESSAGE). |
| Автор: 13dreams 21.7.2010, 18:52 | ||||
| Я думаю, что лучше в потоке проверят создано ли дочернее окно и если создано, то отправить ему сообщение но как правильно использовать GetLastActivePopup? я пробовал аналогично предыдущему коду
и пробовал
и чего-то сообщения не доходят |
| Автор: Earnest 21.7.2010, 20:32 | ||
| А описание в MSDN посмотреть не судьба? GetLastActivePopup ВОЗВРАЩАЕТ попап-окно, принадлежащее главному:
|
| Автор: 13dreams 23.7.2010, 16:08 |
| Спасибо! Заглянул в МСДН и решил проблему с помощью GetForegroundWindow() для конкретного случая подходит |