Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопрос по сообщениям окна! 
:(
    Опции темы
akahan
  Дата 11.2.2007, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 11.2.2007

Репутация: нет
Всего: нет



Привет всем!
Такой вопрос:
Я суперклассирую EDIT. Мне нужно из WndProc моего контрола отследить когда длина текста в MYEDITе равна 0. 
Допустим, я могу это отследить из родительского окна с помощью EN_UPDATE или EN_CHANGE, но как мне это сделать из WndProc моего контрола?
Я думаю можно отслеживать с помощью отлова WM_KEYDOWN, но, ведь, текст можно вставить из clipboard, тогда еще нужно отслеживать WM_PASTE и тд. Должно же быть более оригинальное решение!
С помощью каких сообщений окна это можно отследить?
Посоветуйте, ГУРУ!!!  smile
PM MAIL   Вверх
akahan
Дата 11.2.2007, 20:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 11.2.2007

Репутация: нет
Всего: нет



Ну где вы гуру???
%)
PM MAIL   Вверх
Kostt
Дата 12.2.2007, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 169
Регистрация: 8.1.2006
Где: Томск

Репутация: нет
Всего: 3



Попробуй сделать, как описал. Кстати при COPY/PASTE скорее всего WM_KEYDOWN тоже будет обработан (если через CTrl+V). Кстати, что значит и т.д? Разве есть еще способы изменить содержимое едита???
PM MAIL   Вверх
Earnest
Дата 12.2.2007, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Можно ловить в самом контроле изменения EN_CHANGE  с помощью ON_CONTROL_REFLECT.
Можно просто поставить таймер и проверять: так гарантированно все поймаешь.


--------------------
...
PM   Вверх
akahan
Дата 21.2.2007, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 11.2.2007

Репутация: нет
Всего: нет



Цитата(Kostt @ 12.2.2007,  10:51)
Попробуй сделать, как описал. Кстати при COPY/PASTE скорее всего WM_KEYDOWN тоже будет обработан (если через CTrl+V). Кстати, что значит и т.д? Разве есть еще способы изменить содержимое едита???

Ну например если послать WM_SETTEXT. или SetWindowText(). 

С помощью рефлексии конечно хорощо бы было, но я пишу на Win API. Я не использую ни WTL, ни MFC, ни ATL. Может посоветуете как мне это самом по простенькому прописать. Я слышал, что рефлексия базируется на создании dummy окна, которое будет транслировать сообщения, я пробывал, но что-то ничего не вышло путного! Не хочет созданное окно перехватывать нотификации типа EN_CHANGE .
Кто нибудь сталкивался с этим?

Еще слышал про окна, которые создаются именно для перехвата сообщений с помощью HWND_MESSAGE вместо родительского окна. Но опять таки не могу найти вразумительной информации по этому поводу. Как мне застаить это окно слушать мой контрол! Оно то создается без проблем, принимает, вначале, стандартные сообщения типа WM_NCCREATE и тд, а потом глохнет и не хочет слышать ничего. Оно конечно понятно, что нужно как-то задать, что именно и от кого слушать, но вот как???? вопрос!!!!

Это сообщение отредактировал(а) akahan - 21.2.2007, 14:21
PM MAIL   Вверх
Earnest
Дата 21.2.2007, 20:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Если используешь API, чего в MFC постишь? Перенесу, пожалуй...

По теме: нет, рефлексия работает совершенно не так, а HWND_MESSAGE - вовсе не для перехвата, а для просто приема сообщений, но невидимые - вообще другая тема.
Дело в том, что эти уведомления шлются исключительно от чайлд-контрола к родителю. Т.е. только у родителя их и можно ловить. Рецепт простой: на уровне родителя ловим WM_COMMAND и WM_NOTIFY. Первое нужно еще проверить - не все WM_COMMAND от детей приходят (точно не помню, кажется в lParam что-то такое записано). Посылаем (SendMessage) назад тому, кто прислал, но с какой-нибудь приставкой. Или придумай свое сообщение, с параметрами.
Если ответили "да" (т.е. обработали) - все дальше не обрабатываем, если нет - другая обработка, если надо.
Все это дело можно написать в базовом классе, если таковые есть, или просто как функцию оформить.
Ровно так это дело обрабатывается в MFC, только там не спец-сообщение шлется, а виртуальная ф-я вызывается. Если у вас есть классы окон - то это лучше и проще, чем посылать сообщение.




--------------------
...
PM   Вверх
akahan
Дата 24.2.2007, 02:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 11.2.2007

