COM1 --- 小例子

测试环境: VS2008 + SP1 补丁     XP 32位系统

1、启动VS2008,新建项目,如图

2、再次新建项目,如图

需要注意的就是  在 Solution 那里 选择 Add to Solution ,同时,上面的 Location 会自动定位到当前的解决方案里。这个项目,直接点击Finish 结束就行了。

3、将视图切换到文件视图(View 菜单中的 Solution Explorer) ,如图

可以看到这里面有 类似 文件夹的 东东,,它们是 Filter  就是将某一些相同类型的文件 整理在一起的功能,我们将它们全部折合起来。

还有一点,我们会看到这里有两个项目 ,带 PS 的那个,我们暂时用不到,直接 在 它上面 右击,选择 Remove 即可 ,这样,我们这个解决方案里就只有一个 项目 了。

然后,我们 选中 QMath 这个 项目 ,然后在 Project菜单项 中 选择 Add Class ,为它添加一个类

左边选择 ATL ,右边选择 ATL SIMPLE OBJECT 。然后点击 ADD。

在弹出的对话框中,只需要要在  C++  SHORT NAME 中 写上 QPrimerMath  即可,

然后点击下一步,这里比较重要,我们一定要选择  Custom

然后就可以点击 Finish了。

切换到类视图,我们可以看到 多了 两个东东,,一个 是 I.... ,这个就是接口啦,一个是C...,这个就是组件类了。

然后,我们要为 接口添加 方法 ,在接口 上右击 ,选择  Add  -->  Add Method 弹出图示对话框

在这里面,我们可以 为 我们的接口添加 方法 ,这个 地方的步骤 ,我还是一步一步写下来吧,

1、输入 方法名 ,如 Add

2、点击 in  ,然后 参数类型 输入  LONG  参数名称 输入 nA,然后点击Add ,这样就添加了一个输入参数,然后再次点击 in ,同之前的操作一样,添加第二个参数,nB ,在COM 中 返回值是要用指针往外带值的,但是我们看到 retval  这个参数属性又是灰掉的,,肿么办?  先在 参数类型中 输入  LONG* ,然后你就看到 out 和 retval 都可以用了,然后输入 参数名,其它的都一样操作了。

这样来理解一下,这个函数 叫  Add, 有两个输入参数,一个通过指针向外带的 返回值,OK。

然后直接 点击 Finish 就可以了。

在整个过程中,时刻要记得保存代码。

下面,我们就在  组件类中 实现代码

双击 这个 Add 方法,然后为它 写上 实现代码。

好了,然后我们 迅速的 再 做 其它 4 个 方法 ,,Sub,Mul,Div,Mod

,,,,等等,,迅速,怎么迅速呢?当然是 手工添加啦,因为这些函数  参数都是类似的,,只是函数名 和 实现代码不同而以。

1、为 接口  添加上 其它 4 个方法 ,如何快速呢? 这里要告诉你几个小技巧,快速复制一行,鼠标只要在当前行,按下 CTRL + C 就复制了当前行,不需要选中哦。双击 接口 中的 Add 的声明 ,定位到了如下 位置

其实它里面就 一行,

[helpstring("method Add")] HRESULT Add([in] LONG nA, [in] LONG nB, [out,retval] LONG* nResult);
我们只要将 光标 定位 到这一行,注意,不要选中 任何东东,,直接 CTRL + C ,然后 CTRL + V 四次。 效果如下图

哈哈,是不是 很方便 ,然后 就是 修改函数名,这里也有小技巧,,就是 块选,我先演示一下效果,

不只是可以 块选择,还可以块复制 和 粘贴 ,所以嘛,你懂的,,先改 前面的 五个,然后 复制,然后再 选中 后面的 五个,再 粘贴,那么到底怎么块选择呢,技巧就是 在选择的时候 按住 ALT 键。

其实很多编辑类的软件都提供了这一功能哦,比如 NOTEPAD++。

接口中 声明了 这五个方法 了,,在 组件类 中 也要 进行声明 ,并且 还要实现它们的功能。

直接打开组件类对应的 头文件, 或者  直接 双击 组件类 的类名 也可以,在这里面,我们可以找到 如下图所示的 Add函数声明

所以嘛,其它的我也不用说了,你都会了,不要忘记 块操作哦。

OK,类中,我们也声明完了,,接下来,我们就是 要到 类中 实现 操作了。其实,在这里,还有小技巧,那就是 VS中快捷键的 定制,我相信你,如果看到这里了,你的VS 应该是 安装有 VAX 插件了,,。没有的话,你可以百度一下 VS2008 VAX 插件了。

然后我们  点击  工具 菜单下   自定义 ,弹出

点击 左下角 的 键盘,

在 Show commands containing 中 输入 VAssistX.RefactorCreateIm  ,下面的列表中 就会只剩余一项了,然后 在下面 可以为它 指定  加速键 ,我指定为 了 CTRL + Q,按两次。

好了,我相信你可以搞定它。

那么这个功能是做什么用的呢,说白了 就是 为我们 自动 添加 实现代码的,,然后我们将 鼠标 放在 组件类 中 声明 的  Sub 方法 上, 按下 上面的  加速键, 会发现,CPP文件中 自动添加了

