Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Не могу отловить событие класса CMenu

32K
24 октября 2008 года
Denis1986
27 / / 25.08.2008
Я пишу под VS 2008 и использую mfc для создания GUI.

Я работаю над созданием статус-бара, где будут отображаться подсказки к элементам различных меню приложения (на данный момент - всплывающих меню).
Для этого я отлавливаю событие WM_MENUSELECT. В принципе, это работает: когда пользователь наводит курсор на определённый элемент меню или меню закрывается, вызывается обработчик события MENUSELECT.

Но мне нужно каким-то образом распознавать момент, когда курсор мыши оказывается за пределами окна меню (меню при этом ещё не закрыто), чтобы в этот момент обновить статус-бар.
Если бы CMenu был снаследован от CWnd, то я бы просто отлавливал событие WM_MOUSELEAVE.

Подскажите, пожалуйста, что является для класса CMenu аналогом CWnd::WM_MOUSELEAVE.
288
24 октября 2008 года
nikitozz
1.2K / / 09.03.2007
Цитата: Denis1986

Но мне нужно каким-то образом распознавать момент, когда курсор мыши оказывается за пределами окна меню (меню при этом ещё не закрыто), чтобы в этот момент обновить статус-бар.



В этом случае родительскому окну приходит сообщение WM_MENUSELECT с ItemID равным 0.

32K
24 октября 2008 года
Denis1986
27 / / 25.08.2008
nikitozz
В том-то и дело, что сообщение WM_MENUSELECT с ItemID, равным 0, приходит уже при закрытии всплывающего меню, а не в момент, когда курсор мыши оказывается за пределами окна меню (по крайней мере у меня всё функционирует именно так).
288
24 октября 2008 года
nikitozz
1.2K / / 09.03.2007
Цитата: Denis1986
nikitozz
В том-то и дело, что сообщение WM_MENUSELECT с ItemID, равным 0, приходит уже при закрытии всплывающего меню, а не в момент, когда курсор мыши оказывается за пределами окна меню (по крайней мере у меня всё функционирует именно так).



Вообще-то странно. У меня в 2005 вот такой кусок кода

Код:
void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
{
    CFrameWnd::OnMenuSelect(nItemID, nFlags, hSysMenu);
    if (nItemID == 0)
        SetWindowText("");
    else
    {
        CString str;
        str.LoadString(nItemID);
        SetWindowText( (LPCTSTR)str );
    }
}

работает как должен работать. Т.е. при выделении какого-то пункта меню, соответствующим образом изменяется и заголовок окна, после того, как курсор убран с меню, но меню все еще открыто, заголовок окна становится пустым.
32K
24 октября 2008 года
Denis1986
27 / / 25.08.2008
nikitozz
Выложи, пожалуйста, свой тестовый проект с меню. Я сравню со своим вариантом (по куску кода отличий выявить не удалось).
288
27 октября 2008 года
nikitozz
1.2K / / 09.03.2007
Цитата: Denis1986
nikitozz
Выложи, пожалуйста, свой тестовый проект с меню. Я сравню со своим вариантом (по куску кода отличий выявить не удалось).



Вот, выкладываю.

32K
29 октября 2008 года
Denis1986
27 / / 25.08.2008
nikitozz
Спасибо! Благодаря твоему проекту я понял, что всплывающие и обычные меню генерируют несколько различный набор сообщений. Обычное меню генерирует событие WM_MENU_SELECT при выходе курсора за границы меню, а выплывающие меню - нет.

Поэтому я пошёл другим путём. Я снаследовал свой класс от CMenu и переопределил метод DrawItem():
Код:
void CMyMenu::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
    CPoint l_cursor_point;
    GetCursorPos(&l_cursor_point);

    //if mouse cursor is going out of menu item rectangle.
    if ((l_cursor_point.x <= m_menu_coordinates.x + lpDIS -> rcItem.left + m_left_border_thickness
        || l_cursor_point.y <= m_menu_coordinates.y + m_top_border_thickness
        || l_cursor_point.x > m_menu_coordinates.x + lpDIS -> rcItem.right
        || l_cursor_point.y >= m_menu_coordinates.y + lpDIS -> rcItem.bottom)
        && m_status_bar_event_handler != NULL && m_status_bar_event_handler -> GetSafeHwnd() != NULL)
    {
        m_status_bar_event_handler -> SendMessage(CStatusBarHelper::WM_CURSOR_OVER_MENU_BOUND);
    }
   
    __super::DrawItem(lpDIS);
}

Экземпляру класса CMyMenu предварительно задаются координаты, которые затем будут переданы в функцию TrackPopUpMenu(), а также CWnd*, который будет получать сообщения о выходе курсора за границы меню.
Тему можно считать закрытой :)
288
30 октября 2008 года
nikitozz
1.2K / / 09.03.2007
Цитата: Denis1986
nikitozz
Спасибо! Благодаря твоему проекту я понял, что всплывающие и обычные меню генерируют несколько различный набор сообщений.



Я немного затупил. Невнимательно прочел тему. Думал речь идет об обычном меню.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог