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}