如下的 代码

这个时候,如果我们 按 CTRL + TAB  键,则会 切换 加  头文件中,按一下 下方向键,就会定位到 Mul 这三个字母上,然后再 CTRL + Q 两次,是不是很方便呢。

快速添加完五个函数的实现。

同时呢,我们的五个 函数的 具体实现 也 差不多,只是 运算符不一样而以,复制行,粘贴,但是在粘贴的时候要注意,这个 复制行 在复制的时候 ,将换行符也复制了,,而且在 粘贴的时候 是 将数据 粘贴在 鼠标所在 当前行的 上一行。

所以,我们先 将 鼠标 放在

*nResult = nA + nB;   这一行上

然后 复制,

STDMETHODIMP CQPrimerMath::Sub( LONG nA, LONG nB, LONG* nResult )
{
    return S_OK;    然后将鼠标 放在 这一行上,再 粘贴

}

上面都是一些技巧,掌握了这些技巧 ,你的效率会高出很多哦。

由于 除法中  nB 是不可以 为0 的,,但是我们只是 为了演示 ,不做 特殊处理。

这样,我们就 制作了一 个 组件类了,,是不是感觉 很棒呢。

我们编译生成一下。然后大家去网上下载一个 OLEVIEW 的工具,,VS2008中好像没有,但 2010中又有了。

打开这个工具,

然后点击 工具栏中 3个红色箭头的 图标,然后,打开我们生成的 DLL 文件

好,我们按上面的方法 ,再添加一个组件类,名字叫做 QAdvancedMath  ,注意一定要选择 CUSTOM 。

为它添加 一个 求 阶乘的 方法。

很简单,然后我们再生成 一下。

哦,我的生成出错了。

1>LINK : fatal error LNK1168: cannot open Debug\QMath.dll for writing

这是因为我的OLEVIEW 还在使用着 这个DLL,所以 要关掉它。

然后再生成 就OK了。

再用工具查看一下

我们发现,我们这里有两个 COCLASS,也叫做 组件类,下面,我们要 来 画一下,这里面的 继承关系

好,这就是 它的 最基本的 继承 图表啦。。当然 ,中间的 两个 接口 还 继承了 其它 的 接口,这个暂时不讨论它。

上图中 的 第三层,,是表示  组件类的,,每个组件类 都有一个 类ID,也叫 CLSID ,其形式 表示为  CLSID_类名 ,但是类名 是要 去年 最前面的 字母 C 的。

上图中 的 第二层,,是表示  接口的,每个接口也都有一个 接口ID,也叫 IID,其形式 表示 为

IID_I类名 ,但是类名 是要 去年 最前面的 字母 C 的。

因为组件类 是 二进制 共享的 ,所以 每个  组件类 实现的 功能 只能由 接口负责 调用,为了区分开 所有的 组件类,就使用了上面的 类ID 和 接口ID。

在OLEVIEW 里,可以看到它们的具体定义。

好了,既然是 共享使用的,那么我们就演示一下 在MFC 中 如何使用 它。

点击 File -- Add -- Add New Project  选择MFC  应用程序,

下面的有一步 要对着 下图 所示进行选择

这里选择 Active Accessibility 主要是 让 MFC 做 COM 的自动 初始化 ,加上这句话后,在

BOOL CTestQMathApp::InitInstance()  中 会添加如下 语句。

if (!AfxOleInit())
    {
        AfxMessageBox(IDP_OLE_INIT_FAILED);
        return FALSE;
    }

然后,我们 在对话框 中 添加 两个 按钮

ID 分别为

IDC_BTN_PRIMER_MATH  
IDC_BTN_ADVANCED_MATH
标题分别为

Test Primer Math
Test Advanced Math

添加响应函数

void CTestQMathDlg::OnBnClickedBtnPrimerMath()
{
    IQPrimerMath *    pPrimerMath = NULL;
    HRESULT  hr = CoCreateInstance(CLSID_QPrimerMath,NULL,CLSCTX_INPROC_SERVER,IID_IQPrimerMath,(LPVOID *)&pPrimerMath);
    if (FAILED(hr))        return;

    LONG n1 = 100,n2 = 25, nResult = 0;
    pPrimerMath->Add(n1,n2,&nResult);
    pPrimerMath->Sub(n1,n2,&nResult);
    pPrimerMath->Mul(n1,n2,&nResult);
    pPrimerMath->Div(n1,n2,&nResult);
    pPrimerMath->Mod(n1,n2,&nResult);

    pPrimerMath->Release();

    CoFreeUnusedLibraries();
}

void CTestQMathDlg::OnBnClickedBtnAdvancedMath()
{
    IQAdvancedMath    * pAdvancedMath = NULL;
    HRESULT  hr = CoCreateInstance(CLSID_QAdvancedMath,NULL,CLSCTX_INPROC_SERVER,IID_IQAdvancedMath,(LPVOID *)&pAdvancedMath);

    if (FAILED(hr))        return;

    LONG    nVal = 10 ,nResult = 0;
    pAdvancedMath->Factorial(nVal,&nResult);
    
    SetDlgItemInt(IDC_BTN_ADVANCED_MATH,nResult);
    pAdvancedMath->Release();
    CoFreeUnusedLibraries();
}

