Здрасьте всем! Вопросец: как отловить мышиные сообщения/события в активном (попап) меню? Исследуется процесс создания нестандартного вида меню... Стоит задача реагировать на клик мышкой в конкретной области меню-итема (он OWNERDRAW и DISABLED - иначе срабатывать будет по всему итем-ректанглу). Имеются у кого какие идеи? Заранее благодарен. ЗЫЖ Пешу на VC6/7. Использую чистый API. МФЦ не переношу на дух!
sinth твой вопрос к прикладному программированию, гуёвому, относиться, а не к системному. и на базе MFC на codeproject.com дочерта чего интересного и тебе бы пригодилось. Что бы что-то не переносить, нужно сначала это изучить и понимать как это работает. И такие высказывания "МФЦ не переношу на дух!" - признак глубокой не компетенции можеш аргументировать почему конкретно не переносишь ?
Это делается примерно так: родитель меню обрабатывает wm_enteridle, и если передан параметр MSGF_MENU, то прога обретает хендл меню. Над ним нужно прочесть молитву SetWindowLong + GWL_WNDPROC, переопределив в "самопальном" обработчике реакцию на WM_NCHITTEST. После собственного обработчика следует передавать управление перекрытому.
Согласен, не знаю очень многого - иначе не спрашивал бы! МФЦ хорош для БОЛЬШИХ проектов и очччень много в нем всякого полезного (и не очень). Но с ним не получить мелкую утилитку с мелким же размером. Ехешник распухает от всякого ненужного в большинстве (моих по крайней мере) случаев кода типа всяких там проверок, обработчиков исключений и прочего, чего я не вижу в своем сишном коде, и чего я от VC не ждал и не просил... Я не профессиональный кодер (хотя и имею соответствующее образование) и для моих нужд МФЦ - кувалдой тараканов бить Скажем так - я - ленивый оптимизатор - иначе писал бы на АСМе! Не люблю я РАДы и всякие громоздкие объектные библиотеки. И многие программы, которые на них (в них, с ними) писаны. Intel Server Manager, или HP Status Monitor, например (причем не самые худшие примеры ). Зачем писать небольшие системные утилитки на АСП, .НЕТ и т.п.? Хотя все это - вопрос религий и пристрастий, кому как... Видел я на РСДН кусок переводной статьи с того же codeproject. Там чел именно в МФЦ делал. Меню с полоской в левой части - как в "Пуске", и возможностью вставки своих контролов. Но он делал окно с тулбаром в виде меню. Мне же нужно со "стандартным" меню извратиться! Во как! Чет я разошелся - чую вкатает мне админ! ЗЫЖ А GUI - не часть ли Win32 API?! ЗЗЫЖ Прошу прощения, если че не так!.. Слово не воробей - не поймал - вылетишь...
Чет ни асилил - получаемый хендл меню - он же хендл попап окна, так чтоли? Если не затруднит, разъясните, пожалуйста. Пасибки. И заранее еще раз пасибки...
Спасибо, товарищ! Научили! Вчера уже попробовал! Субклассинг еще не делал - надо поковырять получаемое окно на предмет структурной организации (ну типа чилды проенумить), а тогда уже оконную процедуру подменять... Зато прикольно - сделал прозрачные меню А в M$DN сам не нашел бы... Еще раз спасибо! :beer: !!!
Рано обрадовался! Чего-то не получаиццо Перехватываю оконную функцию для окна меню, но в ней не ловятся никакие сообщения от мыши. По крайней мере, в переопределенных мною обработчиках ничего не выполняется (пробовал WM_(NC)MOUSEMOVE, WM_(NC)LBUTTONDOWN, WM_NCHITTEST). Я ф шоке! Как такое может быть? И как с этим бороться?
Я говорил, что я лентяй? Прошчэ спросить, чем самому попробовать Так вот, обнаружил, что окно меню использует свои "мышиные" события, не описанные ни в одном из документов. Вот, если кому интересно, значения для uMsg в субклассированном окне меню: 0x1E5, 0x1EB - вызываются при перемещениях курсора мыши; 0x1ED - левая кнопка мыши нажата, 0x1EF - отпущена; 0x1E4 - меню деактивировано. Также используются WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED, WM_DESTROY. Это для попупов из стандартного менюбара. С попупами при помощи TrackPopupMenu(Ex) еще не баловался... ЗЫЖ Еще можно постоянно ловить WM_ENTERIDLE, определяя текущую позицию курсора при помощи GetCursorPos...
Как закрыть TrackPopupMenu программно? UPD: Разобрался. Как правильно написал DEEP, нужно только дождаться WM_ENTERIDLE в wndproc, убедиться, что wParam == MSGF_MENU и получить из lParam хэндл меню. А там уже и CloseWindow и все остальное вполне себе действует. Кстати, это еще способ полностью перерисовать окно в "стиле XP", без серой 3d-рамки.
пытаюсь сделать как сказал DEEP : но не работает. программа вылетает после того как курсор мыши попадает на само меню. Код (Text): LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_ENTERIDLE: if ( wParam == MSGF_MENU ) if ( lpfnMenuOldWndProc != (WNDPROC) GetWindowLong ( (HWND)lParam, GWL_WNDPROC ) ) lpfnMenuOldWndProc = (WNDPROC) SetWindowLong ( (HWND)lParam, GWL_WNDPROC, (DWORD)MenuPaint ); break; ... LRESULT CALLBACK MenuPaint ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { return CallWindowProc ( lpfnMenuOldWndProc, hwnd, message, wParam, lParam ); } Что я делаю не так?