30章 メニューとキーボードアクセラレーター(その2)

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis"></meta>
<title>30章 メニューとキーボードアクセラレーター(その2)
</title>
</head>

<body bgcolor="WHITE">
<font size="5">30章 メニューとキーボードアクセラレーター(その2)
</font>
<hr>
<p>
 メニューと言うのは、Windowsの中で、最も基本的なオペレーターの操作手段ですので、6章で簡単に説明しました。これからの章では、重複する事もありますが、メニューとキーボードアクセラレーターについて説明します。
<p>
 メニューの作成と表示の方法は、大きく3つあると言えるでしょう。<br>
 つまり、<br>
<b>1.リソースとしてメニューを作成し、ウインドウクラスに関連付ける。<br>
2.リソースとしてメニューを作成し、ウインドウに関連付ける<br>
3.アプリケーションの実行中に動的にメニューを作成して、ウインドウに関連付ける。</b><br>
<p>
 6章では、1の方法でウインドウにメニューを付けました。
<p>
 まずは、復習と言った意味で、リソースの作成の方法と1の方法の説明を再度し、2の方法を説明します。
<hr>
<p>
<b>・リソースの作成の方法の復習</b>
<p>
 6章で説明したように、リソースは、リソースファイル(拡張子は.rc)に格納されます。これは、単なるテキストファイルですので、テキストエディタでもリソーススクリプトを知っていれば、作成できます。<br>
 しかし、リソースファイルは、VisualC++バージョン5の機能の一つであるリソースエディタを使う方が、視覚的に作成でき、リソーススクリプトも覚えなくて良いので便利です。ただ、欠点は、他の処理系でコンパイルするときに、コンパイル出来ない事ぐらいです。つまり、汎用性が無いのです。
<p>
 リソースファイルの作成の方法は、VisualC++バージョン5のメニュー[プロジェクト]→[プロジェクトへ追加]→[新規作成]で、新規作成のダイアログボックスが開きます。ここでファイルタブを選びます。そして、リソーススクリプトを選択し、ファイル名のエディットボックスに半角文字で、resource.rcと入れて、OKボタンを押します。これで、リソーススクリプトが格納させるファイルと、C言語のソースと定数を共有するためのヘッダファイルresource.hが作成されます。
<p>
<center>
  <img src="/web/20151022184113im_/http://web.kyoto-inet.or.jp:80/people/ysskondo/from29/g30_1.gif"><br>
<b>図30-1</b>
</center>
<p>
 図30-1の様に、マウスの右ボタンで、ポップアップメニューを表示させ、挿入を選びます。
<p>
<center>
  <img src="/web/20151022184113im_/http://web.kyoto-inet.or.jp:80/people/ysskondo/from29/g30_2.gif"><br>
<b>図30-2</b>
</center>
<p>
 図30-2の様に、作成するリソース(この場合、Menu)を選択します。
<p>
<center>
  <img src="/web/20151022184113im_/http://web.kyoto-inet.or.jp:80/people/ysskondo/from29/g30_3.gif"><br>
<b>図30-3</b>
</center>
<p>
<center>
  <img src="/web/20151022184113im_/http://web.kyoto-inet.or.jp:80/people/ysskondo/from29/g30_4.gif"><br>
<b>図30-4</b>
</center>
<p>
 図30-3と図30-4の様に、メニューとして表示さすキャプションを入力します。<br>
 図30-4の様に、実際にメニューとして、WM_COMMANDメッセージを発行するメニュー項目は、ポップアップチェックボックスを外し、IDにシンボリックな文字列を入力する必要があります。IDになるシンボリックな文字列に対応する数値は、リソースエディタが自動的に作成してくれます。
<hr>
<p>
<b>・1の方法の復習</b>
<p>
 まず、百聞は一見にしかりで、メニューからメッセージボックスを表示さす簡単なプログラムを提示しましょう。
