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 )
为什么呢???望高人指点。

解决方案 »

  1.   

    试验了一下 楼主说的问题确实存在
    其实你的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 这个问题也可以不管。 最后,跟你一起等高人解决吧!