43章 グラフィックス・デバイス・インターフェース(GDI)入門(その7)

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis"></meta>
<title>43章 グラフィックス・デバイス・インターフェース(GDI)入門(その7)
</title>
</head>

<body bgcolor="WHITE">
<font size="5">43章 グラフィックス・デバイス・インターフェース(GDI)入門(その7)
</font>
<hr>
<p align="CENTER">
<a href="chap43a.lzh">根源版ダウンロード</a>・<a href="chap43b.lzh">簡易版ダウンロード</a>
<p>
 お久しぶりです。久々の本編更新です。今回のテーマは、ブラシ。<b><u><i>ブラシと言うのは、矩形や楕円で中を塗り潰す時に使う模様です</i></u></b>。
<p>
 本来、全てを説明したかったのですが、筆者の能力不足で、よく使う機能のみに限定して説明します。より高度な事は、他のサイトや書籍に譲る事にします。
<p>
 今まで見てきたようにAPIには、根源的な物と、よく使う機能をより使いやすくした物があります。最初は根源的な方法で描画し、次は、簡易的な方法で描画してみましょう。
<hr>
<p>
<b>・根源的な方法</b>
<p>
<table border="1" bgcolor="#F0F0F0">
<caption align="BOTTOM">リスト43-1
<tr><td>
<pre>
/* C言語で始めるWindowsプログラミング */
/* 43章のサンプルプログラム */
/* Programmed by Y.Kondo */
/* 注:TABサイズは4で見てください */
/* このファイルでは、メインウインドウのウインド*/
/*ウプロシージャが定義されている */

#define STRICT
#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;
#include "wndproc.h"
#include "resource.h"

/*===============================================================================*/

/* このファイル内でのみ用いられる関数のプロトタイプ宣言 */
static LRESULT Wm_CreateProc(HWND,CREATESTRUCT*);
static LRESULT Wm_DestroyProc(void);
static LRESULT Wm_PaintProc(HWND);

/* このファイル内でのみ用いられる変数宣言 */
HBITMAP hB; /* ビットマップのハンドル */
HBRUSH R1,R2,R3,R4,R5,R6; /* 作成するブラシのハンドル */

/* メインウインドウのウインドウプロシージャ */
LRESULT CALLBACK WindowProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
{
  switch(message)
   {
       case    WM_CREATE:              /*  ウインドウ初期化処理    */
           return  Wm_CreateProc(hwnd,(CREATESTRUCT*)lparam);
       case    WM_PAINT:               /*  再描画処理              */
           return  Wm_PaintProc(hwnd);
       case    WM_DESTROY:             /*  ウインドウの破壊後処理  */
           return  Wm_DestroyProc();
   }
   return  DefWindowProc(hwnd,message,wparam,lparam);
}

/*===============================================================================*/

static LRESULT Wm_CreateProc(HWND hwnd,CREATESTRUCT *cs)
{
  LOGBRUSH    lBr;    /*  論理ブラシ構造体    */
   
   lBr.lbStyle=BS_SOLID;           /*純色のブラシ  */
   lBr.lbColor=RGB(255,0,0);       /*赤で塗る      */
   lBr.lbHatch=0L;                 /*意味無し      */
   <b>R1=CreateBrushIndirect(&lBr;);   /*ブラシを作る  */</b>

  lBr.lbStyle=BS_HOLLOW;          /*中空のブラシ  */
   lBr.lbColor=RGB(0,0,0);         /*意味無し      */
   lBr.lbHatch=0L;                 /*意味無し      */
   <b>R2=CreateBrushIndirect(&lBr;);   /*ブラシを作る  */</b>

  lBr.lbStyle=BS_HATCHED ;        /*ハッチ ブラシ */
   lBr.lbColor=RGB(0,255,0);       /*緑で塗る      */
   lBr.lbHatch=HS_DIAGCROSS;       /*45 度の格子状のハッチ*/
   <b>R3=CreateBrushIndirect(&lBr;);   /*ブラシを作る  */</b>

  lBr.lbStyle=BS_HATCHED ;        /*ハッチ ブラシ */
   lBr.lbColor=RGB(0,0,255);       /*青色で塗る    */
   lBr.lbHatch=HS_HORIZONTAL ;     /*水平のハッチ  */
   <b>R4=CreateBrushIndirect(&lBr;);   /*ブラシを作る  */</b>

  hB=LoadBitmap(cs-&gt;hInstance,MAKEINTRESOURCE(IDB_BITMAP1));
   lBr.lbStyle=BS_PATTERN;         /*メモリ ビットマップで定義されるパターン ブラシ*/
   lBr.lbColor=RGB(0,0,0);         /*意味無し  */
   lBr.lbHatch=(long)hB ;          /*ビットマップのハンドル*/
   <b>R5=CreateBrushIndirect(&lBr;);   /*ブラシを作る  */</b>

  return  0;
}

