Issue
Recently had a customer who was facing this issue. His code looked as follows (assuming COM’s initialized) which apparently is trying to setup an ActiveX control…
HWND hWnd = CreateWindow(_T(ATLAXWIN_CLASS), _T(“SysMon”), WS_CHILD, 0, 10, 100, 200, hwndParent, NULL, hInstance, NULL);
As soon as above code executes the application crashes.
Why loading ActiveX failed?
Callstack for the crash looks as follows…
ConsoleApplication1.exe!ATL::CComPolyObject<ATL::CAxHostWindow>::CComPolyObject<ATL::CAxHostWindow> ConsoleApplication1.exe!ATL::CComCreator<ATL::CComPolyObject<ATL::CAxHostWindow> >::CreateInstance ConsoleApplication1.exe!AtlAxCreateControlLicEx ConsoleApplication1.exe!AtlAxCreateControlLic ConsoleApplication1.exe!ATL::AtlAxWindowProc user32.dll!UserCallWinProcCheckWow user32.dll!DispatchClientMessage user32.dll!__fnINLPCREATESTRUCT ntdll.dll!KiUserCallbackDispatch Unknown user32.dll!ZwUserCreateWindowEx Unknown user32.dll!VerNtUserCreateWindowEx user32.dll!CreateWindowInternal user32.dll!CreateWindowExW ConsoleApplication1.exe!wmain ConsoleApplication1.exe!__tmainCRTStartup ConsoleApplication1.exe!wmainCRTStartup kernel32.dll!BaseThreadInitThunk ntdll.dll!RtlUserThreadStart
Autos debug window showed following…
Resolution
The highlighted elements gave ample hint. This is a console application with no ATL boilerplate code generated by project wizard for this project. Ideally ATL requires a global CComModule instance to initialize itself. This is how the CComModule constructor looks like…
CComModule() { // Should have only one instance of a class // derived from CComModule in a project. ATLASSERT(_pModule == NULL); <span style="background-color: #ffff00;">_pModule = this;</span> #if !defined(_ATL_NATIVE_INITIALIZATION) #pragma warning(push) // disable 4483 #pragma warning(disable:4483) using namespace __identifier("<AtlImplementationDetails>"); #pragma warning(pop) // disable 4483 ATLASSERT(ComModuleInitialized == false); // If ComModuleHelper.Module == NULL it mean that DllMain has not been called, so we assume CComModule lives in // an exe and not in a dll if (ComModuleHelper.Module != NULL) { ATLASSERT(ComModuleHelper.Module == this); _DllMain(ComModuleHelper.Instance, DLL_PROCESS_ATTACH, NULL, ComModuleHelper.ObjectMap, ComModuleHelper.LibraryId); } ComModuleInitialized = true; #endif }
This function further initializes _pModule instance to point to this global instance of ours eventually. So after we declare CComModule global instance this is how _pAtlModule (it points to our global instance) will look after instantiation of our global CComModule…
Crash resolved.