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


----------------------------------------------------------------------
┏━┓┏━┓┏━┓┏━┓┏━┓┏━┓ ┏━━━━━━━━━━━━━━┓
┃ネ┃┃ッ┃┃ト┃┃で┃┃投┃┃信┃⇔┃大和投資信託《ネットレード》┃
┗━┛┗━┛┗━┛┗━┛┗━┛┗━┛ ┗━━━━━━━━━━━━━━┛
          充実の商品情報・マーケット情報!
   ⇒⇒⇒ http://www.daiwa-am.co.jp/cgi-bin/inquiry.cgi?aqz1
----------------------------------------------------------------------

発行部数: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(Menu 2回編)   


└─────────────────────────────┘
   さて、Winndows編もはや16回に突入しました.

  前回あまりにも、容量が多すぎたため
  制限を越えた配送となりました.
  そのため、二つに分けることとなりました.

  通信関連 および プログラミング関連 

  こうすることにより,どちらかがそろわなければ
  配信できないということもなくなり,
  こちらの負担も見る読者の方の負担も
  少なくなるとおもいます。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-//    PR//-=-=
■三和銀行の「家持つぞ大作戦2000」ただいま参加者募集中!!(参加費無料)
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
参加者だけのうれしい優遇金利をご用意。今すぐ、下のアドレスをクリック!
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
くわしくは…  http://www.sanwabank.co.jp/meta/iemotsuzo/melmel.html
=-=-//000184-00637//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
┌─────────────────────────────┐

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

└─────────────────────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                ●   文字処理 2回 ●
    
  今回は、文字処理 2回 について触れていきます.
  関数などの説明は、サンプルのあとに乗せていきます。
 
┌─────────────────────────────┐
   では、まず ( WIN16.H )のソースです.
┌─────────────────────────────┐
     #define IDM_EXIT  106
     #define IDC_ADD   107
     #define IDM_MENU_VERSION1 112
     #define IDM_MENU_VERSION2 113
     #define IDM_NEW_MENU 300

└─────────────────────────────┘  
       つぎに、( WIN16.RC ) のソースです. 
┌─────────────────────────────┐
     #include <windows.h>
     #include "win16.h"

     Win16Menu MENU DISCARDABLE
     BEGIN
          POPUP "&File"
          BEGIN
        MENUITEM "E&xit",IDM_EXIT
          END

     END

     STRINGTABLE
     BEGIN 
     IDM_MENU_VERSION1 "追加メニュ"
           IDM_MENU_VERSION2 "さらに追加"
     END
└─────────────────────────────┘  
───────────────────────────────

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

