程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> 淺談在應用CRectTracker類的程序中響應WM_LBUTTONUP消息

淺談在應用CRectTracker類的程序中響應WM_LBUTTONUP消息

編輯:vc教程

  CRectTracker類也有人稱之為“橡皮筋”類。我們可以通過Windows自帶的畫圖板來了解這個類的作用:用“選定”功能在畫圖區隨意選中一塊兒區域,此時會出現一個由虛線和八個調整標記點組成的矩形選框,我們可通過鼠標點中矩形選框的中心移動其位置,並且能利用調整標記點來改變其大小……這個矩形選框其實就是一個“橡皮筋選框”。

  CRectTracker類的使用並不是什麼新鮮的話題,然而在應用這個類的過程中,我卻發現了一個小問題:我創建了一個對話框程序,希望利用CRectTracker類在對話框上畫出一個“橡皮筋選框”,為了使鼠標按下並拖動鼠標的同時出現虛線的選擇框,我在程序中加入了以下代碼:

void CCRectTracker_DemoDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  //當鼠標左鍵按下時
  CRectTracker temp;
  temp.TrackRubberBand(this,point,TRUE);
  temp.m_rect.NormalizeRect();
  
  CDialog::OnLButtonDown(nFlags, point);
}
  這段代碼確實實現了我所期望的效果。但在程序的另一個地方:

void CCRectTracker_DemoDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  //當鼠標左鍵松開時
  MessageBox("鼠標左鍵松開","松開",NULL);
  
  CDialog::OnLButtonUp(nFlags, point);
}

  OnLButtonUp()事件絲毫不理睬我鼠標的動作——MessageBox()並沒有執行。仔細一想:TrackRubberBand()是以鼠標左鍵的松開作為結束標志的,當WM_LBUTTONUP消息發出後,TrackRubberBand()在OnLButtonUp()事件響應前就截獲了該消息,所以OnLButtonUp()事件就無法正常響應了……想到這裡,腦海中也就浮現了一個解決這個小問題的辦法,那就是:在TrackRubberBand()後,向程序自身發送一個自己構造的WM_LBUTTONUP消息。於是將OnLButtonDown()中的代碼改寫成為以下形式:

void CCRectTracker_DemoDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  //當鼠標左鍵按下時
  CRectTracker temp;
  temp.TrackRubberBand(this,point,TRUE);
  temp.m_rect.NormalizeRect();
  //自己構造的WM_LBUTTONUP消息
  this->SendMessage(WM_LBUTTONUP,NULL,NULL);
  CDialog::OnLButtonDown(nFlags, point);
}

  測試後的結果另人滿意,現在我所遇到的問題迎刃而解了。在本文附帶的Demo程序中,程序分別獲取鼠標左鍵按下和松開時的坐標,然後調用修改後的OnPaint()來畫出“橡皮筋矩形”,下面給出Demo中的部分關鍵代碼:

BOOL CCRectTracker_DemoDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
  // TODO: Add your message handler code here and/or call default
  //////////////////////
  //改變光標的形狀
  if (pWnd == this && m_rectTracker.SetCursor(this, nHitTest))
    return TRUE;
  //////////////////////
  else
    return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
void CCRectTracker_DemoDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  ///////////////////////////////////////
  //如鼠標點擊位置不在選框區域內,則構造一個新選框
  Invalidate(TRUE);
  if(m_rectTracker.HitTest(point)<0)
  {
    IsLButtonDown=TRUE;
    CRectTracker temp;
    temp.TrackRubberBand(this,point,TRUE);
    temp.m_rect.NormalizeRect();
    
    //鼠標(矩形選框)起始位置
    pt_start=point;
    //鼠標(矩形選框)結束位置
    GetCursorPos(&pt_end);
    this->SendMessage(WM_LBUTTONUP,NULL,NULL);
  }
  //否則重置選框大小或位置
  else
  {
    m_rectTracker.Track(this,point,TRUE);
    m_rectTracker.m_rect.NormalizeRect();
    this->OnPaint();
  }
  ///////////////////////////////////////
  
  CDialog::OnLButtonDown(nFlags, point);
}
void CCRectTracker_DemoDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  /////////////////////////////////
  //確保在構造一個新選框時才響應OnLButtonUp,否則在響應OnLButtonDblClk時會出現錯誤結果
  if(IsLButtonDown==TRUE)
  {
    //MessageBox("鼠標左鍵松開","松開",NULL);
    
    //由於GetCursorPos獲得的pt_end是Screen坐標,故用ScreenToClIEnt()進行轉換
    rect.right=pt_end.x;
    rect.bottom=pt_end.y;
    ScreenToClIEnt(&rect);
    pt_end.x=rect.right;
    pt_end.y=rect.bottom;
    
    //left,top,right,bottom
    m_rectTracker.m_rect.SetRect(pt_start.x,pt_start.y,pt_end.x,pt_end.y);
    m_rectTracker.m_rect.NormalizeRect();
    
    this->OnPaint();
    IsLButtonDown=FALSE;
  }
  /////////////////////////////////
  
  CDialog::OnLButtonUp(nFlags, point);
}
void CCRectTracker_DemoDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  ////////////////////////////
  MessageBox("鼠標左鍵雙擊","雙擊",NULL);
  ////////////////////////////
  
  CDialog::OnLButtonDblClk(nFlags, point);
}
  由於本人水平所限,關於CRectTracker類的詳細使用方法請參閱其他資料。謝謝!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved