MFC控件編程之鼠標消息
MFC控件編程之鼠標消息
在MFC中鼠標消息.鍵盤消息我們很常用.所以說一下.
鼠標消息分為客戶區消息.跟非客戶區消息.
一丶客戶區消息
我們可以處理消息.來進行我們相應的函數即可.
MFC添加消息的話.可以自己在消息映射表中添加 .可以自己使用工具直接添加.
消息映射表添加
學習過MFC原理的應該知道.這裏可以添加消息. 自己可以手動添加.我們也可以使用向導來添加.
void CCDCDlg::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息處理程序代碼和/或調用默認值 CString str; str.Format(TEXT("x坐標 = %d,y 坐標 = %d"), point.x, point.y); ::SetWindowText(m_hWnd, str); }
輸出我們的鼠標點擊的時候的坐標位置.調用 ::SetWindowText設置窗口標題.
三丶非客戶區消息
非客戶區消息就指的標題欄啊等等.這些位置.
而他們的消息多了一個NC開頭.
例如我們在消息映射表中添加一個NC開頭的消息.
我們也可以使用向導.看自己喜好了.
代碼:
void CCDCDlg::OnNcLButtonDown(UINT nFlags, CPoint point) { CString str; str.Format(TEXT("非客戶區 x坐標 = %d,y 坐標 = %d"), point.x, point.y); ::SetWindowText(m_hWnd, str); }
點擊標題欄
如果按照上面寫我們點擊關閉按鈕會關閉不了.原因就是NcLBUTTONDown裏面包括了點擊關閉按鈕的消息.你沒有進行處理.此時我們交給父類處理即可.
void CCDCDlg::OnNcLButtonDown(UINT nFlags, CPoint point) { CString str; str.Format(TEXT("非客戶區 x坐標 = %d,y 坐標 = %d"), point.x, point.y); ::SetWindowText(m_hWnd, str); CDialogEx::OnNcLButtonDown(nFlags,point); }
其中nflags是一個區域劃分嗎.我們可以自己判斷是否是哪個區域會享用.
例如:
if (nflags == HTSYSMENU) 判斷是否是菜單.... 進行你的操作
點擊客戶區
在我們的鼠標消息到來之前.它會先判斷是客戶區域還是非客戶區域.然後進行轉換.才給我們將消息發送過來.
也就是說我們可以吧客戶區轉換為非客戶區. 比如鼠標點擊客戶區.其實是點擊的非客戶區.
代碼如下.
LRESULT CCDCDlg::OnNcHitTest(CPoint point) { // TODO: 在此添加消息處理程序代碼和/或調用默認值 UINT hit = CDialogEx::OnNcHitTest(point); //獲取父類返回的判斷是否是客戶區還是非客戶區 if (hit == HTCLIENT) //如果是客戶區.那麽我們轉化為非客戶區 { hit = HTCAPTION; } return hit; }
實現的消息
API: 坐標轉為窗口坐標.
::ScreenToClient(m_hWnd, &point);
四丶捕獲鼠標
捕獲鼠標也很常用. 比如我們鼠標按下畫線.的時候. 鼠標會移動到窗口外邊.那這樣的話畫線就不會成功了.
實現思路:
1.鼠標點擊.保存一下坐標
2.鼠標擡起. 創建CClientDc. 使用MoveTo移動到保存的鼠標位置.
3.使用dc畫線.畫出新的位置.
例如:
鼠標按下.
void CCDCDlg::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息處理程序代碼和/或調用默認值 //保存當前位置. m_Point = point; }
m_point是在類中定義的一個成員.
鼠標擡起 void CCDCDlg::OnLButtonUp(UINT nFlags, CPoint point) { // CClientDC dc(this); dc.MoveTo(m_Point); dc.LineTo(point); }
實現截圖
遇到的問題.當我們鼠標拖動到窗口外面之後.就不會畫線了.所以我們要捕獲鼠標.
用到的三個API:
1.SetCapture(); 捕獲鼠標.在鼠標按下的時候.
2.GetCapture(); 獲取捕獲的鼠標.
3.ReleaseCapture(); 釋放
代碼如下.
void CCDCDlg::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息處理程序代碼和/或調用默認值 //保存當前位置. m_Point = point; SetCapture(); //捕獲鼠標 } void CCDCDlg::OnLButtonUp(UINT nFlags, CPoint point) { // CClientDC dc(this); dc.MoveTo(m_Point); dc.LineTo(point); if (GetCapture() == this) { ReleaseCapture(); } }
這樣我們的鼠標移動到客戶區外面也可以畫線了.
MFC控件編程之鼠標消息