定義 - みる会図書館


検索対象: 月刊 C MAGAZINE 1992年11月号
71件見つかりました。

1. 月刊 C MAGAZINE 1992年11月号

short int を 16 ビットて、表現するコンパイラ しなければならない いったメリットがある。 Windows プログラ しかし , すべての long を LONG と記述す て、は , BOOL は short int の同義語て、あるか ミングの世界て、は , ハンガリアン記法を使 る必要はない。プログラマが独自の目的て、 もしれない う慣習があるのて、 , 素直に従ったほうが無 利用する場合には , 必ずしも LONG を使う 難て、ある。 なお , 構造体に対しては , 構造体名を小 必要はない 文字て、表したものを前置子としたり , そっ 本プログラムては , WinProc, WinMain くりそのまま名前として用いたりする。た 関数の順て、定義を行っている。 ANSIC 規格 とえば , List 2 中の msg は , MSG 構造体型 大文字て、表されているのは , キーワード て、採用された関数プロトタイプ宣言の必要 のオプジェクトて、あり , 後者の例て、ある。 だけて、なく ,WORD や LPSTR などの新たな 性などとの関係から , このような順序て、定 大文字のキーワード 義しているのて、ある ( コラムⅢ参照 ) 。もし 型も定義されている。これらは , < window s. h> の中て、 typedef によって宣言されてい WinMain 関数をソースファイルの先頭側に る。 Table 3 に示すように , C 言語の基本的 配置するのならば , その前に WinProc 関数 List 2 のプログラムて、は , WndProc 関数 な型や , それらの型へのポインタ型に対す のプロトタイプ宣言が必要となるだろう (F の戻り型が , long て、はなく大文字の LONG ig. 2 ) 。 る同義語が定義されている。 となっている。 <windows. h> て、は , #defin これは明らかに冗長て、ある。プロトタイ e によって , Table 2 に示す大文字のキーワ near ポインタには接頭子として P が , far プ宣言の記述が欠落した場合や , 関数の仕 ポインタには接頭子として LP が付加されて ードが定義されている。たとえば , FAR は いることがわかるて、あろう。 far や far と同じ意味て、あるが , FAR を使う フ こて、 , BOOL は , 真 (TRUE) て、あるか ことが推奨される。 ASCIZ 文字列 偽 (FALSE) て、あるかを表す真理値を表現す 後述する WndProc の戻り型や引数のよう る型て、ある。 int の同義語て、あるからといっ に , Windows の規則て、 LONCJC' あることが 一般に , 文字列は可変の長さを持っため て , int を使わないように。 int を 32 ビット , 要求されるところには , 必ず LONG を使用 に 3 種々の表現方法が考案されている。た とえば , Turbo Pa al ては , 先頭バ - イトに TabIe 1 Windows プログラミングで使用する八ンガリアン記法の前置子 文字列の長さを格納し , 2 バイト目以降に文 字列の実体が格納される ( 文字列の長さを表 対応する型 前置子 現するのがレヾイトてあるため , TurboPas cal ては 256 文字以上の文字列を扱えない )0 ASCIZ 文字列は , MS-DOS のファンクシ ョンコールなどて利用されており , DOS 上 ての標準的な文字列表現方法てある。具体 的には , ASC Ⅱコード 0 の文字を終端とする ASCII 文字列のことてある。 ASCIZ の Z は 0 を意味するのてある。 0 はスル文字に相当す るのて , ASCII コードを文字体系とする環境 ては , C 言語の文字列と同じ表現形式てある といえる。 関数の配置 大文字で表される基本型 配列 BOOL ( int ) ・・・・・・論理変数 BYTE ・・・・・・ 1 バイト ・・・ 1 バイトの文字値 char•• バイト数 sho ・・・・・幅と高さを表現 DWORD(unsigned long)••・ " 32 ビット値 関数 ハンドル i nt LONG ( long ) ・・・・・・ 32 ピット整数値 fa 「ポインタ ( ロングボインタ ) 一般的な整数 short, int ・・ ポインタ DWORD ・・・・・・ピクセル座標を表現 RGB のカラーを表現 文字列 ASCIZ 文字列 WORD(unsigned)••・ " 16 ビット値 sho 虍 " " ・ x 座標と Y 座標を表現 c, ch cb CX, CY dw TabIe 2 大文字のキーワード 名前 本来のキーワード fa 「 , fa 「 near, near long VOid pascal, pascal cdecl, cdecl FA R NEAR LONG VOID PASCAL CDECL 48 C MAGAZINE 1992 11

2. 月刊 C MAGAZINE 1992年11月号