┌─────────────────────────────┐
     #include <windows.h>
     #include"win16.h"

     #undef WindowsName
     #define WindowsName "Windows"
     #undef WindowsMenu
     #define WindowsMenu "Win16Menu"

     HINSTANCE hInst;
     HWND hwndMain;
     HWND hButton;

     HACCEL hMainAccel=NULL;
     void AccelatorKey(HWND hwnd);
     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))
     {
     /* アクセラレータキー エラー回避 */
      if (!hMainAccel || !TranslateAccelerator(hwndMain,hMainAccel,&msg))
      {
     TranslateMessage(&msg);
      DispatchMessage(&msg);
      }
      }

      return msg.wParam;
     }

     LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
     {

      switch (message)
     {
      case WM_CREATE:
      {
      SetWindowText(hwnd,"アクセラレータ編");
      }
      break;
      case WM_COMMAND:
      switch(LOWORD(wParam))
     {
      case IDC_ADD:
      AccelatorKey(hwnd);
      break;
      case IDM_NEW_MENU:
      MessageBox(hwnd,"追加メニュー1","選択",MB_OK|MB_ICONINFORMATION);
      break;
      case IDM_NEW_MENU+1:
      OutputDebugString("追加メニュー2");
      break;
      case IDM_EXIT:
      DestroyWindow(hwnd);
     }
      break;
     case WM_DESTROY:
      DestroyMenu(GetMenu(hwnd));
      PostQuitMessage(0);
     break;
      default:
      return DefWindowProc(hwnd,message,wParam,lParam);
      }
     return 0;

     }

     void AccelatorKey(HWND hwnd)
     {

      ACCEL* pAccel=NULL; /* アクセラレータ         コピー使用 */
       ACCEL* pCurrentAccel=NULL; /* アクセラレータテーブル メイン     */
      HACCEL hAccel=NULL; /* アクセラレータハンドル 作成用 */
     
       MENUITEMINFO menuiteminfo; /* メニューアイテム構造体 */
      char strmenu[256]; /* メニュー文字列バッファ */
     int numAccel=1;
     static int maxAccel=0; /* アクセラレータキーの最大数を定義 */

     /* 2個まで追加する。それ以上はクリア */
      if (maxAccel==2)
      return;

     /* アクセラレータテーブルの項目数を取得 */
      if(hMainAccel)
     {
      numAccel=CopyAcceleratorTable(hMainAccel,NULL,0)+1;
      }

      /* アクセラレータテーブル構造体の配列の割り当て */
     hAccel=(HACCEL )GlobalAlloc(GHND,sizeof(ACCEL)*numAccel);
      /* アクセラレータハンドルのロック */
     if(hAccel)
     pAccel=(ACCEL*)GlobalLock(hAccel);

      /* アクセラレータテーブルのコピー*/
     if (hAccel && pAccel)
      {
      CopyAcceleratorTable(hMainAccel,pAccel,numAccel-1);
      DestroyAcceleratorTable(hMainAccel);
      hMainAccel=NULL;
      }

      if(pAccel)
     {
     /* 現在のアクセラレータテーブル */
      pCurrentAccel=(ACCEL*)(pAccel+numAccel-1);

      maxAccel++;
     /* メニューアイテム構造体への値の割り当て */
      ZeroMemory(&menuiteminfo, sizeof(menuiteminfo));
     menuiteminfo.cbSize = sizeof(menuiteminfo);
      menuiteminfo.fMask = MIIM_ID | MIIM_STATE | MIIM_TYPE;
     menuiteminfo.fType = MFT_STRING;
      menuiteminfo.fState = MFS_ENABLED;
     menuiteminfo.wID = IDM_NEW_MENU+maxAccel-1;

      /*  ストリングテーブルから文字列を取得する. */
     LoadString(hInst, IDM_MENU_VERSION1+maxAccel-1, strmenu, sizeof(strmenu));
      menuiteminfo.dwTypeData = (LPSTR)strmenu;
     /* メニューを追加する. */
      InsertMenuItem(GetMenu(hwnd),IDM_EXIT,FALSE,&menuiteminfo);

      /* セパレータを足す */
     ZeroMemory(&menuiteminfo, sizeof(menuiteminfo));
           menuiteminfo.cbSize = sizeof(menuiteminfo);
     menuiteminfo.fMask = MIIM_TYPE;
           menuiteminfo.fType = MFT_SEPARATOR;
           InsertMenuItem(GetMenu(hwnd), IDM_EXIT, FALSE, &menuiteminfo);
     
     /*  メニューの再描画を行なう.*/
      DrawMenuBar(hwnd);

      /* アクセル構造体の取得 */
      pCurrentAccel->cmd=IDM_NEW_MENU+maxAccel-1;
     pCurrentAccel->fVirt =FNOINVERT|FVIRTKEY;
      pCurrentAccel->key=VK_F1;

      /* アクセラレータテーブルの作成 */
      hMainAccel=CreateAcceleratorTable(pCurrentAccel,numAccel);
     
      /* アクセラレータハンドルのアンロック */
     GlobalUnlock(hAccel);


      }
      /* アクセラレータハンドルのメモリ解放 */
     if(hAccel)
      GlobalFree(hAccel);

     }

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


    それでは、ソースの説明をしていきます.
──────────────────────────────
  今回のプログラムの説明
──────────────────────────────
──────────────────────────────
         前方参照
──────────────────────────────
          void AccelatorKey(HWND hwnd);
──────────────────────────────
   ここでは、自作関数を宣言しています.
──────────────────────────────
         変数宣言
──────────────────────────────
グローバール部
──────────────────────────────
HACCEL hMainAccel;
──────────────────────────────

 ここでは、全体のアクセラレータテーブルを格納するための
 ハンドルを宣言しています.
