Здравствуйте, Pupil, Вы писали:
P>Как я понимаю CListCtrl — member этого самого CListView и дочерний контрол для окна, которое описывает класс производный от CListView, т.е. я обрабатываю извещение от контрола в классе его родительского окна.
Здравствуйте, <Аноним>, Вы писали:
А>чем отличается ON_NOTIFY от ON_NOTIFY_REFLECT ?
При использовании ON_NOTIFY() извещения от элемента управления обрабатывает его родительское окно, как это и принято в Win32 API; при использовании ON_NOTIFY_REFLECT() Вы получаете возможность обработать это извещение в самом элементе управления (окно-родитель "отражает" его ребенку) — и соответственно создавать реюзабельные элементы управления, которые можно использовать, не внося изменений в код, реализующий родительское окно.
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by Motorhead — Iron Fist ]
Re[2]: чем отличается ON_NOTIFY от ON_NOTIFY_REFLECT ?
От:
Аноним
Дата:
23.07.05 16:27
Оценка:
А если я в родителе обьявлю макрос ON_NOTIFY_REFLECT ? А>>чем отличается ON_NOTIFY от ON_NOTIFY_REFLECT ?
SDB>При использовании ON_NOTIFY() извещения от элемента управления обрабатывает его родительское окно, как это и принято в Win32 API; при использовании ON_NOTIFY_REFLECT() Вы получаете возможность обработать это извещение в самом элементе управления (окно-родитель "отражает" его ребенку) — и соответственно создавать реюзабельные элементы управления, которые можно использовать, не внося изменений в код, реализующий родительское окно.
Re: чем отличается ON_NOTIFY от ON_NOTIFY_REFLECT ?
Здравствуйте, Аноним, Вы писали:
А>чем отличается ON_NOTIFY от ON_NOTIFY_REFLECT ? А>Читаю МСДН не могу вьехать в суть ...просветите пожалуста
Это макросы обработки сообщений WM_NOTIFY
ON_NOTIFY(code, control_id, memberfunc)
где
code — код нотификации, например всякие TVN_SELCHANGED (для дерева) или LVN_SELECHANGE (для ListCtrl)
control_id — ID контрола который послал WM_NOTIFY — тот самый ID с которым создавался контрол (Create) или записан в шаблоне ресурсов.
memberfunc — имя функции
макрос ON_NOTIFY используется когда родительское окно обрабатывает некую нотификацию (WM_NOTIFY c определенным кодом). Например, диалог обрабатывает от CListCtrl изменение выделенного элемента.
//В коде диалога и его же карте сообщений
ON_NOTIFY(LVN_SELCHANGED, IDC_MYCONTOL, OnMyControlSelChanged)
//функция
CMyDialog::OnMyControlSelChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
//pNMHDR - указатель на структуру NMHDR или на ее наследник (в понимании С++, понятно что windows хедеры необязательно будут ее определять как наследник)
//*pResult - указатель на возвращаемое значение. Зависит от нотификации. обычно что то вроде *pResult=1 или *pResult=0
}
макрос ON_NOTIFY_REFLECT(code, memberfunc)
выглядит аналогично, но без ID контрола. Т.к. располагается в коде самого контрола (или View) и обработка нотификации идет уже в коде самого контрола (или View) поэтому и нет ID. Т.е. как бы сам обрабатываешь нотификации от самого себя.
а суть в общем в следующем:
когда происходит некое событие, к примеру тоже самое TVN_SELCHANGED (изменение выделенного узла в дереве) то контрол отсылает родительскому окну сообщение WM_NOTIFY
где LPARAM указатель, как и говорил, на NMHDR
Дык вот в этом NMDRR::code будет равняться TVN_SELCHANGED и idCtrl будет равняться идентификатору контрола.
Разница где будет происходить обработка,
для ON_NOTIFY в коде класса родительского окна (например диалога на котором лежит контрол)
или
для ON_NOTIFY_REFLECT в коде самого контрола, вернее твоего наследника от него. В случае примера с деревом в коде CMyTreeCtrl который public от CTreeCtrl.
В общем примерно так. Надеюсь мне удалось написать понятно.
Есть еще всякие ON_CONTROL, ON_CONTROL_REFLECT, ON_NOTIFY_REFLECT_EX но они в целом следуют этой же концепции.
Здравствуйте, Аноним, Вы писали:
А>А если я в родителе обьявлю макрос ON_NOTIFY_REFLECT ? А>>>чем отличается ON_NOTIFY от ON_NOTIFY_REFLECT ?
это не должно работать.
Здравствуйте, Аноним, Вы писали:
А>Спасиба ,....вроде раздуплил ...а вот еще ON_NOTIFY_REFLECT_EX ?
скажем так, тебе для чего ?
если для зачета то лучший способ воспользоваться непосредственно в процедуре зачета функцией CopyPaste
а если нет, то в чем задача? Просто обычно ON_NOTIFY и ON_NOTIFY_REFLECT хватает в 99 из ста.
Re[4]: чем отличается ON_NOTIFY от ON_NOTIFY_REFLECT ?
От:
Аноним
Дата:
23.07.05 17:07
Оценка:
Мне надо сделать так, чтобы нотификация не попадала паренту в любом случае, а попадала и обрабатывалась в самом контороле. А>>Спасиба ,....вроде раздуплил ...а вот еще ON_NOTIFY_REFLECT_EX ? C> скажем так, тебе для чего ? C>если для зачета то лучший способ воспользоваться непосредственно в процедуре зачета функцией CopyPaste C>а если нет, то в чем задача? Просто обычно ON_NOTIFY и ON_NOTIFY_REFLECT хватает в 99 из ста.
Здравствуйте, Аноним, Вы писали:
А>Мне надо сделать так, чтобы нотификация не попадала паренту в любом случае, а попадала и обрабатывалась в самом контороле.
Если я правильно понимаю, это невозможно.
Потому что сама винда посылает паренту WM_NOTIFY, он вот парент — он уже такая душка, что рефлектит это сообщение контролу, только уже под видом WM_NOTIFY_REFLECT, чтоб он сам попробовал его обработать. А мог бы и не рефлектить :)
Здравствуйте, Аноним, Вы писали:
А>Мне надо сделать так, чтобы нотификация не попадала паренту в любом случае, а попадала и обрабатывалась в самом контороле. А>>>Спасиба ,....вроде раздуплил ...а вот еще ON_NOTIFY_REFLECT_EX ? C>> скажем так, тебе для чего ? C>>если для зачета то лучший способ воспользоваться непосредственно в процедуре зачета функцией CopyPaste C>>а если нет, то в чем задача? Просто обычно ON_NOTIFY и ON_NOTIFY_REFLECT хватает в 99 из ста.
Нужны побробности, какой контрол, виндовс какая? Не уверен, но попробовать можно.
Здравствуйте, SchweinDeBurg, Вы писали:
SDB>При использовании ON_NOTIFY() извещения от элемента управления обрабатывает его родительское окно, как это и принято в Win32 API; при использовании ON_NOTIFY_REFLECT() Вы получаете возможность обработать это извещение в самом элементе управления
Вроде всё правильно, но не могли бы вы разъяснить ещё один момент. Если я использую класс, производный от какого-либо CView, например CListView, то для обработки извещений от CListCtrl, например NM_CUSTOMDRAW, я использую макрос:
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw),
причём именно в классе наследнике от CListView. Как я понимаю CListCtrl — member этого самого CListView и дочерний контрол для окна, которое описывает класс производный от CListView, т.е. я обрабатываю извещение от контрола в классе его родительского окна.
Буду благодарен за ответ.
Re[2]: Чем отличается ON_NOTIFY от ON_NOTIFY_REFLECT ?
Здравствуйте, Pupil, Вы писали:
P>Здравствуйте, SchweinDeBurg, Вы писали:
SDB>>При использовании ON_NOTIFY() извещения от элемента управления обрабатывает его родительское окно, как это и принято в Win32 API; при использовании ON_NOTIFY_REFLECT() Вы получаете возможность обработать это извещение в самом элементе управления
P>Вроде всё правильно, но не могли бы вы разъяснить ещё один момент. Если я использую класс, производный от какого-либо CView, например CListView, то для обработки извещений от CListCtrl, например NM_CUSTOMDRAW, я использую макрос:
P>ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw),
P>причём именно в классе наследнике от CListView. Как я понимаю CListCtrl — member этого самого CListView и дочерний контрол для окна, которое описывает класс производный от CListView, т.е. я обрабатываю извещение от контрола в классе его родительского окна.
не совсем так. Сразу расставим точки над Ы
Мы говорили о родительском окне в понимании Windows, т.е. из серии контрол-диалог. А наследник CView-CListView это исключительно в понимании C++. На самом деле это одно и тоже окно, достаточно сравнить просто hWnd CListCtrl и hWnd CListView ==одно окно. Можно просто с помощью Spy++ проследить иерархию окон Windows в MFC приложении.
1) когда происходит событие (ну не знаю уж как точнее сказать) то окно ListView отошлет своему родителю WM_NOTIFY-сообщение с code==NM_CUSTOMDRAW. Для SDI-проектов это главное окно (CMainFrame), для MDI-проектов это дочерний фрейм (CChildFrame)
2) А уж карта сообщений перенаправит его в обратно в код контрола.
Вот что действительно интересно, что будет если прописать в CListView ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw), а в его родительском окне (в том же CMainFrame для SDI-проектов) прописать ON_NOTIFY(NM_CUSTOMDRAW, IDC_LISTVIEW, OnCustomDraw) где оно поймается первым. Насколько я понимаю маршрутизацию сообщений в MFC поймается по идее раньше в CMainFrame (в родительском окне). Но вообще я так никогда не делал — но все же дюбопытно.
Здравствуйте, SchweinDeBurg, Вы писали:
SDB>Здравствуйте, Pupil, Вы писали:
P>>Как я понимаю CListCtrl — member этого самого CListView и дочерний контрол для окна, которое описывает класс производный от CListView, т.е. я обрабатываю извещение от контрола в классе его родительского окна.
SDB>Неправильно понимаете. Ключевой момент:
SDB>
SDB>А в дополнение советую посмотреть в сорцах MFC объявление/реализацию CListView и CCtrlView, являющегося его непосредственным предком.
А собственно насчет марштутизации если два макроса (ON_NOTIFY от ON_NOTIFY_REFLECT) в родительском окне и в контроле, где поймается первым? По идее в карте родительского окна (CDialog к примеру) "найдется" скорее всего функция раньше? И насколько я понимаю дальнейшая маршрутизация сообщения прекратится?
Здравствуйте, Carc, Вы писали:
C>А собственно насчет марштутизации если два макроса (ON_NOTIFY от ON_NOTIFY_REFLECT) в родительском окне и в контроле, где поймается первым? По идее в карте родительского окна (CDialog к примеру) "найдется" скорее всего функция раньше? И насколько я понимаю дальнейшая маршрутизация сообщения прекратится?
Честно говоря, я таких "каскадных" ON_NOTIFY_REFLECT() не использовал, поэтому сказать не могу. Проверяйте опытным путем...
...и следите за объемом цитирования.
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]