CRectTracker(橡皮筋)類的使用

CRectTracker(俗稱“橡皮筋”類)是一個非常有意思的類。你在Windows中,在桌面上用鼠標拖拽,便可以看到一個虛線的矩形框,它便是橡皮筋.它可以用做顯示邊界,你也可以扽它的八個角用來放大縮小,做框選使用。如何通過編程來實現這種功能呢?這就是CRectTracker類的作用;
介紹橡皮筋類前,先介紹其他兩個類:

(1) Cpoint 類或Point類,cpoint.x   cpoint.y,作爲屏幕上的座標上的x和y 軸的座標。

(2) CRect類,既矩形類。
crect.left   crect.bottom   crect.top   crect.right,
Crect::setrect(crect.left, crect.top, crect.right,crect.bottom);



CrectTracker 類成員:
一 數據成員:(摘自msdn 2000,省略了一些)
1. m_rect
當前橡皮筋矩形的矩形框的位置
2. m_sizeMin
決定橡皮筋矩形的最新的長和寬
3.m_nStyle
橡皮筋矩形的形式如:
CRectTracker::solidLine   用實線標記矩形框
CRectTracker::dottedLine 虛線
CRectTracker::hatchedBorder 影陰線
CRectTracker::resizeInside   改變大小的句柄在橡皮筋矩形框內部(點在橡皮筋矩形框
裏面來改變大小)
CRectTracker::resizeOutside 改變大小的句柄在橡皮筋矩形框外部
CRectTracker::hatchInside 影陰線佈滿總個矩形框
二 成員函數:
1.void Draw( CDC* pDC ) const;
這個函數用來劃矩形框的邊框和內部區域。
2.void GetTrueRect( LPRECT lpTrueRect ) const;
這個函數用來換回矩形框的 矩形座標,參數爲CRECT類型,返回矩形
3.int HitTest( CPoint point ) const;
當你鼠標被按下的時候,你可以調用這個函數,它將返回鼠標點在了矩形框的什麼位置:可以看出,返回值如果大於等於零則在四邊形區域之內。如果小於則說明不在區域範圍之內。

返回值代表的含義-1點在了四邊形的外部0左上角1右上角2右下角3左下角(0,1,2,3順時針轉了一圈)4頂部5右部6底部7左部(還是順時針轉了一圈)8點在了四邊形的內部,但沒有擊中前面的那八個點
4.BOOL SetCursor( CWnd* pWnd, UINT nHitTest ) const;
調用這個函數用來當鼠標放在矩形框時,顯示各種鼠標形象

5.BOOL Track( CWnd* pWnd, CPoint point, BOOL bAllowInvert = FALSE, CWnd* pWndClipTo = NULL );
這個函數用來顯示當人們用鼠標改變矩形框大小 或 拖拽矩形框時顯示矩形框動作
一般由WM_LBUTTONDOWN 消息來觸發這個函數, 不需要編寫MouseMove函數,矩形框它就自動的變大小了呢?這就是Track()函數的功勞,從調用它到擡起鼠標鍵爲止,它時刻的改變四邊形的大小。

6.BOOL TrackRubberBand( CWnd* pWnd, CPoint point, BOOL bAllowInvert = TRUE );
當鼠標在空區域拖拽時顯示橡皮筋矩形框,讓鼠標畫一個橡皮筋區域,第一個參數,畫“橡皮筋”的窗體的指針,當然是this ,第二個參數,畫“橡皮筋”的起始點。 讓我們注意第三個參數,它非常有意思。當你使用 FALSE時(TRUE 值是缺省的),你的“橡皮筋”只能從左上到右下的畫,不允許反向。編譯運行一下FALSE這個值。
特別值得注意的是:在TrackRubberBand的過程中是以右鍵的擡起爲結束的,這其間並沒有CViewMouseMove發生。這一點一定要記住!這時鼠標畫過的區域已經記錄在CrectTracker 類數據成員 m_rect裏面了,即CrectTracker:: m_rect.
下面我舉一個自己已經測試的例子:
我要實現的是一個在圖片控件上選定一部分的功能。首先,在界面上畫一個圖片控件,ID爲:IDC_PICTURE,實現在控件裏選定某一塊內容的功能,
首先,在重載主界面的OnLButtonDown(鼠標左鍵點下消息)函數