static LRESULT Wm_PaintProc(HWND hwnd)
{
  PAINTSTRUCT ps;
   HDC         PaintDC;

  if(GetUpdateRect(hwnd,NULL,TRUE))
   {
       PaintDC=BeginPaint(hwnd,&ps;);   /*  ウインドウ描画用のデバイスコンテキスト取得  */

      SelectObject(PaintDC,R1);       /*  ブラシR1を選択  */
       Rectangle(PaintDC,10,10,300,50);

      SelectObject(PaintDC,R2);       /*  ブラシR2を選択  */
       Rectangle(PaintDC,30,40,320,100);

      SelectObject(PaintDC,R3);       /*  ブラシR3を選択  */
       Rectangle(PaintDC,10,110,300,150);

      SelectObject(PaintDC,R4);       /*  ブラシR4を選択  */
       Rectangle(PaintDC,10,160,300,200);

      SelectObject(PaintDC,R5);       /*  ブラシR4を選択  */
       Rectangle(PaintDC,10,210,300,250);
       
       /*  ブラシを元の状態に戻す  */
       SelectObject(PaintDC,GetStockObject(WHITE_BRUSH));  
       EndPaint(hwnd,&ps;);             /*  ウインドウ描画用のデバイスコンテキスト開放  */
   }
   return  0;
}

static LRESULT Wm_DestroyProc(void)
{
  /*  ブラシとビットマップを破棄する  */
   DeleteObject(R1);
   DeleteObject(R2);
   DeleteObject(R3);
   DeleteObject(R4);
   DeleteObject(R5);
   DeleteObject(hB);
   PostQuitMessage(0);
   return  0;
}
</pre>
</table>
<p>
 特徴は、全て、<b>CreateBrushIndirect関数</b>でブラシを作成している事です。どのようなブラシかは、コメントでわかるでしょう。
<p>
 これと同じ物を簡易的な方法を使ってやってみたのが、リスト43ー2です。
<p>
<b>・簡易的な方法</b>
<p>
<table border="1" bgcolor="#F0F0F0">
<caption align="BOTTOM">リスト43-2
<tr><td>
<pre>
/* C言語で始めるWindowsプログラミング */
/* 43章のサンプルプログラム */
/* Programmed by Y.Kondo */
/* 注:TABサイズは4で見てください */
/* このファイルでは、メインウインドウのウインド*/
/*ウプロシージャが定義されている */

#define STRICT
#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;
#include "wndproc.h"
#include "resource.h"

/*===============================================================================*/

/* このファイル内でのみ用いられる関数のプロトタイプ宣言 */
static LRESULT Wm_CreateProc(HWND,CREATESTRUCT*);
static LRESULT Wm_DestroyProc(void);
static LRESULT Wm_PaintProc(HWND);

/* このファイル内でのみ用いられる変数宣言 */
HBITMAP hB; /* ビットマップのハンドル */
HBRUSH R1,R2,R3,R4,R5; /* 作成するブラシのハンドル */

/* メインウインドウのウインドウプロシージャ */
LRESULT CALLBACK WindowProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
{
  switch(message)
   {
       case    WM_CREATE:              /*  ウインドウ初期化処理    */
           return  Wm_CreateProc(hwnd,(CREATESTRUCT*)lparam);
       case    WM_PAINT:               /*  再描画処理              */
           return  Wm_PaintProc(hwnd);
       case    WM_DESTROY:             /*  ウインドウの破壊後処理  */
           return  Wm_DestroyProc();
   }
   return  DefWindowProc(hwnd,message,wparam,lparam);
}

/*===============================================================================*/

