はじめに
あなたがMFC(Microsoft Foundation Class)の初心者でグラフィック操作に興味があるならば、少なくとも基本的な操作方法を理解できる体系的なチュートリアルが必要でしょう。
本稿は、MFCグラフィックスに関する完璧なチュートリアルというわけにはいきませんが、とりあえず簡単なペイント操作をできるようになるために必要な最低限の情報について説明します。
デバイスコンテキスト
どのウィンドウにも、ペイント処理に使われるデバイスコンテキストというものが関連付けられています。デバイスコンテキストとは「一連のグラフィックオブジェクトとその属性を定義する役割」と「出力に影響するグラフィックモードを定義する役割」の両方を担うオブジェクトです。ここで言う「一連のグラフィックオブジェクト」には、次のものが含まれます。
- ペン
線の描画で使用 - ブラシ
ペイントと塗りつぶしで使用 - ビットマップ
画面各部のコピーやスクロールで使用 - フォント
テキストの描画で使用 - パレット
使用可能な色セットの定義で使用 - リージョン
クリッピングなどの操作で使用 - パス
ペイントや描画の操作で使用
このデバイスコンテキストは、線やシェイプを描いたり、テキストを書いたりする物理的なキャンバスだと考えられます。この「キャンバス」では、上記タイプのオブジェクトを一度に1つしか扱えません。線を描く場合にはその線にふさわしいペン(例えば赤の実線)を使用し、塗りつぶしの円を描く場合にはブラシを使用します。
このとき、円を描く前にブラシを選択しなければなりません。新しいオブジェクトが選択されるまで、前回選択されたオブジェクト(ペン、ブラシ、ビットマップ、フォントなど)がそのまま有効になります。同じタイプのオブジェクトを必要とする後続の操作では、前回選択したオブジェクトが引き続き使われます。このため、必ず次のような使い方をする必要があります。
- 現在の操作で必要なオブジェクトを選択し、それまで選択されていた古いオブジェクトを保存しておきます。
- 操作を実行します。
- 古いオブジェクトを選択し直します。
MFCにはCDC
というクラスがあります。これは、WindowsデバイスコンテキストオブジェクトへのハンドルであるHDC
をカプセル化したものです。デバイスコンテキストを使うすべての操作は、このようなCDC
オブジェクトを通じて行う必要があります。このクラスには、オブジェクトの選択、線とシェイプ(楕円、多角形、四角形)の描画、描画属性の設定、リージョンの操作、クリッピング、テキストの描画などを行う関数が用意されています。
これに加えてMFCには、CDC
から派生した、デバイスコンテキストを処理するための特殊なクラスがいろいろと用意されています。
CPaintDC
BeginPaint()
の呼び出し(コンストラクタ内)とEndPaint()
の呼び出し(デストラクタ内)を扱います。WM_PAINT
メッセージを処理してウィンドウをペイントする必要がある場合は、BeginPaint()
を呼び出してペイント用のウィンドウを準備し、ペイントに関する情報を構造体に入力しなければなりません。その後、ペイントが終了したらEndPaint()
を呼び出す必要があります。基本的に、次の操作が必要です。
void CSomeWindow::OnPaint() { PAINTSTRUCT ps; CDC* pDC = BeginPaint(&ps); // do the painting with pDC EndPaint(&ps); }
CPaintDC
を使うと、次の操作だけで済みます。
void CSomeWindow::OnPaint() { CPaintDC dc(this); // do the painting with dc }
CClientDC
コンストラクタ内でGetDC()
を呼び出し、デストラクタ内でReleaseDC()
を呼び出すことにより、ウィンドウのクライアント領域に関連付けられているデバイスコンテキストを処理します。クライアント領域内で描画するには、これらの関数を次のように呼び出す必要があります。
void CSomeWindow::DrawClient() { // acquire the device context associated with the // client area CDC* pDC = GetDC(); // draw on the client area // release the client area ReleaseDC(pDC); }
GetDC()
とReleaseDC()
は対になっており、GetDC()
を呼び出したら必ず対応するReleaseDC()
を呼び出さなければなりません。CClientDC
を使えば操作は簡単です。
void CSomeWindow::DrawClient() { CClientDC dc(this); // draw on the client area }
CWindowDC
ウィンドウ全体(フレームやコントロールを含む)に関連付けられている表示コンテキストを管理します。コンストラクタ内でGetWindowDC()
を呼び出し(ウィンドウ全体のデバイスコンテキストを取得)、デストラクタ内でReleaseDC()
を呼び出します。
CMetaFileDC
デバイスコンテキストとメタファイルを関連付けます。
なお、このチュートリアルではCPaintDC
だけを扱います。