CRectTracker m_tracker;

m_tracker.m_nStyle=CRectTracker::resizeInside|CRectTracker::solidLine|CRectTracker::hitNothing;


void CmrDlg::OnLButtonDown(UINT nFlags, CPoint point)   //在鼠標左鍵消息中響應拖拽
{
       // TODO: 在此添加消息處理程序代碼和/或調用默認值
       int nIn;                         //定義一個鼠標的點擊值;
       nIn=m_tracker.HitTest(point);       //看看點到了哪了

       CRect Prect1;          //定義圖片的矩形
       CRect Trect;          //定義橡皮筋框的矩形
       CRect Prect;         //圖片矩形框

       GetDlgItem(IDC_PICTURE)->GetWindowRect(&Prect1);    //得到圖片的矩//形大小

       ScreenToClient(&Prect1);   //將圖片框的絕對矩形大小

//判斷是否在圖片框內,不處理不在圖片框內的點擊
              if (point.x<Prect1.left||point.x>Prect1.right||point.y<Prect1.top||point.y>Prect1.bottom)
                               return;

m_tracker.SetCursor(this,nFlags); //改變鼠標的形狀
       if(nIn<0)                 //不在四邊形區域內;
       {
              Invalidate(true);
              m_tracker.TrackRubberBand(this,point,false);   //不在矩形框內則畫橡皮///筋框


              GetDlgItem(IDC_PICTURE)->GetWindowRect(&Prect); //得到圖片框的//矩形
              ScreenToClient(&Prect);
              Trect=m_tracker.m_rect;   //得到畫好的橡皮筋框

              //調整大小
              Trect.top=(Trect.top<Prect.top?Prect.top:Trect.top);
              Trect.left=(Trect.left<Prect.left?Prect.left:Trect.left);
              Trect.bottom=(Trect.bottom>Prect.bottom?Prect.bottom:Trect.bottom);
              Trect.right=(Trect.right>Prect.right?Prect.right:Trect.right);

              m_tracker.m_rect.SetRect(Trect.left,Trect.top,Trect.right,Trect.bottom); //畫出調整好的矩形框

              CClientDC dc(this);
              m_tracker.Draw(&dc);    //畫好矩形框

       }
       else
              //在四邊形區域內:
       {
              Invalidate(); //重畫界面

              CClientDC dc(this);
              GetDlgItem(IDC_PICTURE)->GetWindowRect(&Prect);


           ClipCursor(&Prect); //api函數,將鼠標限制在圖片框內

              m_tracker.Draw(&dc);
              m_tracker.Track(this,point,false);

            ScreenToClient(&Prect);

              Trect=m_tracker.m_rect;   //得到畫好的橡皮筋框

//調整矩形框的位置
              if (Trect.top<Prect.top)
              {//超出圖片框頂部的位置
                     Trect.bottom=Prect.top-Trect.top+Trect.bottom;
                     Trect.top=Prect.top;
              }
              if (Trect.bottom>Prect.bottom)
              {//超出底部的位置
                     Trect.top=Prect.bottom-Trect.bottom+Trect.top;
                     Trect.bottom=Prect.bottom;
              }
              if (Trect.right>Prect.right)
              {//超出右邊
                     Trect.left=Prect.right-Trect.right+Trect.left;
                     Trect.right=Prect.right;
              }
              if (Trect.left<Prect.left)
              {//超出左邊
                     Trect.right=Prect.left-Trect.left+Trect.right;
                     Trect.left=Prect.left;
              }
//設置矩形框大小
              m_tracker.m_rect.SetRect(Trect.left,Trect.top,Trect.right,Trect.bottom);

              m_tracker.Draw(&dc);
              // Track()CRectTracker中最富魅力的函數。它時時的改變調用者的m_rect;
              ClipCursor(NULL);   //釋放對鼠標的限制
       }

       AbsRect.left=abs(Trect.left-Prect.left);
       AbsRect.right=abs(Trect.right-Prect.right);
AbsRect.top=abs(Trect.top-Prect.top);
AbsRect.bottom=abs(Trect.bottom-Prect.bottom);

       CDialog::OnLButtonDown(nFlags, point);
}
發佈了49 篇原創文章 · 獲贊 4 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章