본문으로 바로가기

MFC Extension DLL 사용시 발생하는 에러 검토

category 개발언어/c++ 2016. 7. 18. 05:25

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