──────────────────────────────
AccelatorKey関数内部
──────────────────────────────
      ACCEL* pAccel=NULL; /* アクセラレータ         コピー使用 */
       ACCEL* pCurrentAccel=NULL; /* アクセラレータテーブル メイン     */
      HACCEL hAccel=NULL; /* アクセラレータハンドル 作成用 */
     
       MENUITEMINFO menuiteminfo; /* メニューアイテム構造体 */
      char strmenu[256]; /* メニュー文字列バッファ */
int numAccel=1;
static int maxAccel=0; /* アクセラレータキーの最大数を定義 */

──────────────────────────────
  コメントを参照ください。
──────────────────────────────
     /* 2個まで追加する。それ以上はクリア */
      if (maxAccel==2)
      return;


──────────────────────────────
  アクセラレータキーの追加数を2個までに指定。
──────────────────────────────
     /* アクセラレータテーブルの項目数を取得 */
      if(hMainAccel)
     {
      numAccel=CopyAcceleratorTable(hMainAccel,NULL,0)+1;
      }
──────────────────────────────
  ここでは、アクセラレータテーブルの項目数を取得しています.
──────────────────────────────
    以下の説明から、lpAccelDst がNULLのときは,
  項目数を返します.
──────────────────────────────
CopyAcceleratorTable
指定されたアクセラレータテーブルをコピーします。
この関数は、アクセラレータテーブルハンドルに対応するアクセラレータテーブルデータを
取得するため、またはアクセラレータテーブルのサイズを調べるために使われます。

int CopyAcceleratorTable(
  HACCEL hAccelSrc,   // コピーするアクセラレータテーブルのハンドル
  LPACCEL lpAccelDst, // コピーを受け取る構造体へのポインタ
  int cAccelEntries   // コピーするテーブル内のエントリ数
);
パラメータ
hAccelSrc

コピーするアクセラレータテーブルのハンドルを指定します。

lpAccelDst

アクセラレータテーブル情報がコピーされる ACCEL 構造体の配列へのポインタを指定します。

cAccelEntries

lpAccelDst パラメータで指定されるバッファへコピーする ACCEL 構造体の数を指定します。

戻り値
lpAccelDst パラメータが NULL の場合、元のアクセラレータテーブルのエントリ数が戻ります。
そうでない場合、コピーされたアクセラレータテーブルのエントリ数が返ります。


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

      /* アクセラレータテーブル構造体の配列の割り当て */
     hAccel=(HACCEL )GlobalAlloc(GHND,sizeof(ACCEL)*numAccel);
──────────────────────────────
ヒープから指定されたバイト数のメモリを確保します。
Win32 環境では、グローバルヒープとローカルヒープの区別はありません。

HGLOBAL GlobalAlloc(
  UINT uFlags,    //  allocation attributes
  DWORD dwBytes   //  number of bytes to allocate
);
GHND GMEM_MOVEABLE フラグと GMEM_ZEROINIT フラグとの組み合わせです。 

詳しくは、MSDNをご参照ください.
──────────────────────────────
      /* アクセラレータハンドルのロック */
     if(hAccel)
     pAccel=(ACCEL*)GlobalLock(hAccel);
──────────────────────────────
GlobalLock
グローバルメモリオブジェクトをロックし、メモリブロックの先頭へのポインタを返します。

LPVOID GlobalLock(
  HGLOBAL hMem   //  handle to the global memory object
);
パラメータ
hMem

グローバルメモリオブジェクトのハンドルを指定します。
GlobalAlloc 関数または GlobalReAlloc 関数が、このハンドルを返します。

戻り値
関数が成功すると、メモリブロックの先頭へのポインタが返ります。
関数が失敗すると、NULL が返ります。拡張エラー情報を取得するには、GetLastError 関数を使います。

解説
メモリオブジェクトのロックカウントの初期値は 0 です。
GlobalLock 関数はロックカウントを 1 増やし、GlobalUnlock 関数はロックカウントを 1 減らします。
ただし、GMEM_FIXED フラグを指定して確保したメモリオブジェクトのロックカウントは、常に 0 です。

ロックカウントを取得するには、GlobalFlags 関数を使います。


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

      /* アクセラレータテーブルのコピー*/
     if (hAccel && pAccel)
      {
      CopyAcceleratorTable(hMainAccel,pAccel,numAccel-1);
      DestroyAcceleratorTable(hMainAccel);
      hMainAccel=NULL;
      }


