メルマガ:■CからウィンドウズDIRECTXプログラミング
タイトル:■CからはじめるWindowsDirectXへの道 ■  2000/09/02


 
発行部数:MagMag 2313  Pubzine 312  カプライト209
     Melten 31  E-Magazine 54  ここでメール 146
     Macky 153 Melma 224  

 総発行部数:3446

▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼
------------------------------------------------------------
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

■CからはじめるWindowsDirectXへの道 ■      
      
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

 ホーム:<http://www.geocities.co.jp/SiliconValley-Bay/3125> 
   
┌─────────────────────────────┐


■第2章 Windows( メニュー 編)   


└─────────────────────────────┘
───────────────────────────────
         話題
───────────────────────────────
   さて、1週間以上空いてしまいました.
  掲載する量の多さのため,すこし時間がかかりました。
   毎日,時間を少しずつ積み重ねて書いています.
  
  だんだん,伝送関係がつかめてきました.
  しかし、まだまだ概論のみです.
  計算などは,これからやっていこうと思っています.
  簡単に,TCP/IPといって、どれだけ説明できるのでしょう.
  TCP/IPが、ほとんどわかっていればそれだけで,
  ご飯を食べていけます.
  
  さて、どれだけ説明できるでしょうか?
     
  そこで、私も勉強することにしました.
  しかし、簡単にわかっていると、細かくわかっているとの
  違いは,大きいですね.

  このメルマガもそうですが、打たないとわからないメルマガです.
  まあ、私のプログラムに対しての考え方が出ています.
 
  なぜ、この説明を見ただけでわからないのか?
  それは、知らないからですね.知っていれば,関数を見るだけで,
  コードが頭に湧いてきます.
  
  とりあえず、試す。これが大事だと思います.
  読むだけでは、LAN もペーパードライバーとおなじです、
  試さなければ、何もわかりません.

  ということで,今度新規にPCを増やす予定です.
  サーバーアプリは,NT Sever か、UNIT系に使用と思っています.
  BSDにしようかな?Appacheは、ちょっとといった感じです.

    で、プログラムの話題ばかりですと,まじめすぎるので,
  いきなりカートレースです。バイクのレースもやりたいです.
  楽しいです。カートの大会も開いたりしちゃったりする店です.

    また、以前行ったカートレースをやったときに思ったこと

  [カートをやる人の車もまた腕もさることながら、改造も半端じゃないです.]

    でした。

   では、カートに大きなかかわりのある店の紹介!!

   どちらかというと,女の子しかこない店ですね.
   
   ですが、カートのレースがあったあとは、

    出場した人たちの溜まり場となっています。

         パーティもできるらしいです.
       冷やし冷たいトマトパスタがいまのお勧め!!
            ↓↓↓↓↓↓↓↓
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★
☆★    Pix CAFE                    ☆★
☆★    ピッサとカクテルと 楽しい空間       ☆★
      URL< http://www.geocities.co.jp/Foodpia/8873/>
                          
☆★       ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ☆★
☆★              発行者もおすすめ        ☆★
☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
           通信   (IPアドレス編)
    
  前回に引き続き、IPアドレスをもうすこし、
  くわしく勉強しましょう。

  前回、クラスは概略を示しましたが,
  すこし、それだけでは足りないと思い増したので,
  もうすこし突っ込んだ説明を行ないます.

  前回,クラスには、A,B,Cを使用すると触れました.
  
  では、構成はどうなってるの?と思った方は,勉強家です.

  二進数の勉強にもなります。
  
  前回,IPアドレスは、4*8ビットの形であらわされると書きました。
  この形式は,IPv4と呼ばれます.

  
  クラスA 始まりが,”0 ” で始まるものをいいます。

  クラスB 始まりが,”10 ” で始まるものをいいます。

  クラスC 始まりが,”110 ” で始まるものをいいます。

  また、それぞれのクラスには、予約されているものがあります.

  それは、IPネットワークアドレスの

  すべてが1または、0の場合です。

  クラスAならば、

     00000000.00000000.00000000.00000000 (0.0.0.0)

     01111111.00000000.00000000.00000000 (127.0.0.0)

     を除いた,16777214個が利用可能
    
  クラスBならば、

     10000000.00000000.00000000.00000000 (128.0.0.0)
  
     10111111.11111111.00000000.00000000 (191.255.0.0)
 
     を除いた,65534個が利用可能

    クラスCならば、

     11000000.00000000.00000000.00000000 (192.0.0.0)
  
     11011111.11111111.11111111.00000000 (223.255.255.0)

     を除いた,254個が利用可能

     となっています。

   また、いかにあげるブロードキャストもIPアドレスを知るには,

   必要なことです.

     ブロードキャスト
   
   IPアドレスのホスト部を割り当てるときに、やってはいけないこと。

    それは、ホスト部をすべて0または、1にすることです.

   ブロードキャストアドレスは,同一リンクに接続された全てのホストに

   パケットを送信するためのアドレスのため、このアドレスは使用しては

   いけません. また、全てのホスト部のビットが ”1”の場合、

   ブロードキャストになります.

   例をあげてみます.
   
   172.68.0.0/16 を二進数で表現すると,
  
   10101100.01000100.000000000.000000000
 
      となります.
    
   これから、ブロードキャストを作り出しますと,

   10101100.01000100.11111111.11111111 ( 172.68.255.255 )

      これが、ブロードキャストとなります. 

   と、ここまで着ましたが,次回へ持ち越させていただきます.

   おっと、172.68.0.0/16 の " /16 "について説明するのを

   忘れました.

   /16は、16ビット目からということです.

   それでは、
         
───────────────────────────────
  次回は,IPアドレスの問題を解決する方法

  クラスレス(CIDR( Classless Inter-Domain Routing ))

   および、もうひとつの解決法のIPv6について
     
    触れたいと思います.   
              
      
