本文介绍了从COM服务器中的资源创建对话框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我正在编写一个进程外COM服务器(* .exe),它应该使用资源模板显示一个对话框。资源包含在服务器的exe文件中。我正在使用VC ++ 2010,该项目具有MFC支持并且大量使用MFC类。代码归结为:

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;
}





会发生什么:当 CWnd :: CreateDlgIndirect 调用 AfxGetApp() - > IsKindOf(RUNTIME_CLASS(COleControlModule))因为 AfxGetApp()返回一个NULL指针。



为了验证这一点,我插入了行 CWinApp * pApp = AfxGetApp(); 它为pApp分配NULL。



当我删除对 AfxSetResourceHandle 的调用时,断言在<$中触发c $ c> AfxGetResourceHandle()
因为 afxCurrentResourceHandle 为NULL。



我的项目似乎没有CWinApp派生类。 VC ++ 2010不提供COM out-proc服务器向导,因此我克隆了一个没有GUI的out-proc服务器项目。我是否必须添加应用程序对象?如果是这样,怎么样?



谢谢...... Hans



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

推荐答案


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





GUI线程在其InitInstance函数中创建对话框。





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

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





CMyGuiThread :: m_pWnd成员存储一个指向CMyDlg对象的指针,这样你就可以销毁对话框不再需要。 (请注意,对话框可能会因为IDOK或IDCANCEL控件点击而自行销毁,并且响应右上角的X图标点击;在这种情况下,m_pWnd指向无效的内存;您必须覆盖CMyDlg :: OnCancel和OnOk以防止这种情况。)



对话框在其Create函数中调用其中一个继承的重载。





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.

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





也许重要的是不要使用通常放在每个方法开头的AFX_MANAGE_STATE宏通过COM接口调用。



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.


这篇关于从COM服务器中的资源创建对话框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 03:54