Всё!!! Задолбался совсем!!!
Если кто-то когда-то работал с Owner-Drawn Menu — то please HELP ME!!!
Вот проект. Есть owner-drawn menu CMenuEx. Всё рисуется хорошо, но вот когда доходить до пункта, где есть вложенное меню — то возникает странная ситуация — не обрабатывается WM_MEASUREITEM. В Output видно следующее:
Warning: unknown WM_MEASUREITEM for menu item 0xFFFFFFFF
Из-за этого этот пункт получается очень маленьким — вообщем выглядит плохо.
Почему это так получается? Как это исправить?
файл проекта
Видимо это баг CMenuEx. В WinAPI до пункта меню можно добратся двумя способами: по ID этого пункта и по индексу пункта. В первом случае будут проблемы при получении доступа к разделителям и пунктам имеющим подпункты -- у таких Item'ов ID = 0 (для разделителей) и -1 (для пунктов-родителей).
Проблема еще и в том, что процедуре пользовательской отрисовки всегда передаётся ID пункта, а не его индекс. Как это обойти, я так на вскидку не помню, если есть желание разобратся можешь посмотреть в исходниках "Меню с 32х битными картинками ..." -- оно написано для WTL, но суть будет понятна.
Здравствуйте, WinterMute, Вы писали:
WM>Видимо это баг CMenuEx. В WinAPI до пункта меню можно добратся двумя способами: по ID этого пункта и по индексу пункта. В первом случае будут проблемы при получении доступа к разделителям и пунктам имеющим подпункты -- у таких Item'ов ID = 0 (для разделителей) и -1 (для пунктов-родителей).
Не-а, тут такой проблемы нет — я просто отлавливаю такие значения (как, например =0, и своими руками рисую разделитель)
WM>Проблема еще и в том, что процедуре пользовательской отрисовки всегда передаётся ID пункта, а не его индекс. Как это обойти, я так на вскидку не помню, если есть желание разобратся можешь посмотреть в исходниках "Меню с 32х битными картинками ..." -- оно написано для WTL, но суть будет понятна.
ID я просто запоминаю в структуре которую связываю с конкретным пунктом меню.
Вот интерестная штука получилась. Если вызывать OnMeasureItem окна и там ссылаться на MeasureItem меню:
void CmenuView::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
m_menu->MeasureItem(lpMeasureItemStruct);
CView::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}
то всё работает класно. Почему событие доходит только до окна а не до меню? Почему окно может перехватить сообщение, а мой класс не может? И как всётаки словить его именно в моём класе CMenuEx?(ничего не изменяя в класе родительского окна)
WM>>Видимо это баг CMenuEx. В WinAPI до пункта меню можно добратся двумя способами: по ID этого пункта и по индексу пункта. В первом случае будут проблемы при получении доступа к разделителям и пунктам имеющим подпункты -- у таких Item'ов ID = 0 (для разделителей) и -1 (для пунктов-родителей).
__>Не-а, тут такой проблемы нет — я просто отлавливаю такие значения (как, например =0, и своими руками рисую разделитель)
С разделителем всё понятно, в первую очередь я имел ввиду пункт с подпунктами -- у него нет уникального ID.
__>ID я просто запоминаю в структуре которую связываю с конкретным пунктом меню.
__>Вот интерестная штука получилась. Если вызывать OnMeasureItem окна и там ссылаться на MeasureItem меню:
__>__>void CmenuView::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
__>{
__> m_menu->MeasureItem(lpMeasureItemStruct);
__> CView::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
__>}
__>
__>то всё работает класно. Почему событие доходит только до окна а не до меню? Почему окно может перехватить сообщение, а мой класс не может? И как всётаки словить его именно в моём класе CMenuEx?(ничего не изменяя в класе родительского окна)
Сообщения идут к окну вызвавшему меню. Чтобы твой класс получал эти сообщения нужно вручную, в процедуре обработки сообщений твоего окна переслать это сообщения твоему экземпляру класса CMenuEx. В WTL это делается макросом CHAIN_MSG_MAP_MEMEBER(), как MFC незнаю.