───────────────────────────────
    間違えなどを発見した方は,私宛にメールを下さい.
   次回に、訂正を載せたいと思います.
    また、この講座への意見・ご要望もお待ちしております.

    メール:<mailto:rain2000@geocities.co.jp>

───────────────────────────────
 
    ホームページ

  どうやら、ActiveXの署名がうまくいっているようです.
 実は,問題ありなのですが,ほんとはいけないことをやっています.
 テスト認証を使っています.ホントなら,年間8万円払わなければ
 いけません.
   
 追加:ダウンロードをHTML−HELPを使用したものに変更しました.
    以前の形より見やすくまた、使いやすくなりました.

───────────────────────────────
                   メルマガ収益

  毎回、コムズショップを載せています。
 利益還元率:電話加入   1000円
 でした。    
───────────────────────────────
┌─────────────────────────────┐

 電話加入権激安!ISDNライトなら9800円で電話が引ける!?(株)コムズ
 ↓詳しくはここをクリック!
 <http://www.comzz.co.jp/cgi-bin/cookie/set.cgi?t=top&id=2543>

└─────────────────────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                ●  メニュー  ●
    
  今回は、メニューについて触れていきます.
  以前に,行なったツールを使った方法でなく,
  プログラムを使って作成などを行ないます.

  関数などの説明は、サンプルのあとに乗せていきます。
 
┌─────────────────────────────┐
   では、まず ( WIN15.H )のソースです.
┌─────────────────────────────┐
     #define IDM_DATA1 103
     #define IDM_DATA2 104
     #define IDM_SET   105
     #define IDM_EXIT  106
     #define IDC_ADD   107
     #define IDM_OLDITEM  108

     #define IDM_NEWITEM 109
     #define IDM_SYSMENU1 110
     #define IDM_SYSMENU2 111

 
└─────────────────────────────┘  
───────────────────────────────
   リソースIDの説明
───────────────────────────────
     #define IDM_DATA1 103   メニューの操作
     #define IDM_DATA2 104  メニューの操作
     #define IDM_SET   105  メニューの操作
     #define IDM_EXIT  106  メニューの操作
     #define IDC_ADD   107  ボタンの操作
     #define IDM_OLDITEM  108  メニューの操作

     #define IDM_NEWITEM 109  追加メニュー
     #define IDM_SYSMENU1 110  追加システムメニュー1
     #define IDM_SYSMENU2 111  追加システムメニュー2
───────────────────────────────
       つぎに、( WIN15.RC ) のソースです. 
┌─────────────────────────────┐
     #include <windows.h>
     #include "win15.h"

     Win15Menu MENU DISCARDABLE
     BEGIN
          POPUP "&File"
          BEGIN
         MENUITEM "Set",IDM_SET
        MENUITEM "E&xit",IDM_EXIT
          END

          POPUP "&Data"
          BEGIN
       MENUITEM "Data &1",IDM_DATA1
        MENUITEM "Data &2",IDM_DATA2
          END           
     END

└─────────────────────────────┘  
───────────────────────────────
  ここでは、メニューを作成しています.
───────────────────────────────

───────────────────────────────

 次に,メインソースファイルです.

┌─────────────────────────────┐

     #include <windows.h>
     #include "win15.h"
     #undef WindowsName
     #define WindowsName "Windows"
     #undef WindowsMenu
     #define WindowsMenu "Win15Menu"

     HINSTANCE hInst;
     HWND hwndMain;
     HWND hButton;
     LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
     int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
     {
     WNDCLASSEX wc;
      RECT rect;
     
     wc.hInstance =hInstance;
      wc.lpszClassName=WindowsName;
     wc.lpszMenuName=WindowsMenu;
      wc.lpfnWndProc =WndProc;
wc.cbSize =sizeof(WNDCLASSEX);
     wc.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH);
      wc.cbClsExtra =0;
     wc.cbWndExtra =0;
      wc.hIcon =(HICON)LoadIcon(NULL,IDI_APPLICATION);
     wc.hCursor=(HCURSOR)LoadCursor(NULL,IDC_ARROW);
      wc.style =CS_HREDRAW|CS_VREDRAW;
     wc.hIconSm =NULL;

     if(!(ATOM)RegisterClassEx(&wc))
     {
     return 0;
      }

      rect.left=100;
     rect.top=150;
      rect.right =400;
     rect.bottom =400;
      AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW,(BOOL)TRUE);
     hwndMain=CreateWindow(WindowsName,WindowsName,WS_OVERLAPPEDWINDOW,
      rect.left ,rect.top ,rect.right ,rect.bottom ,NULL,NULL,hInstance,NULL);
     hButton=CreateWindow("BUTTON","メニュ-追加",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,50,250,200,50,
                  hwndMain,(HMENU)IDC_ADD,hInstance,NULL);

        
      if( hwndMain != NULL ) {
     ShowWindow( hwndMain, nCmdShow ) ;
      UpdateWindow( hwndMain ) ;
     }

      MSG msg;
     
     while(GetMessage(&msg,NULL,0,0))
      {
      TranslateMessage(&msg);
     DispatchMessage(&msg);
      }

      return msg.wParam;
     }

     LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
     {
     char buf[256];
      HDC hdc;
     switch (message)
      {
     case WM_CREATE:
      {
      SetWindowText(hwnd,"メニュー編");

      /* システムメニューに、項目を追加する. */
      //HMENU hSysMenu=GetSystemMenu(hwnd,TRUE);
      HMENU hSysMenu=GetSystemMenu(hwnd,FALSE);
     InsertMenu(hSysMenu,SC_MAXIMIZE,MF_BYCOMMAND|MFT_STRING,IDM_SYSMENU1,"&SysMoji1");
      InsertMenu(hSysMenu,SC_MINIMIZE,MF_BYCOMMAND|MFT_STRING,IDM_SYSMENU2,"&SysMoji2");
      }
     break;
      case WM_MOUSEMOVE:
     
      /*   指定された項目の名前 および 数を返す.*/
     {
      POINT pt;
     UINT uPos;
      char lpszState[256];
      int MenuNum;
      pt.x=(SHORT)LOWORD(lParam);
     pt.y=(SHORT)HIWORD(lParam);
      ClientToScreen(hwnd,&pt);
      uPos=MenuItemFromPoint(hwnd,GetMenu(hwnd),pt);
      MenuNum=GetMenuState(GetMenu(hwnd),IDM_EXIT,MF_BYCOMMAND);
      GetMenuString(GetMenu(hwnd),IDM_EXIT,lpszState,lstrlen(lpszState),MF_BYCOMMAND);
     hdc=GetDC(hwnd);
      wsprintf(buf,"項目数=%d 指定されたメニュー名=%s",MenuNum,lpszState);
      TextOut(hdc,00,200,buf,lstrlen(buf));
      ReleaseDC(hwnd,hdc);
      }     
      break;
      case WM_RBUTTONDOWN:
     
      /*   POPUP MENU を表示する. */
     {
      HMENU hMenuPop=CreatePopupMenu();
      POINT pt;
      AppendMenu(hMenuPop,MFT_STRING,IDM_SET,"&SET");
      AppendMenu(hMenuPop,MFT_STRING,IDM_EXIT,"&EXIT");
     AppendMenu(hMenuPop,MFT_STRING,IDM_DATA1,"DATA&1");
      AppendMenu(hMenuPop,MFT_STRING,IDM_DATA2,"DATA&2");
     
      pt.x=(SHORT)LOWORD(lParam);
      pt.y=(SHORT)HIWORD(lParam);
     
      /*   画面の相対座標に変換 */
      ClientToScreen(hwnd,&pt);
      TrackPopupMenu(hMenuPop,TPM_RIGHTBUTTON|TPM_TOPALIGN|TPM_LEFTALIGN,pt.x,pt.y,0,hwnd,NULL);
     DestroyMenu(hMenuPop);
      }
      break;
      case WM_COMMAND:
     switch(LOWORD(wParam))
      {
      /* ボタン操作 */
      case IDC_ADD:
      {
      HMENU hMenu;
     /* 下に追加 */
      //AppendMenu(GetMenu(hwnd),MFT_STRING | MFT_MENUBARBREAK|,120,"&New Item");
      /*   任意の位置に追加 */
      if (IsMenu(GetMenu(hwnd))){
     InsertMenu(GetMenu(hwnd),SC_MAXIMIZE,MF_BYPOSITION,120,"&New Item");
      wsprintf(buf,"追加した項目のメニューIDは、%dです。",GetMenuItemID(GetMenu(hwnd),120));
      hdc=GetDC(hwnd);
        TextOut(hdc,0,50,buf,lstrlen(buf));
     ReleaseDC(hwnd,hdc);
      DrawMenuBar(hwnd);
      }
      else //メニューが存在しないときに、メニューを追加
     {
      hMenu=CreateMenu();
      AppendMenu(hMenu,MFT_STRING,IDM_SET,"&SET");
      AppendMenu(hMenu,MFT_STRING,IDM_EXIT,"&EXIT");
      AppendMenu(hMenu,MFT_STRING,IDM_DATA1,"DATA&1");
     AppendMenu(hMenu,MFT_STRING,IDM_DATA2,"DATA&2");
           SetMenu(hwnd,hMenu);
      }
      }
     break;
      /*  メニュー操作  */
      case IDM_SET:
      /*   指定したメニューの属性を変化させる. */
      ModifyMenu(GetMenu(hwnd),IDM_SET,MF_BYCOMMAND | MFT_STRING ,IDM_NEWITEM,"&NewSET");
      DrawMenuBar(hwnd);
      break;
     case IDM_NEWITEM:
     /*  メニュー項目を消す.  */
      SetMenu(hwnd,NULL);
      break;
     case IDM_DATA1:
     /*  指定したメニュー項目を消す.  */
      if (RemoveMenu(GetMenu(hwnd),IDM_DATA2,MF_BYCOMMAND))
      {
      hdc=GetDC(hwnd);
      wsprintf(buf,"%s","Data2項目を消しました.");
     TextOut(hdc,0,100,buf,lstrlen(buf));
      ReleaseDC(hwnd,hdc);
      DrawMenuBar(hwnd);
      FlashWindow(hwnd,TRUE);
     }
      break;
      case IDM_DATA2:
      /*   メニューを無効化させる. */
     {
      BOOL bEnable;      
      bEnable=EnableMenuItem(GetMenu(hwnd),IDM_DATA2,MF_BYCOMMAND | MFS_ENABLED | MFS_GRAYED);
      hdc=GetDC(hwnd);
     wsprintf(buf,"%s","IDM_DATA2の無効化");
      TextOut(hdc,0,250,buf,lstrlen(buf));
      ReleaseDC(hwnd,hdc);
      }
      break;
      case IDM_EXIT:
      DestroyWindow(hwnd);
      break;
      default:
      break;
     }
      break;
      case WM_SYSCOMMAND:

      /*  システムメニューに対する操作 */
      switch(LOWORD(wParam))
      {
     case IDM_SYSMENU1:
      {
      RECT rect;
      GetClientRect(hwnd,&rect);
     wsprintf(buf,"%s","追加システムメニューが押されました.");
      hdc=GetDC(hwnd);
      DrawText(hdc,buf,lstrlen(buf),&rect,DT_LEFT);
      ReleaseDC(hwnd,hdc);
      }
      break;
      case IDM_SYSMENU2:
      MessageBox(hwnd,"追加メニュー","ボタンが押されました.",MB_OK);
      break;
     default:
      /*  上記の操作以外は,システムにまかせる。*/
      DefWindowProc(hwnd,message,wParam,lParam);
      break;
     }
      break;
     case WM_DESTROY:
     DestroyMenu(GetMenu(hwnd));
      PostQuitMessage(0);
      break;
      default:
      return DefWindowProc(hwnd,message,wParam,lParam);
      }
     return 0;

     }



