1. 程式人生 > >MFC控件編程之鼠標消息

MFC控件編程之鼠標消息

應該 ocl 當我 學習 們的 mov etc 鼠標 cli

            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控件編程之鼠標消息