我有我的對話框派生自CDialog,我想在用戶將鼠標光標從它移開後關閉它。爲此,我添加了OnMouseLeave處理程序,它調用OnCancel()。據我所知,爲了及時發送WM_MOUSELEAVE事件,必須在OnMouseMove例程中調用TrackMouseEvent。所以整個代碼如下:從CDialog上的子控件接收WM_MOUSEMOVE
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知道現在控制什麼。任何想法如何解決這一問題?
好。儘管如此,我會盡力避免發送不可發送的系統消息。如果你使用一個定時器,爲什麼不直接把它放在對話框類本身中,以'GetCursorPos','GetWindowRect','PtInRect','OnCancel()'的形式? – l33t 2012-02-03 12:21:20
你稱之爲「不可發送」的消息是什麼?我看到沒有區別,只是從MSDN複製粘貼此計時器處理程序代碼。 – Mikhail 2012-02-03 13:44:40