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();
    }
}

這樣我們的鼠標移動到客戶區外面也可以畫線了.

 

五丶了解鍵盤消息中的各位代表的含義

 

虛擬鍵代碼  VK_F1... . VK開頭的. 頭文件中有定義.有興趣的可以看一下.

nflgs中的第 14位 為如果先前按下.則為1.否則則為零. 其余的了解即可.

 WM_KEYDOWN WM_KEYUP 可以判斷鍵盤是否按下抬起. 通過nChar 可以確定是哪一個鍵. 

六丶API 判斷虛擬鍵碼是否按下.

Windows 為我們提供了一個API.用來檢索按鍵是否被按下.

GetKeyState(VK_F2)  

如果返回值為負數. 那么代表了按下. 如果返回值為0.則代表沒有按.

所以我們判斷返回值 < 0  則是按下  >0 則是沒有按下.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM