アークピットのホームページに戻る

WinAPIトピックのトップページに戻る

APIトピックの各章に移動する

ダウンロードのページに移動する
ダウンロードができ
ない場合の対処法
 

ページ移動

2-2-10. 補足メモリブロックの使用例

 クラスとはでウィンドウの補足メモリブロックを説明しました。ここでは、実際のその使用法を例示します。

 この例は、"ApHello"ウィンドウを作成し、そのウィンドウ内にリッチテキストコントロールを子ウィンドウとして作成します。そのプロシージャ内でリッチテキストコントロールのハンドルをこの補足メモリブロックに設定します。

         :(他のコード)
    HWND hMain;
    WNDCLASSEX wc;
    static LPSTR pClassName = "ApHelloClass";
    static LPSTR pAppName = "ApHello";

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = (WNDPROC)WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = sizeof(HWND); // 補足メモリブロックサイズ
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(hInstance,pAppName);
    wc.hCursor       = LoadCursor(NULL,IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = pAppName;
    wc.lpszClassName = pClassName;
    wc.hIconSm       = LoadImage(hInstance,pAppName,IMAGE_ICON
                                ,16,16,LR_DEFAULTCOLOR);
    if (!RegisterClassEx(&wc)) return FALSE;
    hMain = CreateWindow(pClassName,pAppName,
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT,0,CW_USEDEFAULT,0,
                         NULL,NULL,hInstance,NULL);
    if (!hMain) return FALSE;
    ShowWindow(hMain,nCmdShow);
    UpdateWindow(hMain);
         :(他のコード)

LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg
                                  ,WPARAM wParam,LPARAM lParam)
{
    HWND  hEdit;  // RichEdit Control

    switch (uMsg)
    {
        case WM_CREATE: // メインウィンドウの新規作成
        {
            InitCommonControls();
            hEdit = CreateWindowEx(WS_EX_CLIENTEDGE,
                          "RICHEDIT",NULL,
                          ES_AUTOVSCROLL|WS_VSCROLL|WS_CHILD|
                          WS_CLIPSIBLINGS|WS_CLIPCHILDREN|
                          WS_VISIBLE|ES_MULTILINE|ES_NOHIDESEL|
                          ES_DISABLENOSCROLL,
                          0,0,0,0,
                          hMain,(HMENU)ID_RTF,hInstance,NULL);
            SetWindowLong(hWnd,0,(LONG)hEdit);  // 設定
             :(他のコード)
            break;
        }
        case WM_SIZE:   // ウィンドウのサイズを変更した
        {
            hEdit = (HWND)GetWindowLong(hWnd,0);  // 取得
            if (hEdit)  // リッチテキストエディタのサイズを設定
                MoveWindow(hEdit,0,0,
                           LOWORD(lParam),HIWORD(lParam),TRUE);
            break;
        }
        case WM_DESTROY:
            hEdit = (HWND)GetWindowLong(hWnd,0);  // 取得
            if (hEdit) DestroyWindow(hEdit);
            break;
             : (他のメッセージ)
    }
    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
 色の違う部分が関連コードです。まず、WNDCLASSEX構造体のcbWndExtraメンバに確保するサイズを設定します。この場合は、ウィンドウのハンドルなので、4バイトです。次にプロシージャ内の、WM_CREATE でリッチテキストコントロールを作成し、SetWindowLong関数で、そのハンドルを補足メモリブロックの0相対位置に設定します。WM_SIZE や WM_DESTROY メッセージでそのハンドルを使用しますが、その場合は、GetWindowLong 関数で得ます。static 記憶クラスでなく、「HWND hEdit;」となっている点に注意してください。また補足メモリブロックは設定する値の型は想定していないので、設定も取得もキャスティングが必要なことを忘れないでください。

 これでは、前の項目のコードの様に、「static HWND hEdit;」と宣言して、使用しても良いではないかと思われるかも知れません。たしかにこの場合はそうです。しかし、このウィンドウを複数個、しかも同時にオープンする必要がある場合だったらどうでしょうか。MDIの子ウィンドウの場合などがそれに相当します。その場合、static 宣言したのでは、1個しかリッチテキストコントロールのハンドルを保持できません。つまり1個しかオープンできません。それに比べ補足メモリブロックでは、ウィンドウ(hWnd)ごとにリッチテキストコントロールのハンドルを設定します。つまりオープンするウィンドウごとなので、いくつオープンしてもいっこうに問題ありません。また、hWnd さえあれば、同じ方法でリッチテキストコントロールのハンドルを得ることができます。スコープを気にする必要はありません。この様に補足メモリブロックは、非常に便利な技法です。

ページ移動