トップ 戻るプログラミングの宝箱 アルゴリズムとデータ構造

デバイスコンテキストのマッピングモード

ウインドウなどに描画を行うデバイスコンテキストのマッピングモード(座標系)は、デフォルトでは描画時に指定する論理ピクセルと実際に描画される物理ピクセルが1:1で対応し、Xは右に行くほど、Yは下に行くほど増えるようになっています。つまり、(0,0)から100×100の正方形を描くとその正方形はデバイスコンテキストの(0,0)の位置から右に100ピクセル、下に100ピクセルの大きさで描かれるわけです。ここでは、100×100という「論理単位」で指定した大きさがそのまま画面上のピクセルという「物理単位」になっていますね。
Windowsでは、このデバイスコンテキストのマッピングモードをSetMapMode()で変更することが出来ます。マッピングモードを変更すると、例えば「100mm×100mmの正方形を描く」といった事が出来る(この場合は、デバイス上で100mmに対応するピクセル分の正方形になる)ので、特に印刷の時に役立つでしょう。
今回は、256×256論理単位の正方形を描いてみて、それがデバイスコンテキストの各マッピングモードでどのように表示されるか見てみることにします。

主なマッピングモード

今回取り上げるマッピングモードは、以下のとおりです。

マッピングモードの例
マッピングモード1論理単位座標方向
MM_TEXT1物理単位(デバイスの1ピクセル)右下
MM_LOENGLISH0.01インチ右上
MM_HIENGLISH0.001インチ右上
MM_LOMETRIC0.1mm右上
MM_HIENGLISH0.01mm右上
MM_TWIPS1/1440インチ右上

*他にも、MM_ISOTROPICMM_ANISOTROPICというマッピングモードもあるのですが、今回は扱いません。

各マッピングモードで100論理単位の線を描くと、MM_TEXTでは表示デバイスの100ピクセルで、MM_LOENGLISHでは1インチで、MM_HIENGLISHでは0.1インチで表示されることになります。また、座標系の方向はMM_TEXT以外は上に行くほどYが増えるのでDIB(そして、数学のグラフ)と同じですね。
ただし、座標の原点(0,0)はデフォルトでは物理座標の(0,0)、つまりクライアント領域の左上端にあるのでMM_TEXT以外で描画する場合は注意が必要です。このままでは、Yに正の値を指定するとそれは「左上端の原点の上」に描かれるので表示されません。マイナスの値を指定すれば表示されますが、それよりも座標系の「原点」を移動した方が良いでしょう。
原点を移動するには、SetViewportOrgEx()に原点とする座標を物理単位で指定します。例えば、クライアント領域のデバイスコンテキストhdcに対して

  SetViewportOrgEx(hdc, 0, 256, NULL);

とすると、原点がクライアント領域の(0,256)に設定されます。

マッピングモード設定と描画

では、実際にデバイスコンテキストの座標系を各マッピングモードに切り替えて描画結果を見てみることにしましょう。今回は、ウインドウプロシージャのWM_PAINTでマッピングモードを変更し、原点を(0,256)にします。マッピングモードは定数で与えますが、今回のプログラムではその定数を変数dwMMで指定することにしました。

続いて、256論理単位四方の正方形を描いてその中に三角形を描きます。

ウインドウプロシージャー内WM_PAINT
case WM_PAINT:

	hdc = BeginPaint(hwnd, &ps);

	/* 描画用ペンとブラシ選択 */
	SelectObject(hdc, GetStockObject(BLACK_PEN));
	SelectObject(hdc, GetStockObject(WHITE_BRUSH));

	/* デバイスコンテキストのマッピングモード設定 */
	SetMapMode(hdc, dwMM);

	/* 原点設定 */
	SetViewportOrgEx(hdc, 0, 256, NULL);

	/* 原点から255 * 255単位の長方形を描画 */
	Rectangle(hdc, 0, 0, 255, 255);

	/* 底辺と対面する辺の中点で三角形を描く */
	MoveToEx(hdc, 0, 0, NULL);
	LineTo(hdc, 128, 255);
	LineTo(hdc, 255, 0);

	EndPaint(hwnd, &ps);

	return 0;

これで、変数dwMMでマッピングモードを指定してウインドウを再描画すれば、そのマッピングモードで描画できるようになりました。

プログラム

メニューでマッピングモードを変更できるようにしたので、実行したらマッピングモードメニューでマッピングモードを変更してみてください。各マッピングモードで、正方形の大きさや位置そして正方形内の三角形の方向などを確認したら、画面の解像度を変えて正方形の大きさがどうなるか見てみましょう。

プログラムソース表示 プログラムダウンロード


トップ 戻る