┌─────────────────────────────┐

==== [ ▼おすすめ情報 ] ===============================================

★−★−★−★−★−★−★−★−★−★−★−★−★−★−★−★−★−★
│                ┏━┳━┳━┳━┳━┳━┓
★ こんな物まで買えちゃうサイト ┃夢 g e t 宝 島┃
│                ┗━┻━┻━┻━┻━┻━┛

│ 1.スイッチオンで半径3mの電波をカット!迷惑防止機です。

│ 2.片山右京MTBでアウトドアを満喫、ブラス製オウル像で運を呼ぶ。

│ 3.築地魚市場からトロ、特大サザエ他海の幸を厳選直送!

│ 『欲しいものがない?』『リクエスト受けます!』─┐
★                         │
│            進化するショッピングサイト▼
★─★─★                 http://216.71.100.246/a/a.cgi?k0960m0469 

============================================== [ ▲おすすめ情報 ] ====

    それでは、ソースの説明をしていきます.
──────────────────────────────
  今回のプログラムの説明
──────────────────────────────
  WinMain 部 のTOPIC
──────────────────────────────
rect.left=100;
rect.top=150;
rect.right =400;
rect.bottom =400;
AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW,(BOOL)TRUE);
hwndMain=CreateWindow(WindowsName,WindowsName,WS_OVERLAPPEDWINDOW,
rect.left ,rect.top ,rect.right ,rect.bottom ,NULL,NULL,hInstance,NULL);
hButton=CreateWindow("BUTTON","メニュ-追加",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,50,250,200,50,
             hwndMain,(HMENU)IDC_ADD,hInstance,NULL);
──────────────────────────────
  今回は,WinMainの部分にも,少し関数を加えました.

   AdjuctWindowRect関数を用いて,スタイルに従った
 領域の大きさを取得し,Windowを作成しています.
  また、ボタンをリソースから出なく、CreateWinodwを用いて
 作成を行なっています.
──────────────────────────────
     BOOL AdjustWindowRect(
       LPRECT lpRect,  
       DWORD dwStyle,  
       BOOL bMenu      
     );

     lpRect

          クライアント領域の左上と右下の座標が入った、RECT 構造体へのポインタを
          指定します。
          この構造体に、指定したクライアント領域に対応するウィンドウの
          左上と右下の座標が格納されます。

     dwStyle

          ウィンドウのスタイル (WS_OVERLAPPEDWINDOW など) を指定します。

     bMenu

          ウィンドウがメニューを持つかどうかを指定します。
          メニューを持つときは TRUE を、持たないときは FALSE を指定します。


──────────────────────────────
         変数宣言
──────────────────────────────
char buf[256];
HDC hdc;
──────────────────────────────
   文字取得用のバッファとデバイスコンテキストを確保しています.
 
──────────────────────────────
case WM_CREATE:
{
SetWindowText(hwnd,"メニュー編");

/* システムメニューに、項目を追加する. */
//HMENU hSysMenu=GetSystemMenu(hwnd,TRUE);
HMENU hSysMenu=GetSystemMenu(hwnd,FALSE);
InsertMenu(hSysMenu,SC_MAXIMIZE,MF_BYCOMMAND|MFT_STRING,IDM_SYSMENU1,"&SysMoji1");
InsertMenu(hSysMenu,SC_MINIMIZE,MF_BYCOMMAND|MFT_STRING,IDM_SYSMENU2,"&SysMoji2");
}
break;
──────────────────────────────
   ここでは、システムメニューを取得し、
 システムメニューに項目を追加しています.
──────────────────────────────
       HMENU GetSystemMenu(
       HWND hWnd,    
       BOOL bRevert  
     );
     パラメータ

     hWnd

     ウィンドウメニューのコピーを持つウィンドウのハンドルを指定します。

     bRevert

     関数の動作を指定します。
     FALSE を指定すると、この関数は、現在使用中のウィンドウメニューのコピーのハンドルを返します。
     TRUE を指定すると、この関数は、ウィンドウメニューをリセットして Windows のデフォルトの状態に戻します。
     以前のウィンドウメニューがある場合は破棄します。

     戻り値
     bRevert パラメータが FALSE のときは、ウィンドウメニューのコピーのハンドルが返ります。
     bRevert パラメータが TRUE のときは、NULL が返ります。

──────────────────────────────
      BOOL InsertMenu(
      HMENU hMenu,
      UINT uItem,
      UINT nFlags,
      UINT uID,
      LPCTSTR lpszNewItem
      );
     パラメータ

   hMenu:変更するメニューのハンドルを指定します.

   uItem:メニュー項目のIDまたは、位置を指定します.

   nFlags: MF_BYCOMMAND または、MF_BYPOSITION を指定します。

   uID   : メニューのリソースIDを指定します.

   lpszNewItem: メニューに表示される名前を指定します.
 
──────────────────────────────
case WM_MOUSEMOVE:

/*   指定された項目の名前 および 数を返す.*/
{
POINT pt;
UINT uPos;
char lpszState[256];
int MenuNum;
pt.x=(SHORT)LOWORD(lParam);
pt.y=(SHORT)HIWORD(lParam);
ClientToScreen(hwnd,&pt);
uPos=MenuItemFromPoint(hwnd,GetMenu(hwnd),pt);
MenuNum=GetMenuState(GetMenu(hwnd),IDM_EXIT,MF_BYCOMMAND);
GetMenuString(GetMenu(hwnd),IDM_EXIT,lpszState,lstrlen(lpszState),MF_BYCOMMAND);
hdc=GetDC(hwnd);
wsprintf(buf,"項目数=%d 指定されたメニュー名=%s",MenuNum,lpszState);
TextOut(hdc,00,200,buf,lstrlen(buf));
ReleaseDC(hwnd,hdc);
}
break;
──────────────────────────────
 指定したメニューの座標にマウスカーソルがきたときに,
 そのメニューの項目数 及びに メニュー名を表示しています。
