次の方法で共有


TN003: オブジェクトへの Windows ハンドルのマッピング

このメモでは、Windows オブジェクト ハンドルから C++ オブジェクトへのマッピングをサポートする MFC ルーチンについて説明します。

問題

Windows オブジェクトは、通常、さまざまな HANDLE オブジェクトによって表されます。MFC クラスは、Windows オブジェクト ハンドルを C++ オブジェクトでラップします。 MFC クラス ライブラリのハンドル ラッピング関数を使用すると、特定のハンドルを持つ Windows オブジェクトをラップしている C++ オブジェクトを見つけることができます。 ただし、オブジェクトに C++ ラッパー オブジェクトがない場合があり、これらの場合、システムは C++ ラッパーとして機能する一時オブジェクトを作成します。

ハンドル マップを使用する Windows オブジェクトは次のとおりです。

  • HWND (CWnd および CWnd 派生クラス)

  • HDC (CDC および CDC 派生クラス)

  • HMENU (CMenu)

  • HPEN (CGdiObject)

  • HBRUSH (CGdiObject)

  • HFONT (CGdiObject)

  • HBITMAP (CGdiObject)

  • HPALETTE (CGdiObject)

  • HRGN (CGdiObject)

  • HIMAGELIST (CImageList)

  • SOCKET (CSocket)

これらのオブジェクトのいずれかにハンドルがある場合は、静的メソッド FromHandleを呼び出すことによって、ハンドルをラップする MFC オブジェクトを見つけることができます。 たとえば、hWnd という HWND を指定すると、次の行は hWnd をラップするCWndへのポインターを返します。

CWnd::FromHandle(hWnd)

hWnd に特定のラッパー オブジェクトがない場合は、hWnd をラップするために一時的なCWndが作成されます。 これにより、任意のハンドルから有効な C++ オブジェクトを取得できます。

ラッパー オブジェクトを作成したら、ラッパー クラスのパブリック メンバー変数からそのハンドルを取得できます。 CWndの場合、m_hWndにはそのオブジェクトの HWND が含まれます。

MFC オブジェクトへのハンドルのアタッチ

新しく作成されたハンドル ラッパー オブジェクトと Windows オブジェクトへのハンドルを指定すると、次の例のように Attach 関数を呼び出すことによって、2 つを関連付けることができます。

CWnd myWnd;
myWnd.Attach(hWnd);

これにより、 myWnd と hWnd を関連付け、永続的なマップにエントリが作成 されますCWnd::FromHandle(hWnd)を呼び出すと、myWnd へのポインターが返されるようになりました。 myWnd が削除されると、デストラクターは Windows DestroyWindow 関数を呼び出すことによって hWnd を自動的に破棄します。 これが望ましくない場合は、 myWnd が破棄される前に hWndmyWnd からデタッチする必要があります (通常、 myWnd が定義されたスコープを離れる場合)。 Detachメソッドはこれを行います。

myWnd.Detach();

一時オブジェクトの詳細

一時オブジェクトは、まだラッパー オブジェクトを持たないハンドル FromHandle が与えられるたびに作成されます。 これらの一時オブジェクトはハンドルからデタッチされ、 DeleteTempMap 関数によって削除されます。 既定では 、CWinThread::OnIdle は 、一時ハンドル マップをサポートするクラスごとに DeleteTempMap を自動的に呼び出します。 つまり、一時オブジェクトへのポインターが、ポインターが取得された関数の終了時点を超えて有効であると想定することはできません。

ラッパー オブジェクトと複数のスレッド

一時的なオブジェクトと永続的なオブジェクトの両方がスレッドごとに保持されます。 つまり、あるスレッドが一時的か永続的かに関係なく、別のスレッドの C++ ラッパー オブジェクトにアクセスすることはできません。

これらのオブジェクトをスレッド間で渡すには、常にネイティブ HANDLE 型として送信します。 あるスレッドから別のスレッドに C++ ラッパー オブジェクトを渡すと、多くの場合、予期しない結果が発生します。

こちらも参照ください

番号別テクニカル ノート
カテゴリ別テクニカル ノート