「Windows API/図形の描画」の版間の差分

{{Nav}},s/命令/関数/
({{Nav}},s/命令/関数/)
 
{{Nav}}
== 塗りつぶし ==
=== 長方形を塗りつぶすには? ===
図形を塗りつぶしたい場合には、図形描画命令関数の直前に、下記のように描画のモードをブラシに設定します。
 
塗りつぶし専用の命令関数は、無いのです。
 
Windows API でいう「ブラシ」とは、図形の塗りつぶしの色を設定するためのツールのことです。画像作成ソフトで例えるなら、Windows API でいうブラシとは、画像作成ソフトの「バケツ」ツールに近いです。世間一般の画材でいう「ブラシ」とは、意味が違います。
上記の2段階のブラシ作成の作業は、CreateSolidBrush はブラシの色作成のためのアドレス確保を意味し、もう片方 SelectObject は、どのウィンドウでどのブラシ色を使うかを定義するための情報を保存するアドレスの確保を意味しています。
 
「Rectangle」は、単に、四角形を描くための命令関数です。これが塗りつぶしか、それとも輪郭線だけをペンで描くのかは、このRectangle命令関数だけでは指定できず、この命令関数が来る前の設定に依存します。
 
 
当然、これらの命令関数は、WM_PAINT ケースにある
「// TODO: HDC を使用する描画コードをここに追加してください...」
のあるブロックで書く必要があります。
図形をピンク色の長方形だけにしたい場合、ペンの色もピンク色にします。
 
Rectangle 命令関数の前に、あらかじめ
<syntaxhighlight lang=c>
HPEN pen_buhin_1;
SelectObject(hdc, pen_buhin_1);
</syntaxhighlight>
のように、ペンを指定します。 CreatePen 命令関数の第2引数の「0」は、ペン幅の追加の線幅です。「0」に指定しても、最低でも1ドットぶんの線幅はあります。
 
よって、今までの話をまとめると、
 
 
=== 典型的な画像描画の命令関数の手順 ===
 
上記のプログラムにあるような手順の、
Create〇〇
SelectObject
実際の描画命令関数
 
といった順序は、長方形以外のほかの図形の描画などでも同様の手順になります。特別な理由の無いかぎり、この順序で命令関数を宣言することになるでしょう。
 
=== polygon関数とPOINT配列 ===
Win32 API では、polygon() という命令関数で、任意の多角形を塗りつぶしできる。ただし、長方形と正方形については、これらの四角形を書ける Rectangle という命令関数でも塗りつぶしできます。
 
 
さて、Polygon関数について説明する。
 
polygon命令関数の使用のさい、その多角形の頂点それぞれの座標位置の格納のために事前に POINT 配列という専用の配列を宣言します。
 
また、ブラシなどの設定や関連づけもする必要があります。
 
=== 任意の図形の塗りつぶし ===
ExtFloodFill 命令関数で、たとえるならペイントソフトのバケツ塗りのような、線などで囲まれた領域の塗りつぶしをできる。詳しくは外部サイトを参照せよ。
 
== その他の描画 ==
べつに塗りつぶしをせずに、単に線を描くだけの機能も存在している。
 
直線を描くだけなら、 MoveToEx() 命令関数と LineTo() 命令関数で描ける。
 
なお、 MoveToEx() で起点を指定しており、引数で起点を指定する。LineTo() 命令関数では終点を指定しており、引数で終点を指定すり。
 
 
そのほか、円や楕円を塗りつぶしで描くなら Ellipse() 命令関数で書ける。
 
また、この円・楕円の引数では、その円を内接円とする長方形を指定する方式で、その長方形の左上の座標と右下の座標を指定する。
 
このため、ナナメに傾いた楕円は書けない。(後述する SetPixel()など別の命令関数に頼ることになるだろう。)
 
 
そのほか、円弧および楕円弧を塗りつぶさずに弧だけ描くなら Arc() 命令関数で書ける。
 
そのほか、円弧および楕円を塗りつぶして描くなら Pie() 命令関数で書ける。
 
これら Arc() や Pie() もまた、内接円を囲む長方形を引数として指定する方式で、その長方形の左上の座標と右下の座標を指定する。
 
=== 点を打つ ===
また、点を打つだけの命令関数もあり、それは SetPixel() 命令関数である。
 
原理的には、パソコン画面に表示されるどんな画像もピクセル単位の点の集まりにすぎないので、原理的には SetPixel だけで、どんな画像も書ける。
 
 
だが、もちろん実用では、上述に紹介したように、線を描くなら線を引くための専用の命令関数があるし、塗りつぶしをしたいなら専用の命令関数があるので、そういう専用の命令関数を使うことで、プログラマーの作業を簡略化するのが常識的である。
 
ちなみに、1文字ちがいの GetPixel() 命令関数は、これは指定した座標の色を取得する命令関数である。
 
 
もし、図形が飛び飛びになってしまうと、グラフに沿って塗りつぶしをしたい場合、飛び飛びだと塗りつぶしの境界枠にできない。
 
なので、用途によっては SetPixel ではなく、近似的に LineTo 命令関数などを使って描画する例も、ネット上では、よく見かける。
 
得られる図形の大まかな形状があらかじめ分かっているなら、LineTo() 命令関数などで描画するのがよいだろう。
 
=== 画面クリアの専用の命令関数は無い ===
Windows32API には、画面を初期状態に戻すようなクリア機能の専用の関数は、無いようです。(※ 参考文献:林晴彦『明快入門 visual C++ 2010』、ソフトバンククリエイティブ(出版社)、2011年3月8日 初版 第1刷、179ページ。 )
 
もし .NET Framework ならば SaveImage メソッドというのがある。しかし Win32API には、そういうのは無い。
 
Win32APIでも、画面の画像をキャプチャしてメモリなどに蓄える命令関数( GetShellWindow 命令関数 )はあるが、しかし、そうやって蓄えた画像情報を外部ファイルに出力して書き込む専用の命令関数は無い。
 
なので、C言語のバイナリ書き込み命令関数などを利用して、自分でビットマップ形式ファイルへの画像エンコーダーを自作することになる。このため、BITMAP構造体の仕様などを把握しておく必要がある。
 
 
<syntaxhighlight lang=c>
void kansuu(HDC hdc){
// ここに描画命令関数を書く
}
</syntaxhighlight>
 
ともかく、どんなプログラミング様式も一長一短です。
なので、簡単で短い単純なプログラムだけを書く場合には、似たような処理の繰り返しがあっても、あえて関数もfor文もif文も全く使わずに、逐次的に1行ずつ命令関数を書いていく場合もあります。
もちろん、この逐次的な方式も、欠点があり、コードがかなり長くなるので、長くなるにつれて記述ミスをしやすくなります。
 
2,361

回編集