• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1020
  • Last Modified:

Converting a 6.0 MFC app to Visual Studio 2008 (quantum leap)

Hi Experts,

I'm getting an error when the call reaches OleInitialize from the First call to AfxOleInit().  The error is RPC_E_CHANGED_MODE ($80010106).  What does this mean?  I think it has something to do with threading models - which are very mysterious and ominous to me...

Thanks for any help!
Mike
BOOL CMyApp::InitInstance()
{
	if (!InitATL())
		return FALSE;
	
	if(!AfxOleInit())  // Your addition starts here
	{
		AfxMessageBox("Could not initialize COM dll");
		return FALSE;
	}                 // End of your addition
 
....
 
BOOL CMyApp::InitATL()
{
	m_bATLInited = TRUE;
	
#if _WIN32_WINNT >= 0x0400
	HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
#else
	HRESULT hRes = CoInitialize(NULL);
#endif
	
	if (FAILED(hRes))
	{
		m_bATLInited = FALSE;
		return FALSE;
	}
	
	_Module.Init(ObjectMap, AfxGetInstanceHandle());
	_Module.dwThreadID = GetCurrentThreadId();
	
	LPTSTR lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
	TCHAR szTokens[] = _T("-/");
	
	BOOL bRun = TRUE;
	LPCTSTR lpszToken = _Module.FindOneOf(lpCmdLine, szTokens);
	while (lpszToken != NULL)
	{
		if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
		{
			_Module.UpdateRegistryFromResource(IDR_MBS, FALSE);
			_Module.UnregisterServer(TRUE); //TRUE means typelib is unreg'd
			bRun = FALSE;
			break;
		}
		if (lstrcmpi(lpszToken, _T("RegServer"))==0)
		{
			_Module.UpdateRegistryFromResource(IDR_MBS, TRUE);
			_Module.RegisterServer(TRUE);
			bRun = FALSE;
			break;
		}
		lpszToken = _Module.FindOneOf(lpszToken, szTokens);
	}
	
	if (!bRun)
	{
		m_bATLInited = FALSE;
		_Module.Term();
		CoUninitialize();
		return FALSE;
	}
	
	hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, 
		REGCLS_MULTIPLEUSE);
	if (FAILED(hRes))
	{
		m_bATLInited = FALSE;
		CoUninitialize();
		return FALSE;
	}	
	
	return TRUE;
	
}

Open in new window

0
thready
Asked:
thready
  • 2
  • 2
1 Solution
 
threadyAuthor Commented:
ok - let me rephrase the question - I realized it is because of the apartment thingamagig.  I changed my CoInitializeEx function to the following and my code works now:
      HRESULT hRes = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); //(NULL, COINIT_MULTITHREADED);

The question is - why is it now single apartment thread now - and what are the consequences of this?  Should I be concerned?  Why was it working in 6.0 for a long time - and now in 2008 it needs to be single threaded?  Thanks again!
Mike
0
 
primeMover2004Commented:
To answer your original question:

The problem arises from the fact that you first call

CoInitializeEx(NULL, COINIT_MULTITHREADED);

Within AfxOleInit() there's another call to CoInitialize.
Don't do that :) That's where the RPC_E_CHANGED_MODE comes from.

Furthermore MFC applications *must* be initialized as single threaded apartment (STA)
(CoInitialize(NULL))


0
 
threadyAuthor Commented:
If you say so!  (any reason why they must be?  just so I understand these apartments)?
0
 
primeMover2004Commented:
Also the help says so :)
http://msdn2.microsoft.com/en-us/library/ms678543.aspx

And from my experience, this is true ;)

You can only initialize a thread to live in a specific department once, the first time, that is.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now