static LRESULT Wm_CreateProc(HWND hwnd,CREATESTRUCT *cs)
{
  LOGBRUSH    lBr;    /*  論理ブラシ構造体    */
   
   /*  純色のブラシ:赤で塗る  */
   <b>R1=CreateSolidBrush(RGB(255,0,0));</b>

  lBr.lbStyle=BS_HOLLOW;          /*中空のブラシ  */
   lBr.lbColor=RGB(0,0,0);         /*意味無し      */
   lBr.lbHatch=0L;                 /*意味無し      */
   R2=CreateBrushIndirect(&lBr;);   /*ブラシを作る  */

  /*45 度の格子状のハッチ、緑で塗る*/
   <b>R3=CreateHatchBrush(HS_DIAGCROSS,RGB(0,255,0));</b>

  /*水平のハッチ、緑色で青色で塗る*/
   <b>R4=CreateHatchBrush(HS_HORIZONTAL ,RGB(0,0,255));</b>

  hB=LoadBitmap(cs-&gt;hInstance,MAKEINTRESOURCE(IDB_BITMAP1));
   /*メモリ ビットマップで定義されるパターン ブラシ*/
   <b>R5=CreatePatternBrush(hB)</b>;

  return  0;
}

static LRESULT Wm_PaintProc(HWND hwnd)
{
  PAINTSTRUCT ps;
   HDC         PaintDC;

  if(GetUpdateRect(hwnd,NULL,TRUE))
   {
       PaintDC=BeginPaint(hwnd,&ps;);   /*  ウインドウ描画用のデバイスコンテキスト取得  */

      SelectObject(PaintDC,R1);       /*  ブラシR1を選択  */
       Rectangle(PaintDC,10,10,300,50);

      SelectObject(PaintDC,R2);       /*  ブラシR2を選択  */
       Rectangle(PaintDC,30,40,320,100);

      SelectObject(PaintDC,R3);       /*  ブラシR3を選択  */
       Rectangle(PaintDC,10,110,300,150);

      SelectObject(PaintDC,R4);       /*  ブラシR4を選択  */
       Rectangle(PaintDC,10,160,300,200);

      SelectObject(PaintDC,R5);       /*  ブラシR4を選択  */
       Rectangle(PaintDC,10,210,300,250);
       
       /*  ブラシを元の状態に戻す  */
       SelectObject(PaintDC,GetStockObject(WHITE_BRUSH));  
       EndPaint(hwnd,&ps;);             /*  ウインドウ描画用のデバイスコンテキスト開放  */
   }
   return  0;
}

static LRESULT Wm_DestroyProc(void)
{
  /*  ブラシとビットマップを破棄する  */
   DeleteObject(R1);
   DeleteObject(R2);
   DeleteObject(R3);
   DeleteObject(R4);
   DeleteObject(R5);
   DeleteObject(hB);
   PostQuitMessage(0);
   return  0;
}
</pre>
</table>
<p>
 同じ事をするにしても、簡潔になったし、判読性が向上したと感じたのではないでしょうか?
<p>
<b>・CreateSolidBrush関数</b>
<p>
 べた塗りのブラシを作成します。
<p>
<b>・CreateHatcBrush関数</b>
<p>
 ハッチブラシを作成します。
<p>
<b>・CreatePatternBrush関数</b>
<p>
メモリ ビットマップで定義されるパターンブラシを作成します
<p><b>・ブラシの廃棄</b>
<p>
 ペン同様、選択されているオブジェクトは廃棄できません。それゆえ、ストックオブジェクトを使って、作成したブラシを選択状態から開放して廃棄します。また、ビットマップから作成したブラシは、ブラシを廃棄してからビットマップを廃棄する必要があります。
<hr>
<p>
 簡単ですが、GDIによる描画オブジェクトはこの辺までにして、次回はGUI独自の座標系の説明をしたいと思います。
<hr>
<p align="RIGHT">
<a href="/web/20150829012821/http://web.kyoto-inet.or.jp:80/people/ysskondo/index.html">目次</a><br>
<hr>
<p align="RIGHT">
著作権者:近藤妥
</body>
</html>

  • 最終更新:2018-03-11 05:35:10

このWIKIを編集するにはパスワード入力が必要です

認証パスワード