MFC Extension DLL 사용시 발생하는 에러 검토(AfxGetApp()==NULL)
Host가 MFC Application이 아닌 Win32 윈도우 애플리케이션인 경우,
다음과 같이 MFC Dialog를 띄우려고 할 때 다음 함수에서 AfxGetApp()를 호출하는데 이것이 NULL을 리턴하게 된다.
따라서 CObject::IsKindOf() 함수에서 this가 NULL인 것을 인식하고 Exception이 발생한다.
단, #ifdef _DEBUG 구문이 있어서 Release는 정상 동작한다. 하지만 Debug 에서는 더 이상 동작하지 않는다.
BOOL CWnd::CreateDlgIndirect(LPCDLGTEMPLATE lpDialogTemplate,
CWnd* pParentWnd, HINSTANCE hInst)
{
#ifdef _DEBUG
if ( AfxGetApp()->IsKindOf( RUNTIME_CLASS( COleControlModule ) ) )
{
TRACE(traceAppMsg, 0, "Warning: Creating dialog from within a COleControlModule application is not a supported scenario.\n");
}
#endif
...
}
BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const
{
ENSURE(this != NULL);
// it better be in valid memory, at least for CObject size
ASSERT(AfxIsValidAddress(this, sizeof(CObject)));
// simple SI case
CRuntimeClass* pClassThis = GetRuntimeClass();
ENSURE(pClassThis);
return pClassThis->IsDerivedFrom(pClass);
}
이를 해결하기 위해 전역변수로 CWinApp의 인스턴스를 선언하면 된다.
CWinApp theApp;
이제 AfxGetApp()는 정상적인 값을 리턴한다. 이제는 AfxGetInstanceHandle()에서 NULL 때문에 Assert를 발생시킨다.
BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister)
{
// mask off all classes that are already registered
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
fToRegister &= ~pModuleState->m_fRegisteredClasses;
if (fToRegister == 0)
return TRUE;
LONG fRegisteredClasses = 0;
// common initialization
WNDCLASS wndcls;
memset(&wndcls, 0, sizeof(WNDCLASS)); // start with NULL defaults
wndcls.lpfnWndProc = DefWindowProc;
wndcls.hInstance = AfxGetInstanceHandle();
wndcls.hCursor = afxData.hcurArrow;
...
}
이것은 AFX_MODULE_STATE와 관련이 있기 때문에 이 부분을 직접 설정해야 한다.
다음과 같이 HINSTANCE를 설정하는 작업을 수행한다.
(AfxGetModuleState() 등은 앞서 CWinApp의 인스턴스를 할당함으로써 정상적으로 수행한다)
::AfxGetModuleState()->m_hCurrentInstanceHandle = gInstance;
이제 정상적으로 MFC 대화상자를 생성하고 띄울 수 있다.
'개발언어 > c++' 카테고리의 다른 글
응용 프로그램에서 아이콘 가져오기 (0) | 2016.07.18 |
---|---|
프로세서 핸들 조회 (0) | 2016.07.18 |
DLL에서 만든 클래스 공유 (0) | 2016.07.18 |
std::function (0) | 2016.07.18 |
namespace (0) | 2016.07.18 |