──────────────────────────────
POINT pt;
──────────────────────────────
 POINT データ構造体は、次の形式です。

     typedef struct tagPOINT {
        LONG x;
        LONG y;
     } POINT;

     POINT 構造体は、点の x 座標と y 座標を定義します。


──────────────────────────────
pt.x=(SHORT)LOWORD(lParam);
pt.y=(SHORT)HIWORD(lParam);
ClientToScreen(hwnd,&pt);
──────────────────────────────
  ここでは、マウス座標の位置を取得し、
  取得した値を画面の相対座標に変換しています.
──────────────────────────────
     ClientToScreen
     クライアント座標で指定された点の座標を、スクリーン座標に変換します。

     BOOL ClientToScreen(
       HWND hWnd,         
       LPPOINT lpPoint   
     );

     パラメータ
     hWnd

     ウィンドウのハンドルを指定します。このウィンドウのクライアント座標が変換に利用されます。

     lpPoint

     変換されるクライアント座標が入った、POINT 構造体へのポインタを指定します。
     関数が成功すると、この構造体にスクリーン座標が格納されます。

     戻り値
     関数が成功すると、0 以外の値が返ります。
     関数が失敗すると、0 が返ります。


──────────────────────────────
uPos=MenuItemFromPoint(hwnd,GetMenu(hwnd),pt);
MenuNum=GetMenuState(GetMenu(hwnd),IDM_EXIT,MF_BYCOMMAND);
GetMenuString(GetMenu(hwnd),IDM_EXIT,lpszState,lstrlen(lpszState),MF_BYCOMMAND);
──────────────────────────────
  ここでは、指定した位置にあるメニューの値を取得しています.
──────────────────────────────

  指定されたメニューと指定された座標から、その座標を含むメニュー項目を取得します。

     UINT WINAPI MenuItemFromPoint(
        HWND hWnd,   // メニューを持つウィンドウのハンドル
        HMENU hMenu,   // メニューのハンドル
        POINT ptScreen   // 調査する座標
     );
     パラメータ
     hWnd

     メニューを持つウィンドウのハンドルを指定します。

     hMenu

     メニューのハンドルを指定します。このメニューが調査されます。

     ptScreen

     調査する座標を入れたPOINT構造体を指定します。

     戻り値
     指定した座標にあるメニュー項目の位置が、最初のメニュー項目を0とするオフセットで返ります。
     指定した位置にメニュー項目がなかったときは、-1が返ります。


──────────────────────────────
UINT GetMenuState(
             HMENU hMenu,
             UINT uItem,
             UINT uFlags);
      
      パラメータ
    
   hMenu
 メニューのハンドルを指定します。
        
      uItem
     メニュー項目のIDまたは、位置を指定します.

    uFlags:
          MF_BYCOMMAND または、MF_BYPOSITION を指定します。

──────────────────────────────
     int GetMenuString(
       HMENU hMenu,      
       UINT uIDItem,     
       LPTSTR lpString,  
       int nMaxCount,    
       UINT uFlag        
     );
     パラメータ
     hMenu

     メニューのハンドルを指定します。

     uIDItem

     情報を取得するメニュー項目の ID (または位置) を指定します。

     lpString

     テキスト (またはタイトル) 受け取るバッファへのポインタを指定します。

     nMaxCount

     lpString パラメータがポイントするバッファが受け入れる最大文字数を指定します (終端の NULL を含む)。
     文字列の長さがこの最大値よりも長い場合は、切り詰められます。
     0 を指定すると、この関数はメニュー文字列の長さを返します。
     lpString パラメータで指定したバッファには、テキストは書き込まれません 
     (したがって、lpString パラメータに NULL を指定しても構いません)。

     uFlag

     uIDItem パラメータの意味を指定します。次の値のいずれかを指定します。


──────────────────────────────
case WM_RBUTTONDOWN:

/*   POPUP MENU を表示する. */
{
HMENU hMenuPop=CreatePopupMenu();
POINT pt;
AppendMenu(hMenuPop,MFT_STRING,IDM_SET,"&SET");
AppendMenu(hMenuPop,MFT_STRING,IDM_EXIT,"&EXIT");
AppendMenu(hMenuPop,MFT_STRING,IDM_DATA1,"DATA&1");
AppendMenu(hMenuPop,MFT_STRING,IDM_DATA2,"DATA&2");
  /* マウスの座標を取得 */       
pt.x=(SHORT)LOWORD(lParam);
pt.y=(SHORT)HIWORD(lParam);

/*   画面の相対座標に変換 */
ClientToScreen(hwnd,&pt);
TrackPopupMenu(hMenuPop,TPM_RIGHTBUTTON|TPM_TOPALIGN|TPM_LEFTALIGN,pt.x,pt.y,0,hwnd,NULL);
DestroyMenu(hMenuPop);
}
break;
──────────────────────────────
   ここでは、ポップアップメニューを作成しています.
  また、マウスカーソルの位置に出現させています.
──────────────────────────────
HMENU hMenuPop=CreatePopupMenu();
──────────────────────────────
     ドロップダウンメニュー、サブメニュー、ショートカットメニューを作成します。
     メニューは初期状態では空ですが、InsertMenuItem 関数などを使用してメニュー項目を
     追加 (または挿入) することができます。

     HMENU CreatePopupMenu(VOID)
     パラメータ
     パラメータはありません。

     戻り値
     関数が成功すると、新しく作成されたメニューのハンドルが返ります。関数が失敗すると、NULL が返ります。