<p>
<table border="1" bgcolor="#F0F0F0">
<caption align="BOTTOM">リスト30-1<a href="c30_1.lzh">ダウンロード</a>
<tr><td>
<pre>
/* C言語で始めるWindowsプログラミング */
/* 30章のサンプルプログラム */
/* ウインドウクラスにリソースとして作成した *
/* メニューを関連付ける例 */
/* Programmed by Y.Kondo */
/* 注:TABサイズは4で見てください */

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

/* ウインドウプロシージャのプロトタイプ宣言 */
LRESULT CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM);

/* アプリケーションエントリーポイント */
int WINAPI WinMain(HINSTANCE hInstance,
                 HINSTANCE    hPrevInstance,
                  LPSTR        CmdLine,
                  int          CmdShow)
{
  HWND            hwnd;   /*  メインウインドウのウインドウハンドル    */
   MSG             msg;    /*  メッセージキューから取得したメッセージ  */
   WNDCLASS        wc;     /*  ウインドウクラス登録用の構造体          */

  wc.style        =0;
   wc.lpfnWndProc  =WindowProc;
   wc.cbClsExtra   =0;
   wc.cbWndExtra   =0;
   wc.hInstance    =hInstance;
   wc.hIcon        =LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
   wc.hCursor      =LoadCursor(NULL,IDC_ARROW);
   wc.hbrBackground=GetStockObject(WHITE_BRUSH);
<b> wc.lpszMenuName =MAKEINTRESOURCE(IDR_MENU1);</b>
  wc.lpszClassName="MainWindowClass";
   
   if(RegisterClass(&wc;)==0)               /*  ウインドウクラス登録    */
       return  0;

  hwnd=CreateWindow(  "MainWindowClass",  /*  ウインドウ作成          */  
                       "30章:ウインドウクラスにメニューを付けた場合",
                       WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       NULL,
                       (HMENU)NULL,
                       hInstance,
                       0);
   if(hwnd==NULL)
       return  0;

  ShowWindow(hwnd,CmdShow);           /*  ウインドウの表示        */
   UpdateWindow(hwnd);                 /*  ウインドウの最初の更新  */

  while(GetMessage(&msg;,NULL,0,0))    /*  メッセージループ        */
   {
           TranslateMessage(&msg;);
           DispatchMessage(&msg;);
   }
   return  msg.wParam;
}

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

/* メインウインドウのウインドウプロシージャ */
LRESULT CALLBACK WindowProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
{
  switch(message)
   {
       case    WM_COMMAND:         /*  メニューに対する処理    */
           return  Wm_CommandProc(hwnd,HIWORD(wparam),LOWORD(wparam),(HWND)lparam);
       case    WM_DESTROY:         /*  ウインドウの破壊後処理  */
           return  Wm_DestroyProc();
   }
   return  DefWindowProc(hwnd,message,wparam,lparam);
}

static LRESULT Wm_CommandProc(HWND hwnd,WORD wNotifyCode,WORD wID,HWND hwndCtl)
{
  if(wID==ID_MESSAGEBOX)
       MessageBox(hwnd,"MessageBox","MessageBox",MB_OK);
   return  0;
}
static LRESULT Wm_DestroyProc(void)
{
  PostQuitMessage(0);
   return  0;
}
</pre>
</table>
<p>
 リスト30-1の太文字の箇所に注目してください。ウインドウクラス、つまり、ウインドウの型レベルで、メニューをウインドウと関連付けています。従って、このウインドウクラスを用いて、ウインドウを作成すると、全てのウインドウに同じメニューが表示されます。
<hr>
<p>
<b>・2の方法の場合</b>
<p>
 これも百聞は一見にしかず。外見上は、1の場合と同じ様に見える簡単なプログラムを提示しましょう。
<p>
<table border="1" bgcolor="#F0F0F0">
<caption align="BOTTOM">リスト30-2<a href="c30_2.lzh">ダウンロード</a>
<tr><td>
<pre>
/* C言語で始めるWindowsプログラミング */
/* 30章のサンプルプログラム */
/* ウインドウにリソースとして作成した */
/* メニューを関連付ける例 */
/* Programmed by Y.Kondo */
/* 注:TABサイズは4で見てください */

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

