您的位置:首页 > 其它

MFC程序运行时注册自身所需要的COM组件

2012-12-27 19:23 253 查看
我们可以在网上找到很多开发好的COM组件,这些组件提供了接口,我们可以对其进行二次开发,比如mp3play.ocx,通过这个控件,我们可以简单快速开发出自己的MP3播放器,COM组件可以是.ocx后缀,也可以是.dll后缀。熟悉VB开发的同志们对这些控件应该很熟悉吧。这些控件不仅可以用在VB中,同样可以用在VC等开发环境中。

在使用该控件时应该保证该电脑上已经注册了该控件。通常,我们都是通过安装包程序来调用regsvr32注册我们程序需要的控件。但由于我们开发的仅仅是只有一个exe和一个ocx的小程序,还要打包成安装包,未免太麻烦了。那么我们能不能在程序中加入代码,在刚运行时就注册该控件呢?答案当然是肯定的,不然就不会有那么多绿色软件了。

一开始我想到在程序中的InitInstance( );初始化实例函数中进行注册,写在构造窗体前,检测当前文件夹下是否有我们需要的控件,如果没有则直接MessageBox提示后退出程序。如果有的话用ShellExecute函数调用系统中的regsvr32.exe来注册我们的ocx控件。但是代码写好后,测试一下,暴露出一些问题,在没有注册过控件的电脑上运行时,出现了问题,DeBug版本下弹出错误提示然后程序崩溃退出。Release版本下双击无反应。我研究了好几个小时,无论把注册ocx的代码放到InitInstance(
)最前端还是放到窗体构造函数中,还是放到程序实例构造函数中。结果都是一样,依然存在问题。
仔细思考了一下,我们的程序在编译时,控件就已经拖到窗体中了,它已经静态的躺在资源里了,程序首次运行时,由于程序已经运行了,静态资源已经读入了内存,后来才进行注册,而我们的程序不知道系统中后来又注册了这个控件了,就出错了。
但后来我尝试不在编译时把控件拖到窗体上,而是通过代码,用new运算符创建一个ocx对应的类的对象,然后用该类提供的create( )函数在窗体上构造出该控件。但是运行时还是遇到一样的问题。不过有了改善,之前是一运行就崩溃,这样写以后,只是首次运行崩溃,再次双击运行就正常了。
经过我反复的试验,发现,在程序上添加一个按钮,程序运行后再单击这个按钮,这个按钮对应的响应函数中用new运算符创建一个ocx对应的类的对象,然后用该类提供的create( )函数在窗体上构造出该控件。这样,再也没出现崩溃的问题了。但是这样做明显太别扭,不可采用。
后来无意中在一本VC++实例的书上看到了有关COM组件的注册于卸载。我的问题终于圆满的解决了。书上是这样讲的。用LoadLibrary函数装载控件库文件,然后用GetProAddress函数检索指定的动态库中输出的库函数地址,然后调用该库函数。以注册mp3play.ocx为例。在程序InitInstance( )函数中构造窗体前加入这段代码:
HINSTANCE h;
	h = ::LoadLibrary(_T("Mp3play.ocx"));
	FARPROC pFunc = ::GetProcAddress((HMODULE)h,"DllRegisterServer");
	if (pFunc==NULL)
	{
		::MessageBox(NULL,_T("OCX控件加载失败!"),_T("错误"),MB_ICONERROR);
		return FALSE;
	}
	pFunc();

注意,如果GetProAddress函数返回了空地址,则注册失败。
卸载该控件时,把第二行代码中的DllRegisterServer改为DllUnRegisterServer即可。

在没有注册过该控件的电脑上运行,一次成功,没有出现过崩溃问题了。愁眉总算舒展了。问题完美解决,并且我们可以直接把控件拖到界面上了,也不用new运算符和create( )函数来构造控件实例了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