好了,一编译会出很多错误。

这是为什么呢,因为我们没有引入相关的定义,这些定义在哪里呢? 我们DLL 项目中 还有一个过滤器呢,就是它们两个啦,只要将它们  加入 我们 的 对话框 项目 中就 可以了。

#include "../QMath/QMath_i.h"
#include "../QMath/QMath_i.c"

好了,最后呢,我们的代码 还是有一个小问题呢,,就留给大家去发现,,去解决啦。。。

TIPS:  就是 求 阶乘 那里,,,我们没有 对 *nResult 赋值为 1,所以结果 一直是 0.。大家自己改改吧,,我们不是来说明这些东西的,,大家要弄清楚 重点。

好了,,就倒这里,,,2个半小时 过去了。。。

COM1 --- 小例子

时间: 2025-01-16 09:32:49

COM1 --- 小例子的相关文章

COM2 --- 小例子

在COM1 的小例子中,,我们大概知道什么是组件类 ,什么是接口了.这小节呢,我们来实现一下由一个组件类去实现两个接口的过程. 新建项目: 我们的 解决方案的 名字是 ComDemoCode ,项目名字是 MathToolKit  这表示 我们的 项目 自动 生成的 DLL  的名字就是 MathToolKit(数学工具包). 我们的继承关系 有必要 给大家 先 列出来,让大家 看看 在这里面,IPrimerMath接口 提供 + - * / % 五个基本运算方法,IAdvanceMath接口提

laravel 数据库操作小例子

public function demo() { $res = null; //insert数据插入 //$user=array('username'=>'joy','password'=>'123456','age'=>23); //$res = DB::table('users')->insert($user); /* 数据查询 $res = DB::table('users')->where('username','joy')->get(); $res = DB:

spring小例子-springMVC+mybits整合的小例子

这段时间没更博,找房去了...   吐槽一下,自如太坑了...承诺的三年不涨房租,结果今年一看北京房租都在涨也跟着涨了... 而且自如太贵了,租不起了.. 突然有点理解女生找对象要房了..   搬家太受罪了... 今天更一下springMVC整合mybits形成最简单的网站demo. 大概效果就是这样的:左边是数据库查询结果,右边是页面访问结果: 首先,一个简单的springMVC小例子可以看这个http://www.cnblogs.com/xuejupo/p/5236448.html 这是在这

cmake 之一个小例子

cmake,比手写makefile更好的选择 安装cmake,此部分略过 一.新建一个工程 这里我是在windows下使用eclipse新建了一个c工程(PS:我一般新建一个Makefile类型的工程,这样比较干净) 二.建立必要的文件夹 我的工程目录: D:\code\cpp\cmakestudy\test>tree /f 卷 软件 的文件夹 PATH 列表 卷序列号为 0006-17B7 D:. │ .cproject │ .project │ CMakeLists.txt │ ├─bin

简述人脸特异性识别&&一个基于LBP和SVM的人脸识别小例子

原谅我用图片,MAC在Safari里给文章进行图文排版太麻烦啦~ 本文适合初入计算机视觉和模式识别方向的同学们观看~ 文章写得匆忙,加上博主所知甚少,有不妥和勘误请指出并多多包涵. 本文Demo的代码由HZK编写,特征点由月神和YK选择和训练. 转载请注明 copyleft by sciencefans, 2014 为了方便大家学习,附上高维LBP的核心代码 1 ################################################### 2 # 3 # 4 # NO

python try小例子

#!/usr/bin/python import telnetlib import socket try: tn=telnetlib.Telnet('10.67.21.29',60000) except socket.error, e: print e exit(1) tn.set_debuglevel(1) tn.write('quit'+'\n') print 'ok' socket.error为错误类型 e为对象 python try小例子,布布扣,bubuko.com

C/C++ New与Delete (小例子)

转自:http://blog.csdn.net/chenzujie/article/details/7011639 先来看两段小程序: 1). #include <iostream.h> #include <String.h> void main(void) { char *str1 = "just have fun"; char *str2 = "happy day"; char *sTmpPtr = new char[255]; char

一个php多态性的小例子

多态性在 OO 中指 "语言具有以不同方式处理不同类型对象的能力",但 PHP 是弱类型语言,在这一点上就比较弱,仅有 instance of 可以用于判断对象的类型 多态性的优点:让代码更接近生活中的真实情况 一下是一个非常简单的多态性例子,描述在电脑上安装不同操作系统,linux, OS X, windows 和 computer 是两种不同类型的对象. interface os{ function name(); function creator(); } class linux

用两个小例子来解释单例模式中的“双重锁定”

学习单例模式时,好多人都不太理解双重锁定.学完后突然想到一个很有趣的例子. 单例模式结构图: 代码: Singleton类 class Singleton { private static Singleton instance; private static readonly object syncRoot = new object(); //程序运行时创建一个静态只读的进程辅助对象 private Singleton() { } //用private修饰构造方法,防止外界利用new创建此类实例