MFC Doc/View结构实现ActiveX控件

来源:互联网 发布:淘宝上怎么买qq号 编辑:程序博客网 时间:2024/06/10 19:24

 背景:

最近在一个项目中,要使用一个第三方用VC6.0开发的基于doc/view结构的DLL(这个第三方库是通过MFC的CView类来实现地图的显示功能),现在要在Vs2008的环境下加载该库,并作进一步扩展,在显示的地图上进行绘图、移动等操作。

解决该问题的直接方案是:直接使用MFC应用程序,动态加载第三方库,从第三方库中提供的View类中派生子类,实现扩展功能,但由于微软不同版本的Vs对MFC扩展功能不兼容,所以没法在Vs2008中直接加载这个第三方库。

换一种方案:使用VC6.0将该第三方库封装成ActiveX控件,在Vs2008的应用程序中直接加载封装好的ActiveX,然后在Vs2008中开发扩展功能。这样就将加载第三方库的操作放到了独立的ActiveX中,就避免了不兼容的情况,同时,该ActiveX还可以和Qt集成,后续的扩展功能也可以使用Qt来开发。

接下来的问题是:MFC并没有在ActiveX控件中为doc/view结构提供一个模板类,因此有了本文的内容。

 

在一个独立的MFC应用程序中,只需要简单的创建一个CSingleDocTemplate类或一个CMultiDocTemplate类,调用它们的AddDocTemplate函数,就能让doc/view结构跑起来。但是,如果直接使用这些类去创建一个ActiveX控件,将会是一个无父窗口的、带有WS_OVERLAPPED窗口样式的带菜单栏的框架窗口,所以需要重新实现这个doc模板类,根据资料DesigningActiveX Components with the MFC Document/ViewModel的描述,只需要重新定义两个类CActiveXDocTemplate和CActiveXDocControl,如下所示,这两个类分别从CSingleDocTemplate和COleControl派生(类的实现源码请参考链接:文档视图结构实现的ActiveX控件源码中的ActivDoc文件):

class CActiveXDocTemplate :public CSingleDocTemplate{…

class CActiveXDocControl :public COleControl{…

然后就可以很容易地在一个ActiveX控件中使用doc/view结构模型了(原理性解释请参见前一个链接)。

 

接下来看看怎么使用定义好的两个类来开发一个通过鼠标移动来绘制椭圆的ActiveX控件:

1、使用MFCAppWizard(exe)创建单文档的应用程序“AxApp”,并在doc/view模式下的View类的鼠标移动消息响应函数中实现绘制椭圆的功能,代码如下所示:
voidCAxAppView::OnMouseMove(UINTnFlags, CPoint point)
{
    // TODO: Add your message handler code here and/orcalldefault
   if(!m_State)
       return;

    CDC* pDC =GetDC();
   if (!pDC)
       return;

    CRectCliRect;
   GetClientRect(&CliRect);

   CDC    MemDC;
    CBitmapMemBmp;

   if (!MemDC.CreateCompatibleDC(pDC))
       return;

   if (!MemBmp.CreateCompatibleBitmap(pDC,CliRect.Width(),CliRect.Height()))
       return;

    CBitmap* pOldBmp = MemDC.SelectObject(&MemBmp);
   MemDC.FillSolidRect(&CliRect,RGB(255,255,255));
   MemDC.Ellipse(m_StartPt.x, m_StartPt.y,point.x, point.y);

   pDC->BitBlt(0,0, CliRect.Width(), CliRect.Height(),&MemDC,0,9,SRCCOPY);

   MemDC.SelectObject(pOldBmp);
   MemBmp.DeleteObject();

   ReleaseDC(pDC);
   
   CView::OnMouseMove(nFlags,point);
}

void CAxAppView::OnLButtonDown(UINTnFlags, CPoint point)
{
    // TODO: Add your message handler code here and/orcalldefault
   m_StartPt = point;
   m_State   = true;
   
   CView::OnLButtonDown(nFlags,point);
}

void CAxAppView::OnLButtonUp(UINTnFlags, CPoint point)
{
    // TODO: Add your message handler code here and/orcall default
    m_State= false;
   CView::OnLButtonUp(nFlags,point);
}

2、使用MFCActiveX ControlWizard,采用默认设置,创建一个ActiveX工程“AxDemo”;

3、将“AxDemo”工程中从COleControl派生的类CAxDemoCtrl改为从CActiveXDocControl派生,利用IDE的查找替换功能将整个工程源码中所有使用类COleControl的地方都替换成CActiveXDocControl;

4、将已定义好的类CActiveXDocTemplate和CActiveXDocControl所在的文件“ActivDoc.h”和“ActivDoc.cpp”加到工程“AxDemo”中,然后将头文件“ActivDoc.h”包含到类CAxDemoCtrl的头文件中;

5、拷贝第1步完成的单文档应用程序“AxApp”的框架类文件(*frm.cpp,*frm.h),文档类文件(*doc.cpp,*doc.h),视图类文件(*view.cpp,*view.h)到“AxDemo”工程目录下,并将这些文件加入到“AxDemo”工程中,然后编译“AxDemo”工程,将三个包含单文档应用程序头文件“#include"AxApp.h"”的错误改为包含ActiveX控件头文件“#include"AxDemo.h"”;

6、删除掉CMainFrame类的OnCreate函数中工具栏“m_wndToolBar”和状态栏“m_wndStatusBar”两个控件“Create”的代码,改为如下所示:
int CMainFrame::OnCreate(LPCREATESTRUCTlpCreateStruct)
{
   if (CFrameWnd::OnCreate(lpCreateStruct)==-1)
       return-1;

   return0;
} 

7、最关键的一步,修改ActiveX控件类“CAxDemoCtrl”的构造函数代码,实现文档视图框架自动创建的功能,改为如下所示:
CAxDemoCtrl::CAxDemoCtrl()
{
   InitializeIIDs(&IID_DAxDemo,&IID_DAxDemoEvents);
   SetInitialSize(200,200);

    // TODO: Initialize your control's instance datahere.
   AddDocTemplate(new CActiveXDocTemplate(
       RUNTIME_CLASS(CAxAppDoc),
       RUNTIME_CLASS(CMainFrame),
       RUNTIME_CLASS(CAxAppView)));
}

源码请参考:http://download.csdn.net/detail/q342210738/6753935 

或者:http://ishare.iask.sina.com.cn/f/38170963.html

 

关于使用VisualC++开发ActiveX控件的具体步骤和细节请参考:http://www.cnblogs.com/beer/archive/2010/08/21/1805462.html

0 0