──────────────────────────────
DestroyAcceleratorTable
アクセラレータテーブルを破棄します。
アプリケーションを閉じる前に、この関数を使って CreateAcceleratorTable 関数で
作成したアクセラレータテーブルを破棄してください。

BOOL DestroyAcceleratorTable(
  HACCEL hAccel   // アクセラレータテーブルのハンドル
);
パラメータ
hAccel

破棄するアクセラレータテーブルのハンドルを指定します。
このハンドルは、CreateAcceleratorTable 関数であらかじめ作成されていなければなりません。

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

──────────────────────────────
      if(pAccel)
     {
     /* 現在のアクセラレータテーブル */
      pCurrentAccel=(ACCEL*)(pAccel+numAccel-1);

      maxAccel++;
     /* メニューアイテム構造体への値の割り当て */
      ZeroMemory(&menuiteminfo, sizeof(menuiteminfo));
     menuiteminfo.cbSize = sizeof(menuiteminfo);
      menuiteminfo.fMask = MIIM_ID | MIIM_STATE | MIIM_TYPE;
     menuiteminfo.fType = MFT_STRING;
      menuiteminfo.fState = MFS_ENABLED;
     menuiteminfo.wID = IDM_NEW_MENU+maxAccel-1;
      /*  ストリングテーブルから文字列を取得する. */
     LoadString(hInst, IDM_MENU_VERSION1+maxAccel-1, strmenu, sizeof(strmenu));
      menuiteminfo.dwTypeData = (LPSTR)strmenu;
──────────────────────────────
typedef struct tagMENUITEMINFO {
  UINT    cbSize; 
  UINT    fMask; 
  UINT    fType; 
  UINT    fState; 
  UINT    wID; 
  HMENU   hSubMenu; 
  HBITMAP hbmpChecked; 
  HBITMAP hbmpUnchecked; 
  ULONG_PTR dwItemData; 
  LPTSTR  dwTypeData; 
  UINT    cch; 
  HBITMAP hbmpItem;
} MENUITEMINFO, *LPMENUITEMINFO; 
   詳しくはMSDNをご参照ください.
──────────────────────────────
LoadString
指定されたモジュールに関連付けられた実行可能ファイルから文字列リソースをロードし、
バッファにコピーします。

int LoadString(
  HINSTANCE hInstance,
                   //  handle of module containing string resource
  UINT uID,        //  resource identifier
  LPTSTR lpBuffer, //  address of buffer for resource
  int nBufferMax   //  size of buffer
);
パラメータ
hInstance

ロードする文字列リソースを持つ実行可能ファイルを含むモジュールの
インスタンスを指定します。

uID

ロードする文字列の ID を指定します。

lpBuffer

バッファへのポインタを指定します。このバッファに、文字列が、
NULL で終わる文字列として格納されます。

nBufferMax

バッファのサイズをバイト数 (ANSI 版) または文字数 (Unicode 版) で指定します。
バッファのサイズが足りない場合は、文字列は途中で切り捨てられます。

戻り値
関数が成功すると、バッファにコピーされたバイト数 (ANSI 版) 
または文字数 (Unicode 版) が返ります (終端の NULL は含まない) 。
文字列リソースが存在しないときは、0 が返ります。
拡張エラー情報を取得するには、GetLastError 関数を使います。


──────────────────────────────
     /* メニューを追加する. */
      InsertMenuItem(GetMenu(hwnd),IDM_EXIT,FALSE,&menuiteminfo);
  ここでは、メニューアイテム構造体の指定の値を入れ,
  InsertMenuItemによって、現在のメニューのIDM_EXITの上に
  挿入しています.
──────────────────────────────
InsertMenuItem
メニュー内の指定された位置に、新しいメニュー項目を挿入します。

BOOL WINAPI InsertMenuItem(
  HMENU hMenu,         
  UINT uItem,          
  BOOL fByPosition,    
  LPMENUITEMINFO lpmii 
);
パラメータ
hMenu

新しいメニュー項目を挿入するメニューのハンドルを指定します。

uItem

メニュー項目の ID または位置を指定します。この項目の前に、新しい項目が挿入されます。

fByPosition

uItem パラメータの意味を指定します。FALSE を指定すると、
uItem パラメータがメニュー項目の ID を指定していることを示します。
それ以外の値を指定すると、uItem パラメータがメニュー項目の位置を指定していることを示します。

lpmii

新しいメニュー項目に関する情報が入った、MENUITEMINFO 構造体へのポインタを指定します。

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



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

      /* セパレータを足す */
     ZeroMemory(&menuiteminfo, sizeof(menuiteminfo));
           menuiteminfo.cbSize = sizeof(menuiteminfo);
     menuiteminfo.fMask = MIIM_TYPE;
           menuiteminfo.fType = MFT_SEPARATOR;
           InsertMenuItem(GetMenu(hwnd), IDM_EXIT, FALSE, &menuiteminfo);
     
     /*  メニューの再描画を行なう.*/
      DrawMenuBar(hwnd);

──────────────────────────────
    ここでは、セパレータをメニューに追加しています.
──────────────────────────────
      /* アクセル構造体の取得 */
      pCurrentAccel->cmd=IDM_NEW_MENU+maxAccel-1;
     pCurrentAccel->fVirt =FNOINVERT|FVIRTKEY;
      pCurrentAccel->key=VK_F1;
──────────────────────────────
  ここでは、アクセル構造体の設定を行なっています.

──────────────────────────────
typedef struct tagACCEL { 
    BYTE   fVirt; 
    WORD   key; 
    WORD   cmd; 
} ACCEL, *LPACCEL; 

    BYTE   fVirt; どのキーとどのキーを使うかなどのOR演算
    WORD   key; ショートカットキーを決めます.
    WORD   cmd; アクセラレータを割り当てるメニューID 

  FALT Altキー
  FCONTROL Ctrlキー
  FNOINVERT トップレベルメニュー項目をハイライトにする。
  FSHIFT Siftキー
  FVIRTKEY 仮想コード、デファルトでは、ASCIIコード
──────────────────────────────

      /* アクセラレータテーブルの作成 */
      hMainAccel=CreateAcceleratorTable(pCurrentAccel,numAccel);
     
──────────────────────────────
CreateAcceleratorTable
アクセラレータテーブルを作成します。

HACCEL CreateAcceleratorTable(
  LPACCEL lpaccl,  // アクセラレータデータを持つ構造体配列へのポインタ
  int cEntries     // 配列内の構造体の数
);
パラメータ
lpaccl

アクセラレータテーブルを記述する ACCEL 構造体の配列へのポインタを指定します。

cEntries

配列内の ACCEL 構造体の数を指定します。

戻り値
関数が成功すると、作成されたアクセラレータテーブルのハンドルが返ります。
関数が失敗すると、NULL が返ります。拡張エラー情報を取得するには、GetLastError 関数を使います。

解説
アプリケーションを閉じる前に、DestroyAcceleratorTable 関数を使って、
CreateAcceleratorTable 関数で作成されたアクセラレータテーブルを破棄します。


──────────────────────────────
      /* アクセラレータハンドルのアンロック */
     GlobalUnlock(hAccel);
──────────────────────────────
GlobalUnlock
グローバルメモリオブジェクトのロックカウントを減らします。
移動可能メモリにのみ有効です。固定メモリには効果がありません。

BOOL GlobalUnlock(
  HGLOBAL hMem   //  handle to the global memory object
);
パラメータ
hMem

グローバルメモリオブジェクトのハンドルを指定します。
GlobalAlloc 関数または GlobalReAlloc 関数が、このハンドルを返します。

戻り値
関数の実行後もロックカウントが 1 以上であれば、0 以外の値が返ります。
それ以外の場合は、0 が返ります。
拡張エラー情報を取得するには、GetLastError 関数を使います。
GetLastError 関数の戻り値が NO_ERROR のときは、そのメモリオブジェクトはロックされていません。

解説
メモリオブジェクトのロックカウントの初期値は 0 です。
GlobalLock 関数はロックカウントを 1 増やし、GlobalUnlock 関数はロックカウントを 1 減らします。
ただし、GMEM_FIXED フラグを指定して確保したメモリオブジェクトのロックカウントは、常に 0 です。
ロックカウントを取得するには、GlobalFlags 関数を使います。 


──────────────────────────────
      }
      /* アクセラレータハンドルのメモリ解放 */
     if(hAccel)
      GlobalFree(hAccel);
