Уведомление BCN_HOTITEMCHANGE не вызывается с классом CMFCButton - PullRequest
0 голосов
/ 11 октября 2019

BCN_HOTITEMCHANGE код вызова не вызывается с классом CMFCButton.

Я использую Visual Studio 2010

Выполненные действия:

1) Добавить CButton в мой диалогиз редактора ресурсов.

2) Используйте мой собственный производный класс CMFCButtonEx, производный от класса CMFCButton (который, в свою очередь, является производным от класса CButton).

3) Объявите переменную экземпляра CMFCButtonEx 'm_btn_ex' длямой диалог.

4) Добавить DDX_Control (pDX, IDC_BUTTON_EX, m_btn_ex);

5) Когда я нажимаю эту кнопку, все мои обработчики сообщений в производном классе вызываются, кроме уведомления BCN_HOTITEMCHANGE, связанного с OnButtonItemChangeфункция. Точка останова в этой функции никогда не срабатывает. Все остальные обработчики сообщений (OnMouseMove, OnMouseLeave и OnButtonClicked) вызываются правильно, и точки останова в них получают совпадение.

В качестве примечания, если я получу по классу CMFCButtonEx из класса CButton, тогда я смогу достичь точки остановав функции OnButtonItemChange, т.е. код уведомления BCN_HOTITEMCHANGE обрабатывается правильно

По какой-то причине мой код уведомления BCN_HOTITEMCHANGE не обрабатывается корректно классом CMFCButton. Я не могу понять, что я делаю здесь не так. Я также пытался использовать код уведомления TBN_HOTITEMCHANGE вместо BCN_HOTITEMCHANGE, но точка останова в функции OnButtonItemChange никогда не достигает.

Спасибо!

Код класса CMFCButtonEx:

IMPLEMENT_DYNAMIC(CMFCButtonEx, CMFCButton)
CMFCButtonEx::CMFCButtonEx()
{   
     m_bMouseTracking = FALSE    
}

CMFCButtonEx::~CMFCButtonEx()
{
}

BEGIN_MESSAGE_MAP(CMFCButtonEx, CMFCButton)
    //{{AFX_MSG_MAP(CMFCButtonEx)
    ON_WM_MOUSEMOVE()
    ON_WM_MOUSELEAVE()
    ON_NOTIFY_REFLECT_EX(BCN_HOTITEMCHANGE, OnButtonItemChange)
   //ON_NOTIFY_REFLECT_EX(TBN_HOTITEMCHANGE, OnButtonItemChange)
    ON_CONTROL_REFLECT_EX(BN_CLICKED, OnButtonClicked)  
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CMFCButtonEx::OnButtonClicked()
{
    AfxMessageBox("MFC Button Clicked");
    return FALSE;
}

BOOL CMFCButtonEx::OnButtonItemChange(NMHDR* pNMHDR, LRESULT* pResult)
{
    NMBCHOTITEM* pnmbchotitem = (NMBCHOTITEM*)pNMHDR;

    AfxMessageBox("MFC Button Item Change");

    *pResult = 0;
    return FALSE;
}

void CMFCButtonEx::OnMouseMove(UINT nFlags, CPoint point)
{
    if (!m_bMouseTracking)
    {
        TRACKMOUSEEVENT tme;
        tme.cbSize = sizeof(TRACKMOUSEEVENT);
        tme.dwFlags = TME_LEAVE;
        tme.hwndTrack = this->m_hWnd;

        if (::_TrackMouseEvent(&tme))
        {
            m_bMouseTracking = TRUE;
            AfxMessageBox("MFC Button Mouse Move");
        }
    }
    CMFCButton::OnMouseMove(nFlags, point);
}

void CMFCButtonEx::OnMouseLeave()
{
    m_bMouseTracking = FALSE;
    AfxMessageBox("MFC Button Mouse Move");
    CMFCButton::OnMouseLeave();
}

1 Ответ

0 голосов
/ 12 октября 2019

BCN_HOTITEMCHANGE не запускается для CMFCButton или любых классов, производных от CMFCButton

Как указано в документации , визуальный стиль должен быть включен, иначе BCN_HOTITEMCHANGE несрабатывает. CMFCButton опирается на метод рисования владельца, поэтому визуальный стиль для этой кнопки отключен.

Вы можете удалить BS_OWNERDRAW из вашего CMFCButtonEx класса. Но это не рекомендуется, поскольку CMFCButtonEx опирается на BS_OWNERDRAW.

Лучшим решением является получение вашего класса из CButton (и убедитесь, что визуальные стили включены), используйте пользовательское рисование вместо рисования владельца. Вам может не понадобиться OnMouseMove и OnMouseLeave.

class CMyButton : public CButton {}
...

BOOL CMyButton::OnButtonItemChange(NMHDR* pNMHDR, LRESULT* pResult)
{
    auto ptr = (NMBCHOTITEM*)pNMHDR;
    bool enter = ptr->dwFlags & HICF_ENTERING;
    if (enter)
        TRACE(L"CMyButton... enter\n");
    else
        TRACE(L"CMyButton... exit\n");
    *pResult = 0;
    return FALSE;
}
...