Click here to Skip to main content
15,895,709 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi,

I am writing an out-of-process COM server (*.exe) which should display a dialog using a resource template. The resource is contained in the server's exe file. I am using VC++ 2010, and the project has MFC support and makes heavy use of MFC classes. The code boils down to this:
STDMETHODIMP CMyComServer::MyMethod()
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState())
    AfxSetResourceHandle(_AtlBaseModule.GetResourceInstance()); // see text below
    CWinApp *pApp = AfxGetApp(); // see text below

    CDialog objDlg(IDD_MY_DIALOG, NULL);
    objDlg.DoModal();
    return S_OK;
}


What happens is this: The call to DoModal asserts when CWnd::CreateDlgIndirect calls AfxGetApp()->IsKindOf(RUNTIME_CLASS(COleControlModule)) because AfxGetApp() returns a NULL pointer.

To verify this, I inserted the line CWinApp *pApp = AfxGetApp(); which assigns NULL to pApp.

When I remove the call to AfxSetResourceHandle, the assertion is triggered in AfxGetResourceHandle() because afxCurrentResourceHandle is NULL.

My project seems not to have a CWinApp-derived class. VC++ 2010 does not provide a COM out-proc server wizard, so I cloned an out-proc server project which has no GUI. Do I have to add an application object? If so, how?

Thanks... Hans
Posted
Comments
BadJerry 18-Jun-13 9:06am    
Did you find a solution to this? I have the same problem!

you've already used ATL to create the Server, so use WTL to do the dialog, throw MFC away :)

Look at CDialogImpl<>[^]
 
Share this answer
 
Comments
hans.sch 20-May-11 5:20am    
I get your point. However junking MFC is no option. I have to follow company guidelines, and besides, our code base makes heavy use of MFC. No, I must do with CDialog, CWinApp, etc.
barneyman 20-May-11 6:01am    
Sorry - I can't help you then

I've retrofitted an ATL server into an MFC app, but not the other way around ...
BadJerry, I found a solution that worked for me. However after such a long time I am not at all sure what the key points were. I hope these chunks of code can help you. I removed all error checking.

This function implements the COM interface. It creates a MFC GUI thread which displays the dialog.

C++
STDMETHODIMP CMyComServer::MyInterfaceFunction(...)
{
    // Don't call AFX_MANAGE_STATE!
    AfxSetResourceHandle(_AtlBaseModule.GetResourceInstance());
    CMyGuiThread *pThread = dynamic_cast<cmyguithread*>AfxBeginThread(RUNTIME_CLASS(CMyGuiThread)));
}


The GUI thread, in its InitInstance function, creates the dialog.

C++
/*virtual*/ BOOL CMyGuiThread::InitInstance()
{
    CMyDlg *pWnd = new CMyDlg;
    BOOL bRes = pWnd->Create();
    if (bRes)
        m_pWnd = pWnd;
    else
        delete pWnd;
    return bRes;
}


The CMyGuiThread::m_pWnd member stores a pointer to the CMyDlg object so that you can destroy the dialog when it is no longer required. (Be aware that a dialog can destroy itself in response to IDOK or IDCANCEL control clicks and inresponse to a click on the X icon in the upper right corner; in that case, m_pWnd points to invalid memory; you must overwrite CMyDlg::OnCancel and OnOk to prevent this.)

The dialog, in its Create function, calls one of the inherited overloads.

C++
/*virtual*/ BOOL CMyDlg::Create()
{
    return __super::Create(IDD, NULL);
}


Maybe the important thing is not to use the AFX_MANAGE_STATE macro which you usually put at the beginning of each method that is called over the COM interface.
 
Share this answer
 
v2
Comments
acolada 20-Nov-14 17:24pm    
this worked for me too:
AfxSetResourceHandle(_AtlBaseModule.GetResourceInstance());
instead of AFX_MANAGE_STATE(...)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900