──────────────────────────────
GlobalFree
指定されたグローバルメモリオブジェクトを解放して、そのハンドルを無効にします。

HGLOBAL GlobalFree(
  HGLOBAL hMem   //  handle to the global memory object
);
パラメータ
hMem

グローバルメモリオブジェクトのハンドルを指定します。
GlobalAlloc 関数または GlobalReAlloc 関数が、このハンドルを返します。

戻り値
関数が成功すると、NULL が返ります。
関数が失敗すると、グローバルメモリオブジェクトのハンドルと同じ値が返ります。
拡張エラー情報を取得するには、GetLastError 関数を使います。

解説
メモリを解放した後にメモリにアクセスすると、ヒープが壊れたり、
アクセス違反 (EXCEPTION_ACCESS_VIOLATION) が起きたりすることがあります。
この関数は、ロックされたメモリオブジェクトも解放します。


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

 今回は、あまり使うこともないことかもしれませんが,
 Windowsの構造体に当てはめる形式の方法が
 わかったと思います.
 
 それでは。

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

なお、以上のプログラムは、私の動作環境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 ] ========================================================


   保険スクエアbang!で  ”自動車保険を見積もり&資料請求”
┏┯┓┏┯┓  □ とにかく価格が安いのが一番!
┠比┨┠較┨  □ 価格も補償も重視!     ★あなたはどのタイプ?
┗┷┛┗┷┛  □ 補償が厚いのが一番!
<<無料>> くわしくは ⇒ http://216.71.100.246/a/a.cgi?k0802m0469 


