14章 補講(その1)

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis"></meta>
<title>14章 補講(その1)</title>
</head>

<body bgcolor="WHITE">
<p>
<font size="5">14章 補講(その1)</font>
<hr>
<p>
 今回は補講という事で、1章から13章の間で説明出来なかった事について簡単にまとめてみました。
<p>
<b>・立体的なウインドウの表示</b>
<p>
 今まで、引数の数が少ない方が良いのでは?という配慮から、平面的なウインドウで学習を進めてきました。しかし、Windows95のメモ帳の様に枠が盛り上がった立体的なウインドウにしたい時があります。
<p>
 つまり、 <img src="/web/20160505174337im_/http://web.kyoto-inet.or.jp:80/people/ysskondo/img14a.gif"> を <img src="/web/20160505174337im_/http://web.kyoto-inet.or.jp:80/people/ysskondo/img14b.gif"> にしたい訳ですね。
<p>
 これは、以下のように<b><i><u>CreateWindowEx関数</u></i></b>を使えば簡単に出来ます。最初の引数は拡張スタイルで、 WS_EX_OVERLAPPEDWINDOWを指定するだけです。マニュアルには多くのフラグが載っていますので、色々試してみてはどうでしょうか。
<p align="CENTER">
<table border="1" bgcolor="#F0F0F0">
<tr><td>
<pre>
hwnd=CreateWindowEx(WS_EX_OVERLAPPEDWINDOW ,/*拡張スタイル*/
                  "MainWindowClass"
                   "立体的なウインドウ枠",
                   WS_OVERLAPPEDWINDOW,
                   CW_USEDEFAULT,
                   CW_USEDEFAULT,
                   CW_USEDEFAULT,
                   CW_USEDEFAULT,
                   NULL,
                   (HMENU)NULL,
                   hInstance,
                   0);
</pre>
</table>
<p>
<b>・座標系のまとめ</b>
<p>
 普通、座標系で意識なければいけないのは2つです。つまり、スクリーン座標系とクライアント座標系です。
<p>
 図示すると以下のようです。<br>
<p>
 どちらの座標系も、水平方向は右側が正で、垂直方向は下側が正です。
<p>
 それゆえ、スクリーン座標系では、640ピクセル×480ピクセルの画面の場合、右下隅の座標は(639、479)です。また、この座標系は、オーバーラップウインドウやポップアップウインドウの位置を指定したり取得したりするのに用いられます。
<p>
 クライアント座標系は、クライアント領域での座標系で、この中に置かれる子ウインウ(コントロール)の位置を指定したり取得したりするのに用いられます。
<p>
<b>・WNDCLASS構造体のcbWndExtraメンバ変数の使い方</b>
<p>
 13章のカウンターコントロールは変数が2つだけの単純なコントロールでした。それゆえ、cbWndExtraメンバ変数に8を指定して、その度に、GetWindowLong関数やSetWindowLong関数を用いてアクセスしていました。
<p>
 もし、この方法を採ると変数名でなく変位でもってメモリーにアクセスする事になり、変数の数が増えると極めてプログラムの判読性が劣ります。また、複雑な型に対応できません。
<p>
 そこで、普通は、構造体を定義し、WM_CREATEメッセージに応答する時にmalloc関数でメモリを確保して、そのポインタをウインドウ毎のメモリ領域に代入します。取得したメモリを利用する時は、GetWindowsLong関数でメモリに対するアドレスを取得、定義した構造体型へのポインタにキャストしてアクセス。最後に、WM_DESTROYメッセージに応答して、取得したメモリ領域をfree関数で開放します。恐らく、これが最もオーソドックスな方法と思います。以下に、具体的な例を挙げます。
<p align="CENTER">
<table border="1" bgcolor="#F0F0F0">
<tr><td>
<pre>
/* ウインドウ毎に実際に確保される変数をまとめるための構造体 */
typedef struct {
  int     a;
   char    b[100];
   long    c[10];
} TData;

/* for WM_CREATE message */
static LRESULT Wm_CreateProc(HWND hwnd,LPCREATESTRUCT cs)
{
  TData   *p;
   p=malloc(sizeof(TData));
   if(p==NULL)
       return  -1;
   SetWindowLong(hwnd,0,(LONG)p);  /*  ウインドウ毎のメモリにはアドレスを書き込む  */
   ZeroMemory(p,sizeof(TData));    /*  0に初期化(代入です)  */
   return  0;
}

/* for WM_DESTROY message */
static LRESULT Wm_DestroyProc(HWND hwnd)
{
  TData   *p;
   p=(TData*)GetWindowLong(hwnd,0);
   free(p);
   return  0;
}
</pre>
</table>

<hr>
<p>
 最後の項目ですが、実際にサンプルプログラムを提示するのが分かりやすいと思います。次回は補講(その2)と題して、5章で作成したお絵描きプログラムをコントロール化し、その中で説明しようと思います。
<p>
 では、お楽しみに。
<p align="RIGHT">
1999年11月11日<br>
加筆修正1999年11月12日<br>
加筆修正1999年11月21日<br>
<hr>
<p align="RIGHT">
<a href="index.html">目次</a><br>
<a href="chap15.html">次へ</a>
<hr>
<p align="RIGHT">
著作権者:近藤妥

</body>
</html>

  • 最終更新:2018-03-11 04:43:17

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

認証パスワード