最近看到很多帖子是關於窗體繪製鼠標座標的問題,於是自己閒來無聊加上心血來潮,就寫了一個基於對話框的鼠標座標顯示
開始吧
一、定義成員變量:
m_strpt :顯示的座標字串
m_point :鼠標座標位置
m_Rect :要繪製的區域
二、OnMouseMove獲取鼠標座標
鼠標座標的獲取當然在OnMouseMove消息函數裏是一個比較簡便的方式,一般不要求很精確的時候,就在這裏面獲取
用嚮導生成該函數,並增加代碼,代碼如下:
void CGetHostIPDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CRect rectpt;
CString strpt;
rectpt = CRect(m_point.x,m_point.y,m_point.x+m_strpt.GetLength()*12,m_point.y+20);
InvalidateRect(&rectpt);//擦除原先鼠標座標,否則會有殘留的座標
strpt.Format("%d,%d",point.x,point.y);
rectpt = CRect(point.x,point.y,point.x+strpt.GetLength()*12,point.y+20);
m_strpt = strpt;
m_point = point;
m_Rect = rectpt;
InvalidateRect(&rectpt);//繪製當前鼠標座標
CDialog::OnMouseMove(nFlags, point);
}
三、OnPaint繪製
在OnPaint函數的else語句裏
else
{
CPaintDC dc(this);
dc.DrawText(m_strpt,&m_Rect,DT_BOTTOM);
CDialog::OnPaint();
}
好了,現在就可以進行測試了,我們看到,在窗體內可以進行鼠標座標的繪製顯示了
但是我們也發現還有個問題:當鼠標移動到標題欄上或窗體外時,窗體上還依然繪製着原先的鼠標座標
經過了VisualEleven 的指導後,終於搞定了,在此感謝VisualEleven
這個問題的原因是我們鼠標離開客戶區的時候沒有重繪我們上一次繪製的地方導致的
可以設置一個變量來判斷是否在客戶區內:m_bIn,
是,繪製鼠標座標,不是,用背景色填充上次繪製的鼠標座標
那麼我們該如何處理呢?
四、有兩個消息:WM_MOUSELEAVE,WM_MOUSEHOVER
這兩個消息在嚮導裏找不到,並沒有相應的消息響應函數
我們通過重載BOOL PreTranslateMessage(MSG* pMsg)函數來捕捉這兩個消息
1、在頭文件public中聲明一下:
virtual BOOL PreTranslateMessage(MSG* pMsg);
2、在cpp文件中
BOOL CGetHostIPDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if(WM_MOUSELEAVE == pMsg->message)
{
m_bIn = FALSE;
InvalidateRect(m_Rect);
return TRUE;
}
else if(WM_MOUSEHOVER == pMsg->message)
{
m_bIn = TRUE;
InvalidateRect(m_Rect);
return TRUE;
}
return CWnd::PreTranslateMessage(pMsg);
}
同時將OnPaint語句修改爲如下:
else
{
CPaintDC dc(this);
if (m_bIn)
{
dc.DrawText(m_strpt,&m_Rect,DT_BOTTOM);
}
else
{
dc.FillSolidRect(&m_Rect,GetSysColor(COLOR_3DFACE));//對話框的系統顏色
}
CDialog::OnPaint();
}
五、_TrackMouseEvent
此時我們發現並沒有捕獲到這兩個消息,爲什麼呢,這邊還有個很牛叉的東東:
_TrackMouseEvent:在鼠標離開某一窗口或在某一窗口上停留超過某一特定時間長度時發送消息
於是我們在OnMouseMove函數的後面加如下語句:
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_HOVER | TME_LEAVE;
tme.dwHoverTime = HOVER_DEFAULT;
tme.hwndTrack = GetSafeHwnd();
_TrackMouseEvent(&tme);
於是,搞定……