1、在ResourceView页中新增一对话框资源,命名为IDD_HELLOFORMVIEW,可以在对话框上放自己的控件;
2、设置对话框资源IDD_HELLODIALOG属性的Style页为Style:Child、Border:none;设置More Style页为Visible:unchecked; 为对话框资源IDD_HELLOFORMVIEW创建新类CHelloFormView,从CFormView继承;
3、在HelloFormView.h中将CHelloFormView的构造函数CHelloFormView()和析构函数virtual ~CHelloFormView()从protected改为public;
4、在HelloFormView.h中对CHelloFormView类加入public friend class CHelloCtrl;
5、确认在HelloCtrl.h中已加入语句#include "HelloFormView.h",为CHelloCtrl类添加成员变量CHelloFormView m_helloFormView;
6、修改CHelloCtrl::OnCreate函数,在此创建m_helloFormView;
7、修改DoHello代码,在此显示FormView;
int CHelloCtrl::OnCreate (LPCREATESTRUCT lpCreateStruct) {
if (COleControl::OnCreate(lpCreateStruct) == -1) return -1;
// 创建FormView
m_helloFormView.Create(NULL,NULL,AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL);
return 0;
}/////////////////////////////////////////////////////////
按照这种方法去做,在调试退出的时候总是会报错。错误信息如下:
HEAP[TSTCON32.EXE]: Invalid Address specified to RtlValidateHeap( 01470000, 01474B18 )
为什么呢???望高人指点。
其实你的ActiveX在使用Release方式编译的话就不会出来这个问题。 我查了半天 本来认为是因为CFrameView在销毁的时候有问题
可是最后跟踪了半天 错误并不是在ActiveX里面报出来的 而是ActiveX Control Test Container 也就是ActiveX调试容器报的错。
具体的原因可以参考下面的这段话:[size=8px]
如何解决“Invalid Address specified to RtlValidateHeap”错误:
一个可能的原因:在不同模块(工程)之间传递 C++ 类,而这两个模块用了不同的运行时库(Runtime Library)设置。例如:EXE 模块调用 DLL 模块里传递 C++ 类的函数,但 DLL 模块使用静态链接(Release 是 Multi-threaded (/MT)、Debug 是 Multi-threaded Debug (/MTd))方式编译,而 EXE 模块使用动态链接(Release 是 Multi-threaded DLL (/MD)、Debug 是 Multi-threaded Debug DLL (/MDd))方式编译。
可以对比这两个模块的工程属性 - C/C++ - Code Generation - Runtime Library,看看设置是否一样,如果不一样要改成一样的。
如果无法解决问题,那就是别的原因了。[/size]从这段话里面可以看出来了,原因就是ActiveX调试容器加载控件的OCX(跟DLL差不多)然后使用它,但是在最后释放它的时候,ActiveX调试容器清理内存时出现了失败。有一个方法可以解决了你的问题 但是不提倡:声明的时候声明成指针:CHelloFormView* m_helloFormView;
生成的时候:
int CFormAVCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
m_helloFormView = new CHelloFormView(); m_helloFormView->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL); return 0;
}但是在析构时候:
CFormAVCtrl::~CFormAVCtrl()
{
//if( NULL != m_helloFormView) delete m_helloFormView; //一般认为声明了指针最后是要释放内存的,但是这里这么做不行
}总之给人的感觉就是:这样使用FormView在内存管理上总会有一点问题,而且跟调用控件的程序有关系,如果我们在控件中对内存进行了释放操作的话,调用控件的程序就会说 不行!但是到它来释放内存的时候能不能释放干净我们又不知道! 所以不管是用那种调用形式 都可能生成内存碎片。当然只是可能。你可以试试那些加Doc/View类的方法来加FrameView 毕竟FrameView继承于CView 在析构的时候有一句void CView::OnDestroy()
{
CFrameWnd* pFrame = GetParentFrame(); //这句在ActiveX中使用返回总是NULL
if (pFrame != NULL && pFrame->GetActiveView() == this)
pFrame->SetActiveView(NULL); // deactivate during death
CWnd::OnDestroy();
}我觉得之所以直接用FrameView会出问题,这里是关键,可能因为没有跟CFrameWnd联系起来的CView都会出现这样的问题。不过既然使用Release没有问题 以后也肯定是用Release 这个问题也可以不管。 最后,跟你一起等高人解决吧!