Репутация: нет
Всего: нет



Уважаемая Earnest!

Сорри!!! Запостил в MFC, потому-что сначала не увидел этого раздела для Win API.

В том то и проблема, что мне нужно все сделать так, чтобы в диалоге (где собственно и ловится в обычных случаях EN_CHANGE и т.д.) мне не нужно было ничего прописывать. То есть все должно быть примерно так:
Ложим на диалог Custom Control, определяем его класс, в исходнике где реализована WndProc диалога подцепляем хеадер моего контрола, где описан класс и реализована рубаха класса на c++. Потом в обработке сообщение WM_CREATE можем найти рубаху, созданную при WM_CREATE моего котнрола, типа: MyEdit * ed1 = MyEdit::GetControl(hwnd_myedit1);
и работать далее с ed1. И все.

Кстати, хочу уточнить, куда именно шлются уведомления? От чайлд-контрола именно к родителю или самому диалогу или главному окну, если контрол создан на главном окне! Я почему спрашиваю, я пробывал создавать на диалоге окно, которое полностью закрывалось моим контролом, и ставил его родителем моего контрола, но, к сожалению, это окно не хотела получать WM_COMMAND от контрола! Может я делал что-то не так. Код создания:
Код

// m_hWnd определяется при создании экземпляра класса. Это хандлер окна моего кнтрола.
MyEdit::OnCreate(LPCREATESTRUCT cs)
{
    if(MyEdit::dummy_window = CreateWindow(DUMMY_CLASSNAME, NULL, WS_CHILD | WS_VISIBLE,
        cs->x, cs->y, cs->cx, cs->cy, cs->hwndParent, 0, cs->hInstance, NULL))
    {
        SetParent(m_hWnd, MyEdit::dummy_window);
        SetWindowPos(m_hWnd,0,0,0,0,0,SWP_NOSIZE);
    }
}


И еще, я решил, в принципе, эту проблему (т.е. проблему этого топика) с помощью хуков, хотя это и несовсем хорошее решение, но оно работает! Может это можно решить еще как нибудь???


Это сообщение отредактировал(а) akahan - 24.2.2007, 02:20
PM MAIL   Вверх
Earnest
Дата 24.2.2007, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Боюсь, нет. Сначала хотела посоветовать "локализовать" хуки, просто встроив их вызов в главный цикл. Т.е. сделать обычными функциями. Но потом вспомнила, что рассматриваемые сообщения шлются Send, т.е. в главный цикл не попадают...

Цитата(akahan @  24.2.2007,  03:06 Найти цитируемый пост)
Кстати, хочу уточнить, куда именно шлются уведомления? От чайлд-контрола именно к родителю 

Да. Не знаю, почему не изменился адресат уведомлений. Скорее всего, это не на OnCreate нужно делать, а позже. 
Кроме того, возможно, что OnCreate тебе просто не приходит - это если у тебя диалог из ресурсов и все контролы уже на форме лежат. Т.е. если ты сам не вызываешь для них CreateWindow, а просто сабклассишь.

Цитата(akahan @  24.2.2007,  03:06 Найти цитируемый пост)
В том то и проблема, что мне нужно все сделать так, чтобы в диалоге (где собственно и ловится в обычных случаях EN_CHANGE и т.д.) мне не нужно было ничего прописывать. 

Честно говоря, это не аргумент. Ну и не прописывай все, кто заставляет. Но функцию-то одну вызвать можно? Всяко лучше чем хук (в смысле адекватности решения проблеме). Что-то типа базового класса. В конце концов, ты же не прописываешь все каждый раз с нуля.





--------------------
...
PM   Вверх
akahan
Дата 24.2.2007, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 11.2.2007

Репутация: нет
Всего: нет



Сорри, какие сообщения шлются Send? EN_CHANGE и EN_UPDATE??? Я думал это нотифи и они постятся!

А насчет OnCreate. Это моя функция, и она вызывается прямо из WndProc при обработке WM_CREATE. Окно создается 100%!
Диалог находится именно в ресурсах и контрол создан в ресурсах. С чего вы взяли, что WM_CREATE не вызвается в таком случае???? smile


Это сообщение отредактировал(а) akahan - 24.2.2007, 20:04
PM MAIL   Вверх
akahan
Дата 25.2.2007, 00:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 11.2.2007

Репутация: нет
Всего: нет