──────────────────────────────
AppendMenu(hMenuPop,MFT_STRING,IDM_SET,"&SET");
──────────────────────────────
  BOOL AppendMenu(
            HMENU hMenu,
            UINT uFlags,
            UINT idNewItem,
            LPCTSTR lpszNewItem
          );

  パラメータ

            HMENU hMenu,
                メニューのハンドルを指定します。

            UINT uFlags,
        形式を指定します.

            UINT idNewItem,
                メニュー項目の ID (または位置) を指定します。

            LPCTSTR lpszNewItem
                メニュの名前を指定します.

──────────────────────────────
    TrackPopupMenu(hMenuPop,TPM_RIGHTBUTTON|TPM_TOPALIGN|TPM_LEFTALIGN,pt.x,pt.y,0,hwnd,NULL);
──────────────────────────────
     指定された位置にショートカットメニューを表示します。
     また、メニュー項目の選択に関する処理も行ないます。ショートカットメニューは、画面上のどこにでも表示できます。

     BOOL TrackPopupMenu(
       HMENU hMenu,  
       UINT uFlags,  
       int x,        
       int y,        
       int nReserved,
                
       HWND hWnd,    
       CONST RECT *prcRect
                
     );

 詳しくは,MSDNをご参照ください.
──────────────────────────────

    DestroyMenu(hMenuPop);
──────────────────────────────
     定されたメニューを破棄し、メニュー用に使われていたメモリを解放します。
     
     BOOL DestroyMenu(
       HMENU hMenu  // handle to menu to destroy
     );
     パラメータ
     hMenu

     破棄するメニューのハンドルを指定します。

     戻り値
     関数が成功すると、0 以外の値が返ります。
     関数が失敗すると、0 が返ります。拡張エラー情報を取得するには、GetLastError 関数を使います

──────────────────────────────

