Нестандартного вида меню. Меню и "мышиные" сообщения...

Тема в разделе "WASM.WIN32", создана пользователем sinth, 3 июн 2008.

  1. sinth

    sinth New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2008
    Сообщения:
    12
    Здрасьте всем!

    Вопросец: как отловить мышиные сообщения/события в активном (попап) меню? Исследуется процесс создания нестандартного вида меню...
    Стоит задача реагировать на клик мышкой в конкретной области меню-итема (он OWNERDRAW и DISABLED - иначе срабатывать будет по всему итем-ректанглу).

    Имеются у кого какие идеи?
    Заранее благодарен.

    ЗЫЖ Пешу на VC6/7. Использую чистый API. МФЦ не переношу на дух!
     
  2. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    sinth
    твой вопрос к прикладному программированию, гуёвому, относиться,
    а не к системному. и на базе MFC на codeproject.com
    дочерта чего интересного и тебе бы пригодилось.

    Что бы что-то не переносить, нужно сначала это изучить и понимать
    как это работает. И такие высказывания "МФЦ не переношу на дух!" -
    признак глубокой не компетенции :) можеш аргументировать почему
    конкретно не переносишь ?
     
  3. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Это делается примерно так: родитель меню обрабатывает wm_enteridle, и если передан параметр MSGF_MENU, то прога обретает хендл меню. Над ним нужно прочесть молитву SetWindowLong + GWL_WNDPROC, переопределив в "самопальном" обработчике реакцию на WM_NCHITTEST. После собственного обработчика следует передавать управление перекрытому.
     
  4. sinth

    sinth New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2008
    Сообщения:
    12
    Согласен, не знаю очень многого - иначе не спрашивал бы! ;)

    МФЦ хорош для БОЛЬШИХ проектов и очччень много в нем всякого полезного (и не очень). Но с ним не получить мелкую утилитку с мелким же размером. Ехешник распухает от всякого ненужного в большинстве (моих по крайней мере) случаев кода типа всяких там проверок, обработчиков исключений и прочего, чего я не вижу в своем сишном коде, и чего я от VC не ждал и не просил... Я не профессиональный кодер (хотя и имею соответствующее образование) и для моих нужд МФЦ - кувалдой тараканов бить ;) Скажем так - я - ленивый оптимизатор - иначе писал бы на АСМе!

    Не люблю я РАДы и всякие громоздкие объектные библиотеки. И многие программы, которые на них (в них, с ними) писаны. Intel Server Manager, или HP Status Monitor, например (причем не самые худшие примеры :) ). Зачем писать небольшие системные утилитки на АСП, .НЕТ и т.п.? Хотя все это - вопрос религий и пристрастий, кому как...

    Видел я на РСДН кусок переводной статьи с того же codeproject. Там чел именно в МФЦ делал. Меню с полоской в левой части - как в "Пуске", и возможностью вставки своих контролов. Но он делал окно с тулбаром в виде меню. Мне же нужно со "стандартным" меню извратиться! Во как!

    Чет я разошелся - чую вкатает мне админ! ;)

    ЗЫЖ А GUI - не часть ли Win32 API?!

    ЗЗЫЖ Прошу прощения, если че не так!..

    Слово не воробей - не поймал - вылетишь... :)
     
  5. sinth

    sinth New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2008
    Сообщения:
    12
    Чет ни асилил - получаемый хендл меню - он же хендл попап окна, так чтоли? Если не затруднит, разъясните, пожалуйста.

    Пасибки.

    И заранее еще раз пасибки...
     
  6. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Именно! Это хендл окна меню. А окно меню, как и всякое другое, должно обрабатывать хит-тесты.
     
  7. sinth

    sinth New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2008
    Сообщения:
    12
    Спасибо, товарищ! Научили!

    Вчера уже попробовал! Субклассинг еще не делал - надо поковырять получаемое окно на предмет структурной организации (ну типа чилды проенумить), а тогда уже оконную процедуру подменять... Зато прикольно - сделал прозрачные меню ;)

    А в M$DN сам не нашел бы...
    Еще раз спасибо!

    :beer: !!!
     
  8. sinth

    sinth New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2008
    Сообщения:
    12
    Рано обрадовался! Чего-то не получаиццо :dntknw:

    Перехватываю оконную функцию для окна меню, но в ней не ловятся никакие сообщения от мыши. По крайней мере, в переопределенных мною обработчиках ничего не выполняется (пробовал WM_(NC)MOUSEMOVE, WM_(NC)LBUTTONDOWN, WM_NCHITTEST).

    Я ф шоке! Как такое может быть? И как с этим бороться?
     
  9. sinth

    sinth New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2008
    Сообщения:
    12
    Я говорил, что я лентяй? Прошчэ спросить, чем самому попробовать :)

    Так вот, обнаружил, что окно меню использует свои "мышиные" события, не описанные ни в одном из документов.

    Вот, если кому интересно, значения для uMsg в субклассированном окне меню:

    0x1E5, 0x1EB - вызываются при перемещениях курсора мыши;
    0x1ED - левая кнопка мыши нажата, 0x1EF - отпущена;
    0x1E4 - меню деактивировано.

    Также используются WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED, WM_DESTROY.

    Это для попупов из стандартного менюбара. С попупами при помощи TrackPopupMenu(Ex) еще не баловался...

    ЗЫЖ Еще можно постоянно ловить WM_ENTERIDLE, определяя текущую позицию курсора при помощи GetCursorPos...
     
  10. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    Как закрыть TrackPopupMenu программно?

    UPD:
    Разобрался. Как правильно написал DEEP, нужно только дождаться WM_ENTERIDLE в wndproc, убедиться, что wParam == MSGF_MENU и получить из lParam хэндл меню. А там уже и CloseWindow и все остальное вполне себе действует.
    Кстати, это еще способ полностью перерисовать окно в "стиле XP", без серой 3d-рамки.
     
  11. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    пытаюсь сделать как сказал DEEP :
    но не работает. программа вылетает после того как курсор мыши попадает на само меню.

    Код (Text):
    1. LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    2. {
    3.     switch (message)              
    4.     {
    5.         case WM_ENTERIDLE:
    6.             if ( wParam == MSGF_MENU )
    7.                 if ( lpfnMenuOldWndProc != (WNDPROC) GetWindowLong ( (HWND)lParam, GWL_WNDPROC ) )
    8.                     lpfnMenuOldWndProc = (WNDPROC) SetWindowLong ( (HWND)lParam, GWL_WNDPROC, (DWORD)MenuPaint );
    9.         break;
    10.  
    11. ...
    12.  
    13. LRESULT CALLBACK MenuPaint ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    14. {
    15.     return CallWindowProc ( lpfnMenuOldWndProc, hwnd, message, wParam, lParam );
    16. }
    Что я делаю не так?