如何在Activex中引入FormVeiw?网上常见的一种方法似乎有问题,高手请进帮忙看看。

blizardskb8 2008-11-18 07:20:01

  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 )
为什么呢???望高人指点。
...全文
129 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
blizardskb8 2008-11-20
  • 打赏
  • 举报
回复
回去试试
blizardskb8 2008-11-20
  • 打赏
  • 举报
回复
向你学习ing,多谢
Tinary3v0 2008-11-19
  • 打赏
  • 举报
回复
试验了一下 楼主说的问题确实存在
其实你的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 这个问题也可以不管。

最后,跟你一起等高人解决吧!

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