case WM_COMMAND:
switch(LOWORD(wParam))
{
/* ボタン操作 */
case IDC_ADD:
{
HMENU hMenu;
/* 下に追加 */
//AppendMenu(GetMenu(hwnd),MFT_STRING | MFT_MENUBARBREAK|,120,"&New Item");
/*   任意の位置に追加 */
if (IsMenu(GetMenu(hwnd))){
InsertMenu(GetMenu(hwnd),SC_MAXIMIZE,MF_BYPOSITION,120,"&New Item");
wsprintf(buf,"追加した項目のメニューIDは、%dです。",GetMenuItemID(GetMenu(hwnd),120));
hdc=GetDC(hwnd);
TextOut(hdc,0,50,buf,lstrlen(buf));
ReleaseDC(hwnd,hdc);
DrawMenuBar(hwnd);
}
else //メニューが存在しないときに、メニューを追加
{
hMenu=CreateMenu();
AppendMenu(hMenu,MFT_STRING,IDM_SET,"&SET");
AppendMenu(hMenu,MFT_STRING,IDM_EXIT,"&EXIT");
AppendMenu(hMenu,MFT_STRING,IDM_DATA1,"DATA&1");
AppendMenu(hMenu,MFT_STRING,IDM_DATA2,"DATA&2");
SetMenu(hwnd,hMenu);
}
}
break;
──────────────────────────────
  ここでは、ボタンを押したときに、
   メニューが存在する場合,新規にメニュー項目を追加しています.

   メニューが存在しない場合,メニューを作成し,表示を行なっています.
──────────────────────────────
        GetMenu(HWND hwnd)
──────────────────────────────
     指定されたウィンドウに割り当てられたメニューのハンドルを取得します

     HMENU GetMenu(
       HWND hWnd  // handle to window
     );
     パラメータ
     hWnd

     メニューを持つウィンドウのハンドルを指定します。

     戻り値
     関数が成功すると、メニューのハンドルが返ります。
     指定したウィンドウがメニューを持たないときは、NULL が返ります。
     指定したウィンドウが子ウィンドウのときの戻り値は、未定義です。


──────────────────────────────
IsMenu(GetMenu(hwnd))
──────────────────────────────
     指定されたハンドルがメニューハンドルであるかどうかを調べます。

     BOOL IsMenu(
        HMENU hMenu   // 調査するハンドル
     );
     パラメータ
     hMenu

     調査するハンドルを指定します。

     戻り値
     指定したハンドルがメニューハンドルのときは、0以外の値が返ります。
     指定したハンドルがメニューハンドルでなかったときは、0が返ります。

──────────────────────────────

DrawMenuBar(hwnd);
──────────────────────────────
     ウィンドウのメニューバーを再描画します。メニューバーを変更したときは、
     この関数を呼び出してメニューバーを再描画しなければなりません。

     BOOL DrawMenuBar(
       HWND hWnd  // handle to window with menu bar to redraw
     );
     パラメータ
     hWnd

     メニューバーの再描画をするウィンドウのハンドルを指定します。

     戻り値
     関数が成功すると、0 以外の値が返ります。
     関数が失敗すると、0 が返ります。拡張エラー情報を取得するには、GetLastError 関数を使います。


──────────────────────────────
hMenu=CreateMenu();
──────────────────────────────
     メニューを作成します。メニューは初期状態では空ですが、
     InsertMenuItem 関数などを使用してメニュー項目を追加 (または挿入) することができます。

     HMENU CreateMenu(VOID)
     パラメータ
     パラメータはありません。

     戻り値
     関数が成功すると、新しく作成されたメニューのハンドルが返ります。関数が失敗すると、NULL が返ります。


──────────────────────────────
SetMenu(hwnd,hMenu);
──────────────────────────────
     指定されたウィンドウに、新しいメニューを割り当てます。

     BOOL SetMenu(
       HWND hWnd,  // handle to window
       HMENU hMenu // handle to menu
     );
     パラメータ
     hWnd

     メニューを割り当てるウィンドウのハンドルを指定します。

     hMenu

     新しいメニューのハンドルを指定します。NULL を指定すると、メニューが除去されます。

     戻り値
     関数が成功すると、0 以外の値が返ります。
     関数が失敗すると、0 が返ります。拡張エラー情報を取得するには、GetLastError 関数を使います。


──────────────────────────────
case IDM_SET:
/*   指定したメニューの属性を変化させる. */
ModifyMenu(GetMenu(hwnd),IDM_SET,MF_BYCOMMAND | MFT_STRING ,IDM_NEWITEM,"&NewSET");
DrawMenuBar(hwnd);
break;
──────────────────────────────
   ここでは、メニューの名前を変えています.
  また、メニューを強制的に再描画しています。
──────────────────────────────
ModifyMenu(GetMenu(hwnd),IDM_SET,MF_BYCOMMAND | MFT_STRING ,IDM_NEWITEM,"&NewSET");
──────────────────────────────
   BOOL ModifyMenu(
          HMENU hMenu,
          UINT uItem,
          UINT uFlags,
          UINT uNewItem,
          LPCTSTR lpszNewName 
        );

     パラメータ
   hMenu
        メニューハンドルを指定。
   
      uItem
        変更させるリソースIDを指定。 
   
   uFlags
        フラグの指定.他の関数と同様.
   
   uNewItem
        新規のリソースIDを指定
  
   lpszNewName
        新規のめにゅー名を指定.

──────────────────────────────
case IDM_NEWITEM:
/*  メニュー項目を消す.  */
SetMenu(hwnd,NULL);
break;
──────────────────────────────
    ここでは、メニューを非表示にしています.
──────────────────────────────
case IDM_DATA1:
/*  指定したメニュー項目を消す.  */
if (RemoveMenu(GetMenu(hwnd),IDM_DATA2,MF_BYCOMMAND))
{
hdc=GetDC(hwnd);
wsprintf(buf,"%s","Data2項目を消しました.");
TextOut(hdc,0,100,buf,lstrlen(buf));
ReleaseDC(hwnd,hdc);
DrawMenuBar(hwnd);
FlashWindow(hwnd,TRUE);
}
break;
──────────────────────────────
      ここでは、指定したメニュー項目をさくじょしています。
   また、そのときに、ウィンドウをフラッシュさせています.
──────────────────────────────
     RemoveMenu(GetMenu(hwnd),IDM_DATA2,MF_BYCOMMAND)
──────────────────────────────
     メニューからメニュー項目を削除します。
     メニュー項目がドロップダウンメニューやサブメニューを開く場合、
     それらのメニューやそのハンドルは削除しません。
     したがって、メニューを再利用することができます。
     再利用する場合は、この関数を使用する前に、GetSubMenu 関数を使って
     ドロップダウンメニューやサブメニューのハンドルを取得しておいてください。

     BOOL RemoveMenu(
       HMENU hMenu,     // handle to menu
       UINT uPosition,  // menu item identifier or position
       UINT uFlags      // menu item flag
     );
     パラメータ
     hMenu

     メニューのハンドルを指定します。

     uPosition

     削除するメニュー項目の ID (または位置) を指定します。

     uFlags

     uPosition パラメータの意味を指定します。次の値のいずれかを指定します。


──────────────────────────────
FlashWindow(hwnd,TRUE);
──────────────────────────────
     指定されたウィンドウのタイトルバーを点滅させます。

     BOOL FlashWindow(
       HWND hWnd,     // handle to window to flash
       BOOL bInvert   // flash status
     );
     パラメータ
     hWnd

     点滅させるウィンドウのハンドルを指定します。

     bInvert

     ウィンドウを点滅状態を変化させるか、元の状態に戻すかを指定します。
     TRUE を指定すると、タイトルバーの点滅状態が変化します 
     (オンのときはオフになり、オフのときはオンになります)。
     FALSE を指定すると、元の状態に戻ります。

     戻り値
     FlashWindow 関数を呼び出す前の点滅状態が返ります。
     アクティブなウィンドウと同じ表示状態のときは、0 以外の値が返ります。
     非アクティブなウィンドウと同じ表示状態のときは、0 が返ります。

──────────────────────────────
case IDM_DATA2:
/*   メニューを無効化させる. */
{
BOOL bEnable;      
bEnable=EnableMenuItem(GetMenu(hwnd),IDM_DATA2,MF_BYCOMMAND | MFS_ENABLED | MFS_GRAYED);
hdc=GetDC(hwnd);
wsprintf(buf,"%s","IDM_DATA2の無効化");
TextOut(hdc,0,250,buf,lstrlen(buf));
ReleaseDC(hwnd,hdc);
}
break;
──────────────────────────────
    ここでは、指定したメニューをEnable化しています。
──────────────────────────────
    bEnable=EnableMenuItem(GetMenu(hwnd),IDM_DATA2,MF_BYCOMMAND | MFS_ENABLED | MFS_GRAYED);
──────────────────────────────
     メニュー項目を有効化、無効化、または淡色表示にします。

     BOOL EnableMenuItem(
       HMENU hMenu,         // handle to menu
       UINT uIDEnableItem,  // menu item to enable, disable, or gray
       UINT uEnable         // menu item flags
     );
     パラメータ
     hMenu

     メニューのハンドルを指定します。

     uIDEnableItem

     有効化、無効化、または淡色表示にするメニュー項目の ID (または位置) を指定します。
     メニューバー、メニュー、サブメニュー内の項目を指定します。

     uEnable

     uIDEnableItem パラメータの意味と、メニュー項目の新しい状態を指定します。


──────────────────────────────
case IDM_EXIT:
DestroyWindow(hwnd);
break;
default:
break;
}
break;
──────────────────────────────
    終了処理をかけています.
──────────────────────────────
case WM_SYSCOMMAND:

