VC++楕円を描く例



1、まず関連する知識点を見てみましょう
1)RECT structure [MSDN]
The RECT structure defines the coordinates(座標)of the upper-left(左上隅)and lower-right(右下角)corners of a rectangle.   
typedef struct tagRECT { 
   LONG left;     //Specifies the x-coordinate of the upper-left corner of a rectangle. x 
   LONG top;    //Specifies the y-coordinate of the upper-left corner of a rectangle.  y 
   LONG right;   //Specifies the x-coordinate of the lower-right corner of a rectangle.  x 
   LONG bottom;  //Specifies the y-coordinate of the lower-right corner of a rectangle.  y 
} RECT;
2)RECT CRect
   CRect Similar to a Windows RECT structure.  
   class CRect : public tagRECT
   This class is derived from the tagRECT structure. (The name tagRECT is a less-commonly-used name for the RECT 
structure.) This means that the data members (left, top, right, and bottom) of the RECT structure are accessible 
data members of CRect. CRect RECT , RECT 。
3) (rectangle) (ellipse)
    
    , 。 。 , 。

4)ベースクラスのポインタは派生クラスオブジェクトを指しているが,虚関数の場合を除き,派生クラスのメンバ関数にアクセスできない.逆に派生クラスのポインタは、ベースクラスのメンバーにアクセスできます.
次の例を例にとります.
RECT*rectを定義すると、rect=new CRect(cp,cp)、すなわちベースクラスのポインタが派生クラスオブジェクトを指すためです.一方ondraw関数ではwidth()とheight()はクラスCRectの関数であり、rectはwidth()とheight()にアクセスできません.そこでここでは派生クラスのポインタCRect*rect
 
5)CWnd::Invalidate 
この関数の役割は、ウィンドウの顧客領域全体を無効にすることです.ウィンドウのクライアント領域が無効なのは、再描画が必要であることを意味し、wm_を送信することによってpaintメッセージはondraw関数を呼び出して再描画を実現します.
CWnd::Invalidate()とCWnd::UpdateWindow()です.
両者についての議論:http://topic.csdn.net/t/20020719/14/886666.html.簡単に言えば、invalidateは顧客領域をすぐに無効にしてondraw関数を呼び出しますが、undatewindownはすぐに顧客領域を無効にしてondraw関数を呼び出しません.それは、顧客領域が無効であることを発見したときにondraw関数を呼び出します.例えば、ウィンドウから上書きする別の場合です.
 
2,本例の機能はviewに楕円を描くことである.マウスでアニメーションからドラッグすると、楕円を描くたびに以前に描いた楕円が削除されます.
一.まず、DrawEllipseという単一ドキュメントプログラムを作成します.
二.次に、CDrawEllipseViewクラスにメンバー変数を追加します.
public:
RECT *rect;//正しいのはCRect*rect;もちろん直接CRect rectも可能ですが、コンストラクション関数で初期化する必要はありません.BOOL m_flag;
三.CDrawEllipseViewクラスコンストラクタに初期化コードを追加します.
CDrawEllipseView::CDrawEllipseView(){   //TODO: add construction code here     CPoint cp(0,0);     rect=new CRect(cp,cp);       m_flag=false;}
四.メッセージ・マッピング・コードの追加
 ON_WM_MOUSEMOVE:
void CDrawEllipseView::OnMouseMove(UINT nFlags, CPoint point) { //TODO: Add your message handler code here and/or call default if(m_flag) {  rect.right=point.x;  rect.bottom=point.y;  Invalidate(); } CView::OnMouseMove(nFlags, point);}
 ON_WM_LBUTTONDOWN:
void CDrawEllipseView::OnLButtonDown(UINT nFlags, CPoint point) { //TODO: Add your message handler code here and/or call default  CView::OnLButtonDown(nFlags, point); m_flag=true; rect.left=point.x; rect.top=point.y;}
 ON_WM_LBUTTONUP:
void CDrawEllipseView::OnLButtonUp(UINT nFlags, CPoint point) { //TODO: Add your message handler code here and/or call default m_flag=false; CView::OnLButtonUp(nFlags, point);}
五.OnDrawを書き換える
void CDrawEllipseView::OnDraw(CDC* pDC){ CDrawEllipseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);    if(rect.Width()>10 && rect.Height()>10) {  CPen penA(PS_DOT,1,RGB(255,0,0));  CPen * pOldPen=NULL;  pOldPen=pDC->SelectObject(&penA);
  pDC->SelectStockObject(NULL_BRUSH);  pDC->Ellipse(rect);  pDC->SelectObject(pOldPen); }
 //TODO: add draw code for native data here}