MFC创建和使用OCX控件

⌚Time: 2023-08-09 19:00:29

👨‍💻Author: Jack Ge

MFC建立OCX控件

新建一个MFC ActiveX控件

一直点下一步,完成

在类视图可以看到系统创建了三个类CtestOcxApp、CtestOcxCtrl、CtestOcxPropPage、和一个接口testOcxLib

在控件的OnDraw函数里面,简单的绘制一个背景


void CtestOcxCtrl::OnDraw(

            CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)

{

    if (!pdc)

        return;



    // TODO: 用您自己的绘图代码替换下面的代码。

    CRect rect;

    GetClientRect(rect);



    COLORREF clr = RGB(74, 65, 42);

    pdc->FillSolidRect(1,1,300,300, clr);

}

添加WM_CREATE消息处理函数,在创建时添加一个按钮


int CtestOcxCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

    if (COleControl::OnCreate(lpCreateStruct) == -1)

        return -1;



    // TODO:  在此添加您专用的创建代码

    CButton *MyBtn = new CButton();

    MyBtn->Create(L"button11", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, CRect(50, 50, 180, 120), this, 10001);

    return 0;

}

添加一个按钮消息响应函数

声明


// 消息映射

    afx_msg void OnMyBtnClicked();//按钮响应

    DECLARE_MESSAGE_MAP()

实现


void CtestOcxCtrl::OnMyBtnClicked(){

    AfxMessageBox(L"你点击了按钮");

}

建立消息映射


// 消息映射

BEGIN_MESSAGE_MAP(CtestOcxCtrl, COleControl)

    ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)

    ON_WM_CREATE()

    ON_BN_CLICKED(10001, OnMyBtnClicked)//按钮ID与函数的消息映射

END_MESSAGE_MAP()

现在按F7生成解决方案。可能会有提示


error PRJ0050: 未能注册输出。请确保您有修改注册表的相应权限。

是因为没有管理员权限(UAC)导致,并不影响,之后手动注册ocx控件就行了

注册OCX控件与反注册

搜索cmd,右键管理员身份运行

输入下面的命令注册OCX控件


regsvr32.exe "D:\ProjectSpace\Visual Studio 2005\testOcx\debug\testOcx.ocx"

输入下面的命令反注册OCX控件


regsvr32.exe /u "D:\ProjectSpace\Visual Studio 2005\testOcx\debug\testOcx.ocx"

其中的路径根据ocx路径修改

使用Internet Explorer测试ocx控件

ocx控件web端使用只能在ie浏览器中运行,编写下面的代码,保存成html格式


<!DOCTYPE html>

<html>

<head> 

<meta charset="utf-8"> 

<title>ocx调用演示</title> 

</head>

<body>

<OBJECT id="MyOcxDemo" classid="clsid:E981DEB8-00E9-4FC7-B565-FBCC9FFC264C" width="300" height="300"></OBJECT>

</body>

</html>

width="300" height="300"表示控件大小

其中的classid在testOcx.idl里面,类信息里面的uuid


    //  CtestOcxCtrl 的类信息



    [ uuid(E981DEB8-00E9-4FC7-B565-FBCC9FFC264C),

      helpstring("testOcx Control"), control ]

    coclass testOcx

    {

        [default] dispinterface _DtestOcx;

        [default, source] dispinterface _DtestOcxEvents;

    };

使用ie浏览器打开,会提示Internet Explorer已限制Activex控件,点击允许阻止的内容。就会显示OCX控件了,点击按钮会有弹出提示

OCX控件添加方法

在testOcxLib下面的_DtestOcx,右键,添加,添加方法

设置返回值类型,方法名,添加两个double类型的参数

点完成

实现该方法


DOUBLE CtestOcxCtrl::add_two_double(DOUBLE arg0, DOUBLE arg1)

{

    AFX_MANAGE_STATE(AfxGetStaticModuleState());



    // TODO: 在此添加调度处理程序代码



    CString str;

    str.Format(L"%lf+%lf=%lf",arg0,arg1,arg0+arg1);

    AfxMessageBox(L"你调用了add_two_double:"+str);



    return arg0 + arg1;

}

OCX控件添加事件

类视图里面,对于控件类CtestOcxCtrl,右键,添加,添加事件

可以选择预定义的事件,完成

之后再添加一个MouseMove事件

在_DtestOcxEvents中可以看到自己添加的事件

Web使用OCX控件

编辑html文件,显示OCX和调用里面的函数


<!DOCTYPE html>

<html>

<head> 

<meta charset="utf-8"> 

<title>ocx调用演示</title> 

<script>

function testOCX()

{

  var myOcx=document.getElementById("MyOcxDemo");

  if(myOcx){

    alert("add_two_double(1,2)="+myOcx.add_two_double(1,2));

  }

}

</script>

</head>

<body>

<OBJECT id="MyOcxDemo" classid="clsid:E981DEB8-00E9-4FC7-B565-FBCC9FFC264C" width="300" height="300"></OBJECT>

<button onclick="testOCX()">调用方法</button>

</body>

</html>


MFC使用OCX控件

建立OCX控件

新建一个mfc项目testOcxUse