/*  システムメニューに対する操作 */
switch(LOWORD(wParam))
{
case IDM_SYSMENU1:
{
RECT rect;
GetClientRect(hwnd,&rect);
wsprintf(buf,"%s","追加システムメニューが押されました.");
hdc=GetDC(hwnd);
DrawText(hdc,buf,lstrlen(buf),&rect,DT_LEFT);
ReleaseDC(hwnd,hdc);
}
break;
──────────────────────────────
  ここでは、追加したシステムメニューを押すことにより
   現在の座標に対して中央に文字を表示しています.
──────────────────────────────
GetClientRect(hwnd,&rect);
──────────────────────────────
     ウィンドウのクライアント領域の左上隅と右下隅の座標を、
     クライアント座標で取得します。
     クライアント座標はクライアント領域の左上隅からの相対座標なので、
     左上隅の座標は常に (0,0) となります。

     BOOL GetClientRect(
       HWND hWnd,      // handle to window
       LPRECT lpRect   // address of structure for client coordinates
     );
     パラメータ
     hWnd

     クライアント領域の座標を取得するウィンドウのハンドルを指定します。

     lpRect

     RECT 構造体へのポインタを指定します。
     この構造体に、クライアント領域の座標が格納されます。
     left メンバと top メンバは 0 になります。right メンバと bottom メンバは、
     クライアント領域の幅と高さになります。

     戻り値
     関数が成功すると、0 以外の値が返ります。
     関数が失敗すると、0 が返ります。拡張エラー情報を取得するには、GetLastError 関数を使います

──────────────────────────────
case IDM_SYSMENU2:
MessageBox(hwnd,"追加メニュー","ボタンが押されました.",MB_OK);
break;
default:
          /*  上記の操作以外は,システムにまかせる。*/
DefWindowProc(hwnd,message,wParam,lParam);
break;
}
break;
──────────────────────────────
    ここでは、システム任せの動作を行なっています.

──────────────────────────────
   今回,古いバージョンの関数も使用しています.
  できるだけ,新しいバージョンの関数を使用したほうが. 
  事実上安心です.

   次回は,新しいバージョンの関数を用いて以下のことにも
 触れながら進めていきます.
  
  それでは、次回は今回掲載できなかったアクセラレーターキー
 の使用について触れていきます.

──────────────────────────────

  NEW!! 、ソースファイル類を私のページの
 メールマガジンバックナンバーからダウンロードできるように
 しました.

 それでは。

└─────────────────────────────┘  

なお、以上のプログラムは、私の動作環境VC++6.0 Win32 Application
で確認済みです.

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
 メールアドレス:<mailto:rain2000@geocities.co.jp>
 ホームページ :<http://www.geocities.co.jp/SiliconValley-Bay/3125>

 発行者:rain2000
 編集 :rain2000

 このメールマガジンは,以下の発行者さんを通して発行してます.

 ●まぐまぐ:
  アドレス : http://www.mag2.com/
 ID    : 0000024922

 ●クリックインカム:
 アドレス :http://clickincome.net/
 ID    : m00002885

 ●Pubzine 
 アドレス :Pubzine (http://www.pubzine.com/)
 ID    :004293

  ●ここでメール
 アドレス : http://mail.cocode.ne.jp/
 ID    : 0400100071

 ●メルマガ天国
 アドレス : http://melten.com/
 ID    : 300

 ●E-magazine 
 アドレス :http://www.emaga.com/
 ID    :cwindows

 ●Macky   
 アドレス : http://macky.nifty.ne.jp/
 ID    : 2329

  ●カプライト  
 アドレス : http://kapu.cplaza.ne.jp/ 
 ID    : 234

 また、登録解除などの手続きに関しましては,上記の  
  ホームにてお願いします.

  私宛にメールをいただいても、解除はおよび登録は
 いたしません.
 

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

==== [ ▼PR ] ========================================================


■…∽…■…∽…■…∽…■…∽…■…∽…■…∽…■…∽…■…∽…■…∽
§ トレイダーズ証券のオンライン外国為替取引「ネットフォレックス」。
■ 売買単位10万ドルに対して、取引コスト1ドルあたり10銭、
§ 最低預託金200万円という低コストが魅力です。
■ 詳しくはこちら: http://216.71.100.246/a/a.cgi?k0980m0469 


==== [ ▼PR ] ========================================================


◆ travelsquare ◆ 海外旅行は【トラベルスクエア】 ◆  travelsquare  ◆
             http://216.71.100.246/a/a.cgi?k0985m0469 
◆(( まだ間に合う!9月の海外旅行 激安パッケージはこれだ )))◆
◆    羽田からラクラク・ハワイ6日間! ¥59,800〜    ◆
◆ なんと10日間でこの値段! ペナン島でバカンス¥59,800〜 ◆


==== [ ▼PR ] ========================================================


■〓〓【保険料を毎月4万円 年間48万円 30年で 1440万円 】〓■
◇      この30年で、買えるものは、家か車か安心か?
■   保険スクエアbang!が【生命保険】の選び方を提案します!
◇     知らない人も知っている人も、保険スクエアbang!
■【詳しくはココ】⇒ http://216.71.100.246/a/a.cgi?k0801m0469 


==== [ ▼PR ] ========================================================


■■今までになかった新しい求職・求人サービス![アクティブウェブ]■■
日本初の本格的求職広告(匿名無料)でお仕事探しを応援します!応募はもち
ろん、企業からの勧誘が受けられる双方向の新サービス!ホームページと無料
メルマガのダブル広告で効果大!転職、就職、SOHO、契約、派遣等もOK
求人広告も多数。★★ < http://216.71.100.246/a/a.cgi?k0325m0469 > ★★

==== [ ▼PR ] ========================================================


☆★☆★☆★☆★☆★ 急な出費でお困りのあなた! ★☆★☆★☆★☆★☆
“NOLOAN”なら一週間以内は無利息です!例えば月曜に借りて、次の週
の月曜に返せば利息はいただきません!しかも手数料も無料!いつでも、どこ
でも、何度でも御利用いただけます
今すぐGO→ http://216.71.100.246/a/a.cgi?k0825m0469 


==== [ ▼PR ] ========================================================

ブラウザの閉じるボタンで閉じてください。