テクニカル ノート 3: Windows ハンドルとオブジェクト間のマップ
ここでは、 C++ オブジェクトにマッピングのペイン オブジェクトのハンドルをサポートする MFC のルーチンを記述します。
問題
ペイン オブジェクトは、 MFC クラスのラップのペイン オブジェクトが C++ オブジェクトで処理 ハンドル のさまざまなオブジェクトには、通常、表されます。MFC クラス ライブラリの関数をラップするハンドルは、特定のハンドルを持つペイン オブジェクトをラップする C++ オブジェクトを見つけることができます。ただし、オブジェクトに対する C.C++ のラッパー オブジェクトがなく、これらの時点でシステムは C++ のラッパーとして機能するための一時的なオブジェクトを作成します。
次のように使用するハンドルのマップがあります。ペイン オブジェクト:
HWND (CWnd と CWnd派生クラス)
(HDCCDC と CDC派生クラス)
HMENU (CMenu)
HPEN (CGdiObject)
HBRUSH (CGdiObject)
HFONT (CGdiObject)
HBITMAP (CGdiObject)
HPALETTE (CGdiObject)
HRGN (CGdiObject)
HIMAGELIST (CImageList)
ソケット (CSocket)
ハンドルをこれらのオブジェクトの一つにより、静的メソッド FromHandleを呼び出すことでハンドルをラップする MFC のオブジェクトを検索できます。たとえば、 HWND を指定 hWnd、次の行を返します hWndをラップする CWnd にポインターを呼び出して:
CWnd::FromHandle(hWnd)
hWnd に固有のラッパー オブジェクトがない場合 hWndをラップするために、一時 CWnd が作成されます。これは、ハンドルの有効な C++ のオブジェクトを取得できるようにします。
ラッパー オブジェクトが割り当てられると、ラッパー クラスのパブリック メンバー変数のハンドルを取得できます。CWndの場合、 m_hWnd は、そのオブジェクトの HWND が含まれます。
MFC のオブジェクトへのハンドルの接続
ペイン オブジェクトへのハンドル新しく作成されたラッパー オブジェクトおよびハンドルは、この例のように Attach 関数を呼び出すことによって 2 を関連付けることができます:
CWnd myWnd;
myWnd.Attach(hWnd);
これは myWnd と hWndを関連付けるパーマネント マップのエントリを作成します。CWnd::FromHandle(hWnd) を呼び出すことは myWndに、ポインターを返します。myWnd が削除されるとき、デストラクターは、 Windows の DestroyWindow 関数を呼び出すことによって自動的に hWnd を破棄します。これが望まれなければ、 hWnd は myWnd から myWnd 定義された)離れたときスコープを myWnd が破棄される前にデタッチする必要があります (通常は。Detach のメソッドは、これを行います。
myWnd.Detach();
一時オブジェクトに関する詳細
一時オブジェクトは FromHandle が既にラッパー オブジェクトがないハンドルを指定したときに作成されます。これらの一時オブジェクトはハンドルからデタッチし、 DeleteTempMap 関数によって削除されます。既定で CWinThread::OnIdle は自動的に一時的なハンドルのマップをサポートするクラスごとの DeleteTempMap をダイヤルします。これは、一時オブジェクトへのポインターがポインターが派生関数の終了点を含む有効であると仮定できないことを意味します。
ラッパー オブジェクトと複数のスレッド
一時とパーマネント オブジェクトは、スレッドごとに保持されます。つまり、 1 種類のスレッドは、一時的な場合は永続的であるかどうかを別のスレッドの C++ のラッパー オブジェクトに、に関係なくアクセスできません。
1 種類のスレッド間でこれらのオブジェクトを渡すには、 HANDLE のネイティブ型としてそれらを常に送信します。1 種類のスレッド間で C.C++ のラッパー オブジェクトを渡すと、多くの場合、予期しない結果が発生します。