======================================================== [ ▲PR ] ====
■マガジン発行者のうれしいクリックを!
■広告掲載マガジン募集中!< http://216.71.100.246/b/a.cgi?k0010m0469 >
======================================================== [ ▲PR ] ====




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


◇*◇* 「安い海外旅行」よりも、「お得な海外旅行」がイイ!! *◇*◇
* ―海外旅行でキャッシュバック!→「JCBトラベルプラスカード」― *  
◇  ・スピード発行OK・入ってすぐ使うと→ボーナスポイント進呈  ◇ 
* ・海外旅行傷害保険付き・写真付きカードもご用意・初年度年会費無料 *
◇ 海外で絶対お得⇒  http://216.71.100.246/a/a.cgi?k0695m0469 


======================================================== [ ▲PR ] ====
■マガジン発行者のうれしいクリックを!
■広告掲載マガジン募集中!< http://216.71.100.246/b/a.cgi?k0010m0469 >
======================================================== [ ▲PR ] ====




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


━━━━━━   新築マンション・不動産の情報満載!  ━━━━━━━
▲▲▲ 多彩なカテゴリー検索であなたのお住まい探しをサポート! ▲▲▲
■田■     物件購入のお役立ち情報、豆知識まで掲載!    ■田■
■■■      困ったときの相談コーナーも設置!       ■■■
               http://216.71.100.246/a/a.cgi?k1026m0469 


======================================================== [ ▲PR ] ====
■マガジン発行者のうれしいクリックを!
■広告掲載マガジン募集中!< http://216.71.100.246/b/a.cgi?k0010m0469 >
======================================================== [ ▲PR ] ====




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


■■■■■■■■■■■ <<TCBカード>> ■■■■■■■■■■■
■■    不意な出費で財布の中がちょっぴり心もとない!    ■■
■   そんなあなたにお知らせ。時間をかけずにキャッシング。   ■
■■■■■■■■■■↓今すぐこちらにアクセス!↓■■■■■■■■■■
             http://216.71.100.246/a/a.cgi?k1055m0469 


======================================================== [ ▲PR ] ====
■マガジン発行者のうれしいクリックを!
■広告掲載マガジン募集中!< http://216.71.100.246/b/a.cgi?k0010m0469 >
======================================================== [ ▲PR ] ====




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


―― 初歩から学んでプロのJAVAプログラマーを目指す本格講座 ――
 ◆  「はじめて学ぶJAVAプログラミング」の著者が直接指導
◆+◆ 東京・お茶の水に10月開講    ≪ドットネット≫
 ◆  JAVAプログラミング本科コース(平日昼間週2回:6ヶ月)他
 資料請求はこちら: http://216.71.100.246/a/a.cgi?k0911m0469 


======================================================== [ ▲PR ] ====
■マガジン発行者のうれしいクリックを!
■広告掲載マガジン募集中!< http://216.71.100.246/b/a.cgi?k0010m0469 >
======================================================== [ ▲PR ] ====


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