我有一个模块,可以创建一个包含ActiveX控件的无模式对话框。该模块是MFC EXE应用程序的一部分,对话框的创建工作正常。最近,我将模块移出到ATL / COM服务器,并将对话框资源从EXE复制到COM服务器。尝试使用CDialog::Create()
创建无模式对话框时,会发生错误。
我已调试到CDialog::Create
并注意到它在::CreateDialogIndirect()
失败,返回NULL
而GetLastError
返回0
。我在对话框资源属性中将“No Fail Create”标志更改为True,我得到了更多错误信息。问题发生在DoDataExchange()
宏内的对话框DDX_Control
中。这将使用控件的资源ID调用CDataExchange::PrepareCtrl()
,如下所示:
HWND CDataExchange::PrepareCtrl(int nIDC)
{
ASSERT(nIDC != 0);
ASSERT(nIDC != -1); // not allowed
HWND hWndCtrl;
COleControlSite* pSite = NULL;
m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
if (hWndCtrl == NULL)
{
// Could be a windowless OCX
pSite = m_pDlgWnd->GetOleControlSite(nIDC);
if (pSite == NULL)
{
TRACE(traceAppMsg, 0, "Error: no data exchange control with ID 0x%04X.\n", nIDC);
ASSERT(FALSE);
AfxThrowNotSupportedException();
}
}
m_idLastControl = nIDC;
m_bEditLastControl = FALSE; // not an edit item by default
return hWndCtrl;
}
对函数m_pDlgWnd->GetOleControlSite()
的调用对于传递的资源ID失败。顺便说一句,资源ID是控件的ID。
有关为什么在EXE内部工作并且在COM服务器中失败的任何建议?
答案 0 :(得分:4)
我有完全相同的问题。在我的情况下,问题是我没有调用AfxEnableControlContainer()。我在我的应用程序的InitInstance成员函数中添加了一个调用,它修复了问题。
答案 1 :(得分:2)
前几天有类似的问题。将控件从一个对话框资源复制到另一个。实际上,您不能像使用其他MFC控件那样将ActiveX控件从一个对话框复制到另一个对话框。对于ActiveX控件,rc文件包含DLGINIT部分。例如,我有一个带有IE WebBrowser控件的表单:
IDD_ONLINE_REPORTVIEW_FORM DIALOGEX 0, 0, 320, 200
STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
CONTROL "",IDC_EXPLORER1,"{8856F961-340A-11D0-A96B-00C04FD705A2}",WS_TABSTOP,7,61,299,77
END
以及rc文件中的下面有一个DLGINIT部分:
IDD_ONLINE_REPORTVIEW_FORM DLGINIT
BEGIN
IDC_EXPLORER1, 0x376, 160, 0
0x0000, 0x0000, 0x004c, 0x0000, 0x2e68, 0x0000, 0x0ceb, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x004c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
0x0000, 0xd0e0, 0x0057, 0x3573, 0x11cf, 0x69ae, 0x0008, 0x2e2b, 0x6212,
0x0008, 0x0000, 0x0000, 0x0000, 0x004c, 0x0000, 0x1401, 0x0002, 0x0000,
0x0000, 0x00c0, 0x0000, 0x0000, 0x4600, 0x0080, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0
END
打开rc文件的源并搜索您的控件ID。搜索DLGINIT部分并将其复制到新对话框
答案 2 :(得分:1)
在我的情况下,我在调用
时输入了错误的Dialog IDBOOL Create(UINT nID, CWnd * pWnd);
DoDataExchange()
失败了。
答案 3 :(得分:1)
这是另一种可以获得相同的Debug Assersion警告的情况(错误:没有ID dlgdata的数据交换控制:第40行):
e.g。如果您通过虚函数CDialogExExample :: Create(CONTROL_ID,..)创建CDialogExExample的对话框实例,而CONTROL_ID与CDialogExExample头文件中的IDD_EXAMPLE(枚举{IDD = IDD_EXAMPLE};)不一致....那么可以添加控制总是失败。
此处an inspiring link from msdn !
可能对某人有帮助:))
PS:这种情况可能与@Hank Chang的回答相同
答案 4 :(得分:0)
就我而言,我有一个MFC对话框,它通过ActiveX托管.Net UI控件。
调试后发现,DoModal失败并返回-1,GetLastError给出0。
经过一天的调试后,结果证明是.Net Assemblies版本不匹配问题。这导致OLE控件实例化失败。
WinDBG摘录:
(21b0.71cc):CLR异常 - 代码e0434352(第一次机会) OLE控制的CoCreateInstance {EE3C4329-83A8-4DD8-A74C-680AC01AC593} 失败。
结果代码:0x80131040
HRESULT值0x80131040含义:
找到的程序集的清单定义与程序集引用不匹配。
答案 5 :(得分:-1)
在出现该确切错误后,我发现的解决方案是检查头文件中的类定义。 假设课程是
然后在下面的代码中
class CNewDlg : public CMyBaseDlg
{
DECLARE_DYNAMIC(CNewDlg)
public:
CNewDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CNewDlg();
// Dialog Data
enum { IDD = IDD_MYNEWDIALOGID };
检查该行:
enum { IDD = IDD_MYNEWDIALOGID };
确保您具有正确的ID。您收到的错误可能是由于从以前创建的控件/对话框的另一个头文件复制和粘贴代码而没有更新此ID的结果。
这应与您的.rc文件中对话框的定义匹配。例如:
IDD_MYNEWDIALOGID DIALOGEX 0, 0, 445, 314