А вот нашел решение своей проблемы! Все делается, как и все гениальное, просто!
Я суперклассирую еще и диалог! Это полностью решает все проблемы! Спасибо всем за советы, в частности дамам! smile
PM MAIL   Вверх
Earnest
Дата 25.2.2007, 08:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Цитата(akahan @  24.2.2007,  20:57 Найти цитируемый пост)
 Окно создается 100%!
Диалог находится именно в ресурсах и контрол создан в ресурсах. С чего вы взяли, что WM_CREATE не вызвается в таком случае???? 

А ты поставь точку прерывания и посмотри. Сначала создается контрол (внутри кода виндоус - CreateDialogIndirect), и в этот момент у него еще своя родная оконная функция, и только потом ты его сабклассишь.
Исключение - если контрол Custom.
Цитата(akahan @  24.2.2007,  20:57 Найти цитируемый пост)
Сорри, какие сообщения шлются Send? EN_CHANGE и EN_UPDATE??? Я думал это нотифи и они постятся!
 Это, строго говоря, WM_COMMAND, и они, насколько помню, посылаются родителю прямо, в обход очереди.

Какая, собственно, принципиальная разница между написанием свой DlgProc и сабклассированием диалога (т.е. подменой WndProc)?
Я тебе и предлагала вставить в диалоговую функцию один стандартный вызов.


--------------------
...
PM   Вверх
akahan
Дата 25.2.2007, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 11.2.2007

Репутация: нет
Всего: нет



Цитата(Earnest @  25.2.2007,  08:14 Найти цитируемый пост)
Исключение - если контрол Custom.

смотрите выше! smile
Цитата(akahan @  24.2.2007,  02:06 Найти цитируемый пост)
Ложим на диалог Custom Control, определяем его класс, в исходнике где реализована WndProc диалога подцепляем хеадер моего контрола, где описан класс и реализована рубаха класса на c++. Потом в обработке сообщение WM_CREATE можем найти рубаху, созданную при WM_CREATE моего котнрола, типа: MyEdit * ed1 = MyEdit::GetControl(hwnd_myedit1);
и работать далее с ed1. И все.


--------------------------------------------------------------------------

Цитата(Earnest @  25.2.2007,  08:14 Найти цитируемый пост)
Какая, собственно, принципиальная разница между написанием свой DlgProc и сабклассированием диалога (т.е. подменой WndProc)?
Я тебе и предлагала вставить в диалоговую функцию один стандартный вызов. 


Изначально и была такая мысль, что-бы сделать все прозрачно. Т.е. при каждом написании какого либо диалога не париться и не вставлять каждый раз один и тот-же код в DlgProc. Ведь гораздо проще на этапе конструирования вставить в поле ClassName свое значение и прицепить хеадер, ведь это проще и правильнее.
И насчет суперклассирования. Это именно суперклассирование, а не субклассирование. Это два разных метода, хоть и суперклассирование базируется на субклассировании. Главное отличие в том, что при суперклассировании не нужно каждый раз, для каждого, вновь созданного котнрола, менять WndProc, а это делается один раз. Это, согласитесь, утомительно и неправильно! smile
PM MAIL   Вверх
Earnest
Дата 26.2.2007, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Цитата(akahan @  25.2.2007,  10:05 Найти цитируемый пост)
смотрите выше!

Если тебе кажется, что все изложено абсолютно четко и однозначно - ты ошибаешься. smile 
Это тебе все ясно, потому что это твоя проблема.
... Я думала, что речь идет о всяких эдитах, лежащих на форме, т.к. все время упоминались EN_CHANGE и т.д.

Цитата(akahan @  25.2.2007,  10:05 Найти цитируемый пост)
Ведь гораздо проще на этапе конструирования вставить в поле ClassName свое значение 

Не согласна. Гораздо лучше иметь все нестандартное управление в одном месте. А данном случае -  в коде, т.к без кода не обойтись.
Лучше - в смысле последующей поддержки и внесения изменений. Простота поддержки и внесения изменений гораздо важнее простоты создания. Причина банальна: когда создаешь, ты весь в этой проблеме и совершенно несложно немного напрячься и сделать пару лишних движений. А вот когда придется что-то поменять, добавить, ... когда уже не помнишь толком, что и как работает - вот тогда проклянешь свою простоту создания. И следующий раз десять раз подумаешь, что важнее.

Цитата(akahan @  25.2.2007,  10:05 Найти цитируемый пост)
И насчет суперклассирования. Это именно суперклассирование, а не субклассирование. Это два разных метода

Не знаю, это какая-то игра слов. Суть одна.




--------------------
...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0809 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.