У меня есть диалог, полученный из CDialog, и я хочу закрыть его, как только пользователь переместит курсор мыши от него. Для этого я добавил обработчик OnMouseLeave, который вызывает OnCancel (). Насколько я понимаю, для своевременной отправки событий WM_MOUSELEAVE необходимо вызвать TrackMouseEvent внутри подпрограммы OnMouseMove. Итак, весь код выглядит следующим образом:
void CDlgMain::OnMouseLeave()
{
CDialog::OnMouseLeave();
// Close dialog when cursor is going out of it
OnCancel();
}
void CDlgMain::OnMouseMove(UINT nFlags, CPoint point)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE;
tme.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&tme);
CDialog::OnMouseMove(nFlags, point);
}
Он работает нормально, но диалоговое окно закрывается, когда пользователь наводит курсор на некоторые из его дочерних элементов управления (например, кнопки, на которые он хочет нажать :)). Это потому, что дочерние элементы управления не отправляют WM_MOUSEMOVE в родительский диалог.
Единственная функция, которую я обнаружил для «распространения» сообщений WM_MOUSEMOVE от дочерних элементов управления, - это SetCapture (). И он выполняет свою работу, но 1) пользователь не может нажать ни одну кнопку после этого и 2) значок мыши меняется на песочные часы. Так что это не вариант.
Какие-либо предложения?
Обновление. Я поместил вызов TrackMouseEvent в подпрограмму PreTranslateMessage, которая правильно вызывается при любых событиях перемещения мыши (даже при наведении курсора на дочерние элементы управления). Странно то, что WM_MOUSELEAVE все еще генерируется, когда пользователь наводит курсор на дочерний элемент управления! Похоже, TrackMouseEvent знает, какой элемент теперь завис. Любые идеи, как это исправить?