/* ウインドウプロシージャのプロトタイプ宣言 */
LRESULT CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM);

/* アプリケーションエントリーポイント */
int WINAPI WinMain(HINSTANCE hInstance,
                 HINSTANCE    hPrevInstance,
                  LPSTR        CmdLine,
                  int          CmdShow)
{
  HWND            hwnd;   /*  メインウインドウのウインドウハンドル    */
   MSG             msg;    /*  メッセージキューから取得したメッセージ  */
   WNDCLASS        wc;     /*  ウインドウクラス登録用の構造体          */

  wc.style        =0;
   wc.lpfnWndProc  =WindowProc;
   wc.cbClsExtra   =0;
   wc.cbWndExtra   =0;
   wc.hInstance    =hInstance;
   wc.hIcon        =LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
   wc.hCursor      =LoadCursor(NULL,IDC_ARROW);
   wc.hbrBackground=GetStockObject(WHITE_BRUSH);
   wc.lpszMenuName =NULL;
   wc.lpszClassName="MainWindowClass";
   
   if(RegisterClass(&wc;)==0)               /*  ウインドウクラス登録    */
       return  0;

  hwnd=CreateWindow(  "MainWindowClass",  /*  ウインドウ作成          */  
                       "30章:ウインドウにメニューを付けた場合",
                       WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       NULL,
                       <b>LoadMenu(hInstance,MAKEINTRESOURCE(IDR_MENU1)),</b>
                       hInstance,
                       0);
   if(hwnd==NULL)
       return  0;

  ShowWindow(hwnd,CmdShow);           /*  ウインドウの表示        */
   UpdateWindow(hwnd);                 /*  ウインドウの最初の更新  */

  while(GetMessage(&msg;,NULL,0,0))    /*  メッセージループ        */
   {
           TranslateMessage(&msg;);
           DispatchMessage(&msg;);
   }
   return  msg.wParam;
}

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

/* メインウインドウのウインドウプロシージャ */
LRESULT CALLBACK WindowProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
{
  switch(message)
   {
       case    WM_COMMAND:         /*  メニューに対する処理    */
           return  Wm_CommandProc(hwnd,HIWORD(wparam),LOWORD(wparam),(HWND)lparam);
       case    WM_DESTROY:         /*  ウインドウの破壊後処理  */
           return  Wm_DestroyProc();
   }
   return  DefWindowProc(hwnd,message,wparam,lparam);
}

static LRESULT Wm_CommandProc(HWND hwnd,WORD wNotifyCode,WORD wID,HWND hwndCtl)
{
  if(wID==ID_MESSAGEBOX)
       MessageBox(hwnd,"MessageBox","MessageBox",MB_OK);
   return  0;
}
static LRESULT Wm_DestroyProc(void)
{
  PostQuitMessage(0);
   return  0;
}
</pre>
</table>
<p>
 リスト30-2の太文字の箇所に注目してください。ウインドウの作成の時にメニューが<b><u><i>LoadMenu関数を用いてロードされ、ウインドウと関連付けられています</i></u></b>。
<p>
 筆者としては、メニューからのメッセージを処理するのは、ウインドウクラスに結び付けられたウインドウプロシージャーですので、メニューをウインドウクラスに関連付ける方が、一般的と思います。
<hr>
<p>
 次回は、<b>29章のキーボードによる操作(その1)</b>の実装について説明します。では、お楽しみに。
<p align="RIGHT">
2002年12月05日<br>
加筆2002年12月08日<br>
<hr>
<p align="RIGHT">
<a href="/web/20151022184113/http://web.kyoto-inet.or.jp:80/people/ysskondo/index.html">目次</a><br>
<hr>
<p align="RIGHT">
著作権者:近藤妥
</body>
</html>

  • 最終更新:2018-03-11 05:26:11

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

認証パスワード