在窗体上右键,添加ActiveX控件,可以看到注册后的ocx控件,选择自己建立的ocx控件

突然提示崩溃

因为只有在窗体创建完成后,才可以获得窗体句柄,而MFC控件要根据OnDraw显示窗体样式

之前的OnDraw函数


void CtestOcxCtrl::OnDraw(

            CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)

{

    if (!pdc)

        return;



    // TODO: 用您自己的绘图代码替换下面的代码。

    CRect rect;

    GetClientRect(rect);



    COLORREF clr = RGB(74, 65, 42);

    pdc->FillSolidRect(1,1,300,300, clr);

}

直接调用了OnDraw的GetClientRect函数,由于没有创建窗体,GetClientRect获取窗体空句柄崩溃。

直接改变OnDraw函数


void CtestOcxCtrl::OnDraw(

            CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)

{

    if (!pdc)

        return;



    // TODO: 用您自己的绘图代码替换下面的代码。

    HWND hAppWnd = NULL;

    if (m_pInPlaceSite != NULL){

        m_pInPlaceSite->GetWindow(&hAppWnd);

    }

    CRect rect;

    ::GetClientRect(hAppWnd, rect);

    COLORREF clr = RGB(74, 65, 42);

    pdc->FillSolidRect(rect, clr);



}

之后添加控件就没有了崩溃问题,但是并不会显示填充的背景颜色,因为并没有获取到窗体客户区范围。也没有显示按钮,因为按钮是动态建立的。

后来我发现,系统自带的方法在OnDraw是


void CaaaaaaaaaaCtrl::OnDraw(

            CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)

{

    if (!pdc)

        return;



    // TODO: 用您自己的绘图代码替换下面的代码。

    pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));

    pdc->Ellipse(rcBounds);

}

OnDraw它的第二个参数rcBounds代表窗体区域,直接改成


void CtestOcxCtrl::OnDraw(

            CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)

{

    if (!pdc)

        return;



    // TODO: 用您自己的绘图代码替换下面的代码。



    COLORREF clr = RGB(74, 65, 42);

    pdc->FillSolidRect(rcBounds, clr);



}

就行了,直接显示了控件的背景色

点击运行,就可以了,点击按钮弹出消息提示

ocx控件添加变量

为了调用ocx控件的功能,需要为控件添加一个类成员变量。有两种办法

方式一:

点击项目,添加类,选择MFC,ActiveX控件中的MFC类

从可用的Activex控件中选择测试的ocx控件,选择左侧的接口,点击中间的>箭头,移到右边生成的类,点击完成

系统会自动生成CDtestOcx类,对应的头文件CDtestOcx.h、源文件CDtestOcx.cpp

在使用OCX控件的窗体类头文件中包含头文件


#include "CDtestOcx.h"

在窗体类中定义OCX控件变量


public:

    CDtestOcx m_testOcx;

在窗体的DoDataExchange函数中建立变量与控件资源的数据交换,IDC_TESTOCXCTRL1是窗体OCX控件资源ID,m_testOcx是添加的变量


void CtestOcxUseDlg::DoDataExchange(CDataExchange* pDX)

{

    CDialog::DoDataExchange(pDX);

    DDX_Control(pDX, IDC_TESTOCXCTRL1, m_testOcx);

}

添加变量完成了

方式二:

对于ocx控件右键,添加变量,起名字,点完成,系统会自动生成一个CTestocxctrl1的类。它的头文件是testocxctrl1.h,源文件testocxctrl1.cpp。自动用这个类在窗体类内创建成员变量、建立和控件的数据交换。这种办法更加的快捷简单

调用ocx的功能函数

在界面上添加一个按钮,点击它调用ocx的add_two_double功能


void CtestOcxUseDlg::OnBnClickedButton1()

{

    // TODO: 在此添加控件通知处理程序代码

    m_testOcx.add_two_double(1.0f, 2.0f);

}

之后运行

对ocx的事件响应

右键ocx控件,添加事件处理程序,可以看到之前添加的两个事件

对click消息进行处理


void CtestOcxUseDlg::ClickTestocxctrl1()

{

    // TODO: 在此处添加消息处理程序代码

    MessageBox(L"你点击了ocx控件区域");

}

运行程序

OCX控件调试工具tstcon32.exe

加载ocx控件

使用tstcon32.exe调试OCX控件,它在VS安装文件夹下:

C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools

点击编辑,插入新控件,可以找到已经注册的ocx控件

鼠标在控件上移动和点击,可以看到对已经添加事件的监听,click和mousemove

点击控件,调用方法,可以调用控件方法

使用tstcon32.exe调试ocx

VS2005中点击项目,属性,配置属性,调试,命令,设置ActiveX控件测试容器的的路径

直接点击调试按钮,会提示无法找到tstcon32.exe的调试信息,询问是否继续,不用管。点击是。

之后会弹出tstcon32程序,按照之前的步骤,添加控件,然后触发控件设置断点的地方,会自动运行到断点然后停住

这里我在弹出提示框的地方设置断点,然后点击按钮,在断点处停住了。


提示:

注意生成的OCX控件Debug版本和Release版本、位数要和使用的程序保持一致