第 8 回 by St 実懿プロクラミンク 奥村晴彦 ソースファイルの分割 大きいプログラムは , いくつかのファイルに分けて書くと 便利です。今回は有効範囲の概念を復習したあと , ソースコ ードのファイルの分割 , make の使い方を勉強します。実 例として , 乱数生成と金種計算のプログラムを掲載します。 有効範囲 84 C MAGAZINE 1992 11 けてす。 5 行目て、 x に何かを代入すれば , 4 行 て , その有効範囲は , この中力ッコの中だ の定義は中力ッコ { ・・・・・・ } て、囲まれているの 義したほうが勝ちます。ただし , 4 行目の x 同じ名前の変数を定義したときは , 後て、定 たってきたことになります。このように , 定義しています。同じ x という名前の箱がふ ところが , 4 行目て、も同じ名前 x の変数を れば , この 1 行目て、作った x に入ります。 ことがあります。 18 行目て、 x に何かを代入す 域 ( たいいき ) 変数 (global variable) と呼ぶ のように , ファイル全体て、有効な変数を大 イルのこれ以降最後まて、 ( のはず ) てす。 義の影響がおよぶ範囲 ( 有効範囲 ) は , ファ いうこともあります。このような変数の定 変数は「トップレベルで定義されている」と ッコ { ・・・・・ } に囲まれていません。こういう 箱を作ったわけて、す。この x の定義は , 中力 います。整数を入れるための x という名前の 1 行目て、 , 整数 ( int ) 型の変数 x を定義して List 1 のプログラムを見てください 説明 ( 一部復習 ) します。 語の変数や関数の有効範囲 ()c 叩 e) の概念を ファイル分けについて説明する前に , C 言 0 目て、作った x に入ります。しかし , 6 行目以 降て、は 4 行目の x は消滅し , 隠れていた 1 行目 の x が再び見えるようになります。 4 行目の x のように , 有効範囲がかぎられた変数のこ とを , 局所変数 (local variable) と呼ぶこと があります。 このように , 変数は「見え隠れ」するのて、 す。 大域変数 , 局所変数 , 有効範囲の概念は , C 言語に特有なものて、はなく , 多くのプログ ラム言語に共通のものて、すから , よく理解 しておいてください List 1 の説明を続けましよう。 7 行目て、関 数 bar のパラメータ ( 仮引数 ) として x が使わ れています。このような関数のパラメータ bar(3) ; も , 局所変数の一種て、す。 じカッコ、、ドまて、て、す。 がて、きます。その有効範囲は , 対応する閉 ッコ、、 { 〃の直後て、あれば , 変数を作ること 語て、はこのように関数の途中て、も , 開きカ 12 行目て、また x が定義されています。 C 言 す。 を代入しても , 値が変わるのは 7 行目の x て、 た x の値は変わりません。 10 行目て、 x に何か 代入されるのて、すが , もちろん 1 行目て、作っ のように呼び出すと , この局所変数 x に 3 が 忙しい人が , 書類の山の上にまた書類を 積まれたとしましよう。この人は「書類 x の 内容を報告してくれ」といわれたとき , 上か ら探していって最初に見つかったものを報 告します。上のほうの書類が用済みになっ て廃棄処分になったあとて、 , もうひとっ x と いう書類があったことに気づくわけて、す。 コンパイラが変数の格納番地を検索する方 法も , これと同じて、 , 最新のものから順に 探して , 最初に見つかったものを使うのて、 す。コンパイラが閉じカッコに出会うと , 対応する開きカッコ以降に積んだ情報は捨 て去るのて、 , ひとつ前の定義が再び見える ようになります。 局所変数は , 有効範囲がかぎられ , その 変数に起因するエラーが見つけやすいのて、 , て、きるだけ局所変数を使いましよう。 ファイル分けの考え方 局所変数は有効範囲がひとつの関数 , あ るいはその一部分にかぎられます。しかし , 場合によっては , ある変数をいくつかの関 数て、共有したいこともあります。この場合 は大域変数を使うことになりますが , 大き いプログラム全体て、有効な大域変数をあま り作ると , その変数に起因するエラーが見

3. 月刊 C MAGAZINE 1992年11月号

特集 ープログラ テキストの描画 ミンク、 LiSt 4 : 3 : 2 : hello. exe 用定義ファイル He110. def He110 5 : NAME 6 : DESCRIPTION ' 日 el 10 (c) BohYoh Shibata, 1992 ' 10 : DATA Fig. Fig struct tagRECT 7 : EXETYPE 8 : STUB 9 : CODE 11 : HEAPSIZE 12 : STACKSIZE 13 : EXPORTS WINDOWS 3.0 ' WINSTUB. EXE' PRELOAD MOVABLE DI SCARDAB LE PRELOAD MOVABLE MU LTI PLE 1024 8192 WndProc 12 PAINTSTRUCT 型の定義 typedef struct tagPAlNTSTRUCT HDC BOOL RECT BOOL BOOL BYT E hdc ; fErase ; rcPaint; fRestore ; fIncUpdate; rgbReservedC16] ; / / 描画用ディスプレイコンテクスト / / 背景が再描画されたか ? / / 描画すべき矩形領域 / / 予約 ( Wind 。 ws 内部処理用 ) / / 予約 ( Wind 。 ws 内部処理用 ) / / 予約 ( Wind 。 ws 内部処理用 ) } PAINTSTRUCT ; . 13 Table 19 RECT 型の定義 typedef } RECT; int int int int left; top; right; bottom; / / 左端座標 / / 上端座標 / / 右端座標 / / 下端座標 BeginPaint と EndPaint の概要 BeginPaint 形式 解説 戻り値 HDC BeginPaint(HWND hWnd, LPPAINTSTRUCT lppaint) : hWnd によって表されるウインドウの描画準備を行い , lpPaint の指す PAINTSTRUCT 構造体デ ータに , 描画に関する情報を格納する。 指定したウインドウのテパイスコンテクストの識別子 関連項目 EndPaint EndPaint 形式 解説 戻り値 void BeginPaint(HWND hWnd, LPPAINTSTRUCT lppaint) : hWnd によって表されるウインドウの描画の終了処理を行う。 lpPaint は , BeginPainth\ 与えた PA 爪 TSTRUCT 構造体へのポインタてなければならず , 必す BeginPaint と対にして呼び出さな なし けれはならない。 関連項目 BeginPaint それて、は , ウインドウブロシージャが W M PAINT に応答して行っていることを , 具体的に見ていこう。 まず , BeginPaint と EndPaint が対になっ ていることがわかる ( これらの関数の概要を TabIe 19 に示す ) 。 BeginPaint (hwnd, &ps) ・ hdc EndPaint (hwnd, &ps) ・ 第 1 引数は , 描画の対象となるウインドウ のウインドウハンドルて、ある。第 2 引数は , PAINTSTRUCT 構造体へのポインタ (LPP AINTSTRUCT 型として定義されている ) て、 ある。 PAINTSTRUCT 構造体は , Fig. 12 のよ うに定義されている。 ウインドウのクライアント領域に , グラ フィックやテキストを出力するには , デバ イスコンテクストのハンドルが必要て、ある。 BeginPaint は , デバイスコンテクストのハ ンドルを返す。 EndPaint は , BeginPaint が返したハンド ルを解放する役目を持つのて、 , BeginPaint と EndPaint は , 必ず対に呼び出さなければ ならないことに注意しなければならない さて , BeginPaint によって描画の準備を した後は , GetClientRect(hwnd, &rect) ・ によって , クライアント領域を取得する。 GetClientRect の概要を Table 20 に , RECT 構造体の定義を Fig. 13 に示す。 GetClient Rect は , 左上隅を示す left , top には必ず 0 を , right および bottom には , クライアント 領域の幅と高さを格納する。 テキストの出力を行うのが , 次の行て、あ DrawText (hdc, "HeIIO, World!" ー 1 , &rect, DT SINGLE 凵 NE DT CENTER ー DT VCENTER) ; 特集 MS-Windows プログラミング基礎学 63 DrawText の概要については , Table 21

