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
연결할 수 있습니다.
CWnd myWnd;
myWnd.Attach(hWnd);
그러면 myWnd 및 hWnd와 연결된 영구 맵에 항목이 만들어집니다. 이제 호출 CWnd::FromHandle(hWnd)
은 myWnd에 대한 포인터를 반환합니다. myWnd가 삭제되면 소멸자는 Windows DestroyWindow 함수를 호출하여 hWnd를 자동으로 삭제합니다. 원하는 것이 아닌 경우 myWnd가 제거되기 전에 hWnd를 myWnd에서 분리해야 합니다(일반적으로 myWnd가 정의된 범위를 떠날 때). 메서드는 Detach
이 작업을 수행합니다.
myWnd.Detach();
임시 개체에 대한 자세한 정보
래퍼 개체가 없는 핸들이 제공되면 임시 FromHandle
개체가 만들어집니다. 이러한 임시 개체는 해당 핸들에서 분리되고 함수에 DeleteTempMap
의해 삭제됩니다. 기본적으로 CWinThread::OnIdle 은 임시 핸들 맵을 지원하는 각 클래스를 자동으로 호출 DeleteTempMap
합니다. 즉, 임시 개체에 대한 포인터가 포인터를 가져온 함수의 종료 지점을 지나서 유효하다고 가정할 수 없습니다.
래퍼 개체 및 여러 스레드
임시 개체와 영구 개체는 모두 스레드별로 기본. 즉, 한 스레드는 임시 또는 영구 여부에 관계없이 다른 스레드의 C++ 래퍼 개체에 액세스할 수 없습니다.
이러한 개체를 한 스레드에서 다른 스레드로 전달하려면 항상 해당 개체를 네이티브 HANDLE
형식으로 보냅니다. C++ 래퍼 개체를 한 스레드에서 다른 스레드로 전달하면 종종 예기치 않은 결과가 발생합니다.