第7章 ペン


今回は、線の描画をします。MoveToとLineTo関数を知っていればOKです。

CDC::MoveTo CPoint MoveTo( int x, int y ); CPoint MoveTo( POINT point );

引数は座標を直接入れてもよいし、POINT構造体で入れてもよいことがわかります。

CDC::MoveTo CPoint MoveTo( int x, int y ); CPoint MoveTo( POINT point );

これも、MoveToと同じく直接座標を入れるか、POINT構造体を入れます。 また、どちらの関数もCPointオブジェクトを引数にして問題ありません。 戻り値は直前のx,y座標をCPointオブジェクトで返します。

これで、直線を描画できるようになりました。 ところで線の色を変えたり、太さを変えるにはペンを作る必要があります。 MFCでは、CPenクラスのオブジェクトでペンを表現します。 これには、すくなくとも3つの方法があります。好みの方法で行ってください。

1.CPen myPen(PS_SOLID, ....) という感じで作る方法 2.CPen myPen; myPen.CreatePen(PS_SOLID,...); 後から、CreatePenを呼ぶ方法 3.CreatePenIndirectを使う方法

ペンは使い終わったら削除するのが原則ですが、 CPenオブジェクトがスコープ外に出ると自動的に削除されるので 自分で削除する必要はありません。

ペンを作ってもデバイスコンテキストにSelectされていないと 描画に反映されません。

CDC::SelectObject CPen* SelectObject( CPen* pPen ); CBrush* SelectObject( CBrush* pBrush ); virtual CFont* SelectObject( CFont* pFont ); CBitmap* SelectObject( CBitmap* pBitmap ); int SelectObject( CRgn* pRgn );

SelectObjectによってペンなどのデバイスコンテキスト・ オブジェクトを選択します。 また、戻り値は直前まで選択されていたデバイスコンテキスト・ オブジェクトのポインタとなります。(CRgnは例外)

具体的には次のような感じで使います。

void CMyWindow::OnPaint() { CPaintDC dc(this); CPen myPen, *pOldPen; myPen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0)); pOldPen = dc.SelectObject(&myPen); dc.MoveTo(0, 0); dc.LineTo(100, 100); dc.SelectObject(pOldPen);//ペンを元に戻す }

または、次のような書き方もできます。

void CMyWindow::OnPaint() { CPaintDC dc(this); CPen myPen(PS_SOLID, 1, RGB(255, 0, 0)), *pOldPen; pOldPen = dc.SelectObject(&myPen); dc.MoveTo(0, 0); dc.LineTo(100, 100); dc.SelectObject(pOldPen);//ペンを元に戻す }

さらに、次のような書き方もできます。

void CMyWindow::OnPaint() { CPaintDC dc(this); CPen myPen, *pOldPen; LOGPEN lp; lp.lopnStyle = PS_SOLID; lp.lopnWidth = 1; lp.lopnColor = RGB(255, 0, 0); myPen.CreatePenIndirect(&lp); pOldPen = dc.SelectObject(&myPen); dc.MoveTo(0, 0); dc.LineTo(100, 100); dc.SelectObject(pOldPen);//ペンを元に戻す }

今回のサンプルプログラムです。ウィンドウの大きさを変えても 文字は中央にあります。対角線もウィンドウの大きさに応じて 変化します。

// grph01.h class CMyApp : public CWinApp { public: virtual BOOL InitInstance(); }; class CMyWindow : public CFrameWnd { public: CMyWindow(); protected: afx_msg void OnPaint(); DECLARE_MESSAGE_MAP() };

前回とほぼ同じですが、OnPaint()以下をprotectedにしてみました。

// grph01.cpp #include <afxwin.h> #include "grph01.h" CMyApp MyApp; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWindow; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } BEGIN_MESSAGE_MAP(CMyWindow, CFrameWnd) ON_WM_PAINT() END_MESSAGE_MAP() CMyWindow::CMyWindow() { Create(NULL, "猫でもわかるグラフィックス"); } void CMyWindow::OnPaint() { CPaintDC dc(this); CPen myRedPen, myBluePen, *pOldPen; CRect rc; GetClientRect(&rc); dc.DrawText("猫でもわかるグラフィックス", -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER); myRedPen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0)); pOldPen = dc.SelectObject(&myRedPen); dc.MoveTo(rc.left, rc.top); dc.LineTo(rc.right, rc.bottom); dc.MoveTo(rc.right, rc.top); dc.LineTo(rc.left, rc.bottom); myBluePen.CreatePen(PS_SOLID, 5, RGB(0, 255, 255)); dc.SelectObject(&myBluePen); dc.MoveTo(rc.left, rc.top); dc.LineTo(rc.right, rc.top); dc.LineTo(rc.right, rc.bottom); dc.LineTo(rc.left, rc.bottom); dc.LineTo(rc.left, rc.top); dc.SelectObject(pOldPen); dc.MoveTo(0, (rc.bottom - rc.top)/2); dc.LineTo(rc.right, (rc.bottom-rc.top)/2); }

あまり、説明はいらないと思いますが、DrawTextは次のようになっています。

CDC::DrawText virtual int DrawText( LPCTSTR lpszString, int nCount, LPRECT lpRect, UINT nFormat ); int DrawText( const CString& str, LPRECT lpRect, UINT nFormat );

nCountは文字列のバイト数ですが−1にすると自動的に計算してくれます。

lpRectはテキストがフォーマットされる四角形のRECT構造体(またはCRectオブジェクト) へのポインタです。

uFormatはフォーマットの方法を指定します。
DT_BOTTOMはテキストを四角形の底に揃えます。(DT_SINGLELINEとの組み合わせ必要)
DT_CENTERはテキストを水平方向の中央に揃えます。
DT_VCENTERはテキストを垂直方向の中央に揃えます。(1行の時のみ)


[MFC Index] [総合Index] [Previous Chapter] [Next Chapter]

Update 27/Mar/1998 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。