4. 月刊 C MAGAZINE 1992年11月号

Fig. 7 Window とメッセージの概路 キーボード Fig. 8 MSG 構造体の定義 typedef struct tagMSG { hwnd; HWND WORD message; WOR D WParam : LONG 1 Param ; DWORD time; POI NT pt; } MSG; / / メッセージが送られるウインドウのハンドル / / メッセージ識別子 / / ワードバラメータ / / ロングパラメータ / / メッセージがキューにポストされた時刻 / / メッセージがポストされたときのマウスの座標 マウス タイマ Windows Fig. 9 PO 爪 T 構造体の定義 typedef s truct tagP01 NT ( / / X 座標 int / / Y 座標 i nt ) POINT; アプリケーション アプリケーション るのか , マウスの情報て、あるのかはわから よ ! ) や WM DESTROY( ウインドウが破壊 ージループの解説に移れるようになった。 ない ( わざと選択的に待っこともて、きるが , される ! ) のように , WM て、始まる名前が while 文の条件式中の GetMessage が , メ あまり一般的て、はない ) 。 ッセージを受け取る関数だ ( 概要を Table 与えられている。 Windows て、は , そのような情報をメッセ 14 に示す ) 。 GetMessage は , 受け取ったメ 続くメンバ , wParam および IParam は , ージという概念て、考える。キーポードやマ サプメッセージ , すなわちウインドウメッ ッセージが , アプリケーションを終了する ウスの操作などは , メッセージの形に変換 必要があることを指示する WM QUIT て、あ セージに対する追加情報が格納される。 され , Windows システムに送られる。その れば , アプリケーションを終了すべきて、あ こに格納される内容は , 各メッセージによ メッセージは , アプリケーションに読み出 ることを示す FALSE を返す 0FALSE は 0 と って異なる。たとえば , 文字入力を表す W され , そのメッセージに対して何らかの処 して定義されているのて、 , while ループは , M CHAR メッセージの場合 , 入力された文 理を行うというのがⅥⅱ ndows プログラムの 字の ASCII コードがサプメッセージて、ある w 繰り返しを終了する。 基本的な構造てある。 Windows とメッセー これがメッセージループの骨格だ。 Param に格納される。 ジの関係の概略を Fig. 7 に示す。 while (GetMessage(&msg, NULL' 0 , 0 ) ) { 最後のふたつのメンバは , メッセージ発 TranslateMessage (&msg) ・ 生時の状況を示すものて、ある。メンバ time メッセージを表す MSG 構造体 DispatchMessage(&msg) ・ には , メッセージがメッセージキューに入 れられた時間が , メンバ pt には , その時点て、 第 2 引数は , アプリケーションに属するす Windows の動作の根本となるのがメッセ のマウス座標が格納される。なお , 座標を べてのウインドウのメッセージを得るため ージて、あることがわかったが , そのメッセ 表す POINT 構造体は , Fig. 9 に示すように ージは , プログラム上て、はどのように表現 に NULL を指定している。第 3 引数 , 第 4 引 定義されている。 されるのだろうか。メッセージは , Fig. 8 のよ 数は受け取るメッセージの範囲を制限する うに定義される MSG 構造体として表される。 メッセージループ。。 ためのものて、あるが , 通常はすべてのメッセ ージを受け取るのて、 , 両方とも 0 を指定する。 MSG 構造体の各メンバを見ていこう。 これて、 , 先ほど名前だけ紹介した GetMessage が受け取ったのが , WM QU 最初のメンノ *hwnd は , メッセージの送り ' メッセ 先て、あるウインドウを表す。 TabIe 14 GetMessage の概要 2 番目のメンバ message は , メッセージ識 GetMessage 別子て、あり , どのようなイベントが発生し * IpMsg, HWND hWnd, WORD wMsgFilterMin• 形式 BOOL GetMessage(LPMSG たのかをアプリケーションに知らせる。 WORD wMsgFilterMax) : れは , ウインドウメッセージと呼ばれるも 解説 アプリケーションキューからメッセージを受け取り , ゆ Msg の指す LPMSG 構造体テータに , メ ッセージを格納する。 のて、 , <windows. h> には , すべてのウイン hWnd には , メッセージを受け取るウインドウの識別八ンドル ( アプリケーションに属するすべ ドウメッセージが定義されている。ウイン てのウインドウのメッセージを得るには NUL し ) を指定する。 戻り値 メッセージが WM QU げであれば 0 ( FALSE ) を , そうでなければ非ゼロの値を返す。 ドウメッセージには , WM PAINT ( ウイン 関連項目 PeekMessage, WaitMessage ドウの描画内容が破損したのて、 , 再描画せ 56 C MAGAZINE 1 2 11

5. 月刊 C MAGAZINE 1992年11月号

ープロクラミング道場 Dr. 望洋の List 5 のコンノヾイルによるアセンプリソース 同一の文字列リテラル LiSt LiSt 1 : #include く stdio. h> 2 : 3 : int main(void) 5 : char *SI 6 : Char *s2 7 : sl [ 0 ] = 8 : puts(sl) ; 9 : puts(s2) ; 10 : return ( の ; 11 : cs : TEXT assume 2 : near maln proc bp 3 : push bp, s p 4 : mov ax, offset DGROUP: s@ 6 : mov push call near ptr _putS 9 : CX 00P 10 : ax, offset DGROUP: s@+ 4 11 : mov 12 : push call 13 : near ptr —puts 14 : CX POP 15 : ax, offset DGROUP: s@+ 5 16 : mov push 17 : call 18 : near ptr _puts 19 : CX POP 20 : ax, offset DGROUP: s@+ 9 21 : mov 22 : push call 23 : near ptr _putS 24 : CX POP 25 : 26 : ax, ax xor short @1@58 27 : Jmp 28 : @1@58 : 29 : POP 30 : ret endp 31 : maln 32 : endS TEXT segment word publ ic ' DATA' 33 : DATA 34 : s@ label byte ' ABC' db 35 : db 0 36 : 37 : db 0 38 : db 39 : 0 db 40 : 0 41 : endS DATA segment byte public ' CODE' 42 : _TEXT endS 43 : _TEXT public _main 44 : 45 : extrn _puts : near 46 : equ end int main(void) ” ASDF ”・ ” ASDF ”・ puts( ” ABC ” ) ; Fig. 5 List 7 の実行結果 (a) ZSDF ZSDF ZS D F ASDF て、ある。フナイルをオープンする fopen 関数 は , オープン失敗時に NULL を返すのて、 , fopen ("file" if ((fp NULL) / * オープン失敗 * / のような記述をする。説明するまて、もない だろうが , ここて、の fp は FILE * 型として定 義されていなければならない こて、 , 次 の規則を覚えておこう。 puts( ” ABC ” ) ; return ( の ; ” ABC ” ” ABC ” ' ABC' 【重要】スルポインタが , ほかのポイ ンタに代入されたり , 比較されるときは , そのポインタ型に変換される したがって , スルポインタは , FILE * や int * などの , あるゆる型へのポインタとの 比較が可能なのて、ある。間違っても , if ( (fp fopen ("file いるのに違和感を持つ人もいるだろう。整 SI の定義によると , # if 内て、の sizeof は意味を (FILE *)NULL) 数値 0 は , 任意のポインタ型へと変換可能で / * オープン失敗 * / 持たないのて、 , このような定義は間違いて、 あり , その結果はヌルポインタとなるとい あるといえる。 といったキャストを行わないように。冗長 う規則があるから , 問題がないのて、ある。 void ポインタは ,ANSI て、取り入れられた て、あり , プログラムが醜くなるだけだ。 80X86 系の処理系て、は , メモリモデルによっ ものて、 , ( 3 ) の定義は比較的新しい。これだ てポインタの大きさを変える必要があるの とメモリモデルによる切り換えも必要ない し , もっとも親切て、ある。今後はこのよう 最後に , 少し難しい話をしよう。 NULL な定義を提供する処理系が増えるて、あろう。 は , 0 とはかぎらないのて、ある ( ! ? ) 。話がや やこしくなるのて , 順を追って説明しよう。 NU L [ との比較 int *p C 言語の標準ライプラリ中のいくっかの関 は , int へのポインタて、ある p に対して , 整数 #define NULL 数は , 「無効なポインタ』を表すために , N 定数 0 を代入している。 0 はスルポインタへ #endif といった定義も見受けられる。しかし , AN ULL を返す。たとえば , malloc, f 叩 en など と変換されて , p に代入される。したがっ U 住は 0 ではな #if sizeof(void * ) = =sizeof (int) #define NULL 0 #else D 「 . 望洋のプログラミング道場 121

6. 月刊 C MAGAZINE 1992年11月号

特集 ープログラミンク WM DESTROY このメッセージは , ウインドウに対して 破棄する旨を通知する。 DestroyWindow 関数はスクリーンから削除した後のウィ ンドウに WM DESTROY メッセージを送 る。ウインドウが破壊される前には , そ の親ウインドウに対して WM DESTROY メッセージが送られる。 nothing. exe て、は , ウインドウを破壊する ときに , 特別な後始末処理が必要なわけ て、はない。ただ PostQuitMessage ( 0 ) を実 行しているだけて、ある。 PostQuitMessa ge は , メッセージキューに WM QUIT メ ッセージをポストする (Table 17 ) 。 WinMain 関数のメッセージループは , G etMessage が読み出したメッセージカ第一 M QUIT て、あれば , 繰り返しを終了するこ と ( すなわちプログラムを終了すること ) は , 前述した。これて、 , 正しくプログラ ムが終了て、きる。 WM QUIT メッセージの概要を示す。 WM QUIT アプリケーションが postQuitMessage 関 数を呼び出したときに生成され , アプリ ケーションの終了を要求する。 このメッセージが送られると , GetMess age 関数は 0 を返す。なお , wParam には PostQuitMessage 関数の呼び出して、与え られた終了コードを含む。 このことから , WM QUIT メッセージ List は , 「 Windows が与えるメッセージ」て、は なく , 「 WM DESTROY に応答して Post QuitMessage を呼び出すことによって , アプリケーションが生成するメッセージ」 て、あることがわかる。このあたりは少し 難しいのて、 , 後て、もう一度説明する。 さて ,WM DESTROY 以外のメッセージ は , (b) て、ある。最初のほうて、も述べたよ うに , この nothing. exe に対しては , ウィ ンドウを移動したり , ウインドウの大き さを変更したり , アイコン化したりする ことがて、きる。ューザが , そのような操 作を行うたびに , いろいろなメッセージ が発生しているはずだ。しかし , このプ ログラムて、は , それらのメッセージに対 して , 特別な応答をする必要はなく , W indows て、決められている既定の処理だけ を行えばよい。自ら応答する必要がない メッセージの対処を , Windows に委ねる のが , DefWindowProc (TabIe 18 ) て、ある。 モジュール定義ファイル 以上て、 , ようやく「何もしないプログラム」 をひと通り解説した。 先ほども簡単に述べたように , C 言語のソ ースファイルだけて、は , Windows の実行フ ァイルを作成することはて、きず , モジュー ル定義ファイルと呼ばれるファイルを用意 Step9 発環境型の処理系て、は , モジュール定義フ ァイルを必要としない ) 。 nothing. exe を作成するための , モジュー ル定義ファイルて、ある nothing. def を List 3 に示す。 , こて、 , 、、 ; ク ( セミコロン ) はコメントの 開始を意味する。 〃からその行末まて、 しなければならない ( ただし , 部の統合開 nothing. exe 用モジュール定義ファイル 4 : 6 : 7 : 8 : 9 : 10 : 11 : 13 : EXPORTS 12 : STACKSIZE HEAPSIZE DATA CODE STUB EXETYPE N0th i ng. def 5 : NAME NOTHING DESCRIPTION ' Nothing (c) BohYoh Shibata, 1992 ' WINDOWS 3.0 ' WINSTUB. EXE' PRELOAD MOVABLE DISCARDABLE PRELOAD MOVABLE MULTIPLE 1024 8192 WndProc は , コメントとみなされる。 NAME には , モジュール名を記述する。 通常は , . EXE ファイルのファイル名をモジ ュール名とする。 DESCRIPTION には , プログラムに対す るコメントを記述する。一般には , 著作権 やアプリケーションのバージョン番号など て、あり , この文字列は , . EXE ファイル中に 埋め込まれる。 EXETYPE には , プログラムが WINDO WS て、あることを主張する ( OS / 2 などとの区 別のために必要 ) 。 Windows て、はなく , MS-DOS から nothin g. exe を起動しようとしたときに実行するプ ログラムを指定するのが STUB だ。通常は winstub. exe を指定する。これは , 英語版て、 あれば , 'This program requires Microsoft Wi ndows ” 日本語版て、あれば , このプログラムの実行には , Microso ft Windows が必要です。 と表示 , 終了するプログラムて、ある。 CODE には , 三つの属性を指定している。 PRELOAD 実行と同時にセグメントをロー ドすることを意味する。 MOVEABLE 空きメモリプロックをまとめ なければならなくなったときに , メモ リ内の他の位置に移動されることを許 可することを意味する。 DISCARDABLE メモリ不足の際に , 必要 に応じて . EXE ファイルからロードされ るのて、あれば , メモリから破棄されて もかまわないことを意味する。 なお , PRELOAD と相反する指定として LOADONCALL(±グメントを必要に応じ 特集 MS-Windows プログラミング基礎学 59

7. 月刊 C MAGAZINE 1992年11月号

Ste 1 List HelloMB. exe 用モジュール定義ファイル 2 : HeIl 醴 B. def 3 : 4 : 5 : NAME HelloMB 6 : DESCRIPTION ' HelIo (c) BohYoh Shibata, 1992 ' 7 : EXETYPE WINDOWS 3.0 ' WINSTUB. EXE' 8 : STUB 9 : CODE PRELOAD MOVABLE D I SCARDABLE 10 : DATA PRELOAD MOVABLE MULT I PLE 11 : HEAPSIZE 1024 12 : STACKSIZE 8192 メニューテンプレート メニューの追加は , わりと簡単だ。まず , リソース記述ファイルにメニュー構造を記 述する。これは , 一般にメニューテンプレ ートと呼ばれるものだ。 HelloMenu MENU BEGIN Fig. 1 6-(a) helloa. exe の実行例① atok7 Tu 「 bo P VtnAtok QC END は , HeIIoMenu という名前を持つメニュー の定義開始を指定し , そのメニューの定義 は , BEGIN と END て、囲まれた部分て、ある CBEGIN ′′ , 、、 END 〃の代わりに , C 言語のプ ロックと同様に { , } を使ってもよい ) 。 そのメニューの中は , POPUP "&Help" BEGIN H . World! MENUITEM ” About...", IDM ABOUT END と記述されている。 POPUP は , ポップアップメニューて、ある ことを指定する ( ポップアップて、ないメニュ ーて、あれば , POPUP て、はなく MENUITEM と記述する ) 。 次の、、 & HeIp 〃は , メニューの項目名てあ る。ここて、、、 & クをつけているのて , 最初の文 字てある H クは , 下線つきて、表示され , しか もユーザは , 十回キーて、選択て、き る。いわゆる , アクセレーターとか , ホッ トキーと呼ばれるものて、ある。 さて , その Help メニューの下には , さら にひとつだけ子メニューがある。そのメニ ュー項目名はヾ About …クて、ある。 クをつ けているのは , 一般に , ダイアログボック スを開くメニューには ! 〃をつける慣習が あるからて、ある。 最後に IDM ABOUT を指定しているが , 68 C MAGAZINE 1 2 11 \ ' ェに 0 彎 \ 平をに 0 心 0 ' 当 List He OA. exe 用リソースファイル 2 : HelloA. rc 3 : Hel 10A 用リソースファイル 4 : 5 : 6 : 7 : #include く windows. h 〉 8 : #include ” helloa. h ” 9 : 10 : HelloMenu 11 : BEGIN POPUP ”囲 e 10 ” BEGI N 14 : MENUITEM ” Atmt.. 15 : END 16 : END 18 : AboutBox DIAIÆ 22 , 17 , 144 , 72 19 : STYLE WS_CAPTION ー WS_SYSMENU (C ) BohYoh Sh i bata, 1992 , I DM_ABOUT

8. 月刊 C MAGAZINE 1992年11月号

種川種行 om 川計 Ma れ門 FUJITSU High C VI. 7 拡張ライプラリⅡ になりますが , 囲キーや特殊キー Q ファイルダイアログを使う場 の場合は , 特別なコードになりま 合の注意点などありますか す。ショートカットに使える特殊 キーのキーコードー覧を Table 1 に A あげておきますのて、 , 参考にして ファイルダイアログは , GUI の 標準部品をいくっか組み合わせて ください 構成されています。したがって , 使用している部品の初期化が必要 Q ューサ定義のアイコンの作り になります。通常はアプリケーシ ョンて、使用する部品をプログラム 方はどうすればいいの ? の最初て、初期化するわけて、すが , A GUI ライプラリてはシステムて、 ファイルダイアログを使う場合は PFI アプリケーションて、使用していな いくつかのアイコンが用意されて P F 12 くてもファイルダイアログが使用 おり , アイコンの番号を指定する している部品は初期化する必要が だけて、ボタンやメニューて、使える PF13 PF20 あります。ファイルダイアログが使 ようになっています。それ以外に 取消 アプリケーション固有のアイコン 用しているのは Fig. 1 の部品てす。 パターンを定義して使用すること 実行 がて、きます。 Q ショートカットキーの設定の ューザアイコンの定義は , アイ 合のアイコン番号は 1024 番以降に ントループをネストして使うこが コンパターンのテープルを登録す 仕方を具体的に教えてください てきます。 なります。 る方法とアイコンパターンを取得 いずれの方法て、も 2 値から 32K 色 通常 GUI を初期化し , 動きはじめ A メニューやボタンにはショー する関数を登録する 2 通りの方法が まて、各色モードのアイコンを定義 るところて、呼ぶ MMI ExecSyste トカットキーを設定することがて あります。 することがてきます。詳しくはリ m は , ローカルな関数の中ても呼ぶ きます。ショートカットキーは , 則者のアイコンパターンのテー ファレンスマニュアルの各関数の ことがてきます。こうすると , そ メニューやボタンがアクテイプな プルを登録するという方法は , M 項目を参照してください の時点て、イベントループが回り始 状態 , つまりマウスて、選択て、きる MI SetIconTabIe 関数を使ってア めます OMMI ExecSystem を抜け 状態になっているとき , マウスの イコンパターンが定義されている て帰ってくるのは , MMI SetHal Q で局所的なループを作り 代わりにキーポードて、操作て、きる 構造体のポインタの配列 ( 登録する tFlag(TRUE) が実行されたときに アイコンの数の要素数を持っ ) を設 ようにするものて、す。 なります。たとえば [ 確認 ] ボタ たいのですが 定します。この場合のアイコン番 ンて終了するようなアラートボッ ショートカットキーとしては , A 皿キーとーキーを押し 号は 512 から 1023 まてを使用するこ GUI ライプラリを使ってのプロ クスを作る場合 , アラートボック ながらキーを押すものと囲 とがてきます。 グラミングては通常メニューやポ スを表示後に MMI ExecSystem キーやキー」など直接タイプ 後者のアイコンパターンを取得 タンなどの処理関数は , イベント を呼び , 確認ボタンの実行関数内 する関数を登録する方法て、は , ま て , アラートを消してから MMI S ループから呼ばれ , 処理が終わる して有効になるものがあります。 ずアイコン番号に対してアイコン とまたイベントループへ帰ってゆ ショートカットキーの設定は , etHaltFIag(TRUE) を実行するよ のパターンを帰す関数を用意して くという構造になっています。し うにしておきます。こうすると , GUI レイアウタて、部品ごとに設定 MMI SetGetIcnDataFunc て、登録 かしときには , イベントループを します。レイアウタて、部品の属性 アラート関数を呼ぶとアラートを します。この方法てはアイコンパ 関数の内部て持って , ある一連の 表示し , 確認ボタンが押されるま の項目にショートカットキーの設 定がありますが , ターンをあらかじめ定数として用 処理が終わるまて、はその関数を抜 て待っという一連の処理をひとつ こには「キーコ ード」を設定します。キーコードは 意しなくても , その場て生成する けたくないというような場合があ の関数内て、完結するという作りに キーの場合は , ASCII コード ような使い方がて、きます。この場 ります。このような場合は , イベ することがて、きるわけて、す。 Fig . 1 ファイルダイアログが使用している部品 ・ダイアログ ・メッセージ ・ドローボタン ・アイコンボタン ・スクロールバー ・テキスト ・リストメニュー Table 1 特殊キーのショートカットコード コード ( 1 6 進 ) 8001 ~ 800B 801 D 8021 ~ 8028 ( テンキーっきのみ ) 801 1 8012 PF 1 1 162 C MAGAZINE 1992 11

9. 月刊 C MAGAZINE 1992年11月号

List 1 6 ジ wParam には , ダイアログテンプレートて、 指定したコントロール ID が格納されてい る。そのメッセージが IDOK もしくは IDCA NCEL の場合は , EndDialogBox を呼び出す ことにより , ダイアログボ、ツクスを終了す 77 : 78 : 80 : 82 : 83 : 84 : 86 : 87 : / * ー メイン関数 88 : 89 : 90 : int PASCAL WinMain(HANDLE hlnstance, HANDLE hPrevlnstance, LPSTR lpszCmdParam, int nCmdShow) 92 : { hwnd ; HWND 93 : MSG 94 : msg; wndclass : WNDCLASS 95 : 96 : hlnst = hlnstance; if ( !hPrevInstance) { 98 : wndclass. style 99 : wndclass. lpfnWndProc 100 : wndclass. cbClsExtra 101 : wndclass. cbWndExtra 102 : wndclass. hlnstance 103 : wndclass. hlcon 104 : wndclass. hCursor 105 : wndclass. hbrBackground 106 : wndc 1 as s. 1 ps zMenuName 107 : wndclass. lpszClassName 108 : RegisterCIass(&wndclass) ; 109 : 110 : hwnd = CreateWindow(szAppName, ” Hel 10 World ! ” 111 : WS OV ERLAPPEDWI NDOW, 112 : CW_USEDEFAULT, CW_USEDEFAULT, 113 : CW USEDEFAULT, CW_USEDEFAULT, 114 : NUiL, NULL, hlnstance, NULL) ; 115 : 116 : ShowWindow(hwnd, nCmdShow) ; 117 : UpdateWindow(hwnd) ; 118 : 119 : while (GetMessage(&msg, NULL, 0 , の ) { 120 : TransIateMessage(&msg) ; 121 : DispatchMessage(&msg) ; 122 : 123 : return (msg. wparam) : 124 : ー 125 : ) = IDYES) if (ConfirmTerm(hwnd) DestroyWindow(hwnd) ; return ( の ; cas e WM_DE STROY : PostQuitMessage( の : return ( の : return (DefWindowProc(hwnd, message, lParam) ) : ダイアログボックス プロシージャの工クスポート ダイアログボックスプロシージャは , ウ インドウブロシージャと同様に , Windows から呼び出される関数て、ある。したがって , モジュール定義ファイルの EXPORTS に登 録しなければならない。モジュール定義フ ァイルを List 13 に示す。 もう少し凝った プログラム = CS_HREDRAW ー CS_VREDRAW ; ニ WndProc ; = hlnstance; = LoadIcon( NULL, IDI—APPLICATION) : ニ LoadCursor(NULL, IDC—ARROW) : ニ GetStockObject(WHITE_BRUSH) : ” Hel loMenu ” szAppName ; Step3 helloa. exe に手を加え , もう少し凝ったプ ログラムて、ある hellodx を , List 14—List 16 に示す ( モジュール定義ファイルは , 付録 ディスクに収録 ) 。 Fig. 17,Fig. 18 の実行例を見ていただけ れば , どのように手を加えたかご理解いた だけるて、あろう。 こて、のメニュー構造は , Fig. 19 のよう になっており , さらに he110C2. c と同様に プログラム終了時には確認を行うものとす return ( 0 ) ; こて、行っていることがわかるだろうか。 アプリケーションを終了させなければなら ないのて、 , WM CLOSE というメッセージ を発生させ , 自分自身に送っているのて、あ る。したがって , ウインドウブロシーシャ が , 次に呼び出されるときは , WMCLSO このプログラムて、は , 、、 FiIe ' ' メニューの下 E メッセージを受け取ることになり , そこて、 に、、 Exit" メニューがある。このメニューは , ーて、 終了処理に取りかかるわけて、ある。 アプリケーション終了のためのメニュ このように , あるメッセージに対して , あり , IDM EXIT というメニュ—ID を割り ほかのメッセージと同様な処理を行わせる 当てている。その処理の部分を見てみよう。 メニューテンプレートにおいて , 、、 Edit 〃の 必要があるときは , そのメッセージを自分 case IDM E 刈 T 項は , 自身に対して送るというテクニックが頻繁 SendMessage (hwnd, WM CLOSE' に使われる。必ず覚えておかねばならない と定義している。 GRAYED を指定すること によって , メニューは無効化され , テキス トの表示もグレイ ( 淡色 ) になる。 Step4 プログラムの解説 Exit メニュー 誌面の残りに余裕がないのて、 , 重要な点 のみを , かいつまんて、解説しよう。 グレイメニュー '&Edit ” , IDM EDIT, MENUITEM GRAYED 74 C MAGAZINE 1992 11

10. 月刊 C MAGAZINE 1992年11月号

特集 ープロクラ ミンク ウインドウ構造体に対して , 付加的な追加 スタイル 情報を加える際に , その大きさをバイト数 アイコン て、指定するためのものて、ある。 最初のメンバは , スタイルて、ある。 hlcon には , アイコンを設定する。アイコ wndclass. cbClsExtra ンには , Windows て、定義済みの標準アイコ wndclass. style = CS HREDRAW wndclass. cbWndExtra ンと , ユーザが自分て、デザインするものと この例て、は , 追加情報を必要としないの CS VREDRAW がある。 style には , ウインドウのクラススタイル て、 , 0 を指定している。 を指定する。スタイルは , CS て、始まる定数 Loadlcon (NULL, wndclass. hlcon インスタンスハンドル として < windows. h > 中に定義されている 一団 APPL ℃ ATION) ; (Table 4 ) 。この例のように , 各スタイルの TabIe 5 標準アイコンの識別子 ビット和を指定することもて、きる。 前述したとおり , WinMain 関数の引数と こて、 識別子 説明 は , 縦方向または横方向のサイズ変更にと して受け取る hlnstance には , 自分のプログ もなって , ウインドウを再描画することを ラムの背番号 = インスタンスハンドルが与 ー APPLICATION 標準的なアイコン 指定している。 一団 HAND 重大警告用の手 ( STOP ) えられている。 ー QUESTION 質問用の、、 ? ″ wndclass. hlnstance hlnstance , 警告用のツ″ 一団 EXCLAMATION wndclass のメンバ hlnstance には , その値 一団 ASTERISK メッセージ用の、、 * ″ をそのまま設定すればよい Fig. 5 標準アイコン ウインドウブロシージャ 2 番目のメンバは , ウインドウブロシーシ ャて、ある。 wndclass 」 pfnWndProc WndProc ; 説明するまて、もなく , こて、初期値とし て与えている WndProc は , List 2 において プログラマが定義した関数の名前て、ある。 C 言語て、は ,func( ) といった関数呼び出して、 なく , func のように名前だけが現れると , その関数へのポインタを意味することはご 存じだろう。したがって , lpfnWndProc と いうメンノヾに , WndProc のポインタを代 入しているのだ。 こて、 ,WinMain 関数をよく見ていただ きたい。 WinMain 関数中て、 , 、、 WndProc" が登場するのは , こだけて、あり , WndPr 。 c 関数を呼び出している箇所はどこにもな い。通常の C 言語のプログラムて、は , すべて の関数は , main 関数から直接もしくは間接 的に呼び出されるものて、あるはずだが 詳細は , WndProc 関数の項て、解説すること にして , 次のメンバを見て行こう。 追加バイト 計 nO ア , co ロ・②④① IDI APPLICATION IDI HAND IDI QUESTION IDI EXCLAMATION IDI_ASTERISK 次のふたつのメンバは , クラス構造体 , 特集 MS-Windows プログラミング基礎学 51