龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > VC开发 >

VC++实现应用程序对插件的支持(3)

时间:2009-12-30 15:42来源:未知 作者:admin 点击:
分享到:
对于各个插件按钮的命令响应也不能以通常的ON_COMMAND宏执行命令映射,而要以ON_COMMAND_RANGE宏实现对一个ID范围的命令映射: BEGIN_MESSAGE_MAP(CMainFrame, CMDIFr

  对于各个插件按钮的命令响应也不能以通常的ON_COMMAND宏执行命令映射,而要以ON_COMMAND_RANGE宏实现对一个ID范围的命令映射:

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
……
ON_COMMAND_RANGE(ID_PLUG_POINTER, ID_PLUG_POINTER+256, OnPlugHit)
END_MESSAGE_MAP()
……
void CMainFrame::OnPlugHit(UINT nID)
{
int id = nID - ID_PLUG_POINTER;
if (id >= 0 && id < m_arrPlugObj.GetSize())
{
// 调用对应插件的功能函数。
if (m_arrPlugObj[id].pObj)
m_arrPlugObj[id].pObj->Interface(id);
}
}

  为保证系统资源的有效释放,在程序终止之前必须确保将加载过的所有插件资源予以释放:

for (int i = 0; i < m_arrPlugObj.GetSize(); i++)
{
if (m_arrPlugObj[i].pObj)
m_arrPlugObj[i].pObj->Release();
if (m_arrPlugObj[i].hIns)
FreeLibrary(m_arrPlugObj[i].hIns);
}
m_arrPlugObj.RemoveAll();

  至此,只要应用程序在PLUGINS子目录下发现了插件动态链接库的存在,就会将其装载到程序并通过工具条按钮完成用户同新添加插件的交互。如要从程序去掉某个插件只需在插件目录下将对应的插件模块删除即可。

  插件的制作

  插件的制作其实就是对动态链接库的创建,因此总的来说比较简单,但是作为插件载体的动态链接库与普通的动态链接库还是有一些区别的。例如,插件需要为主体应用程序提供图标,因此不仅在资源中要引入插件图标,而且在编译时还要将其设置为"Use MFC in a Static Library"以便在编译时能将所有的资源打包到插件模块,否则在应用程序插入插件时将无法在工具条按钮上绘制图标。插件在创建时同样也必须遵循其同主体程序的接口标准,这主要通过导出函数来体现的:

LIBRARY "PlugA"
DESCRIPTION 'PlugA Windows Dynamic Link Library'
EXPORTS
Plug_CreateObject @1

  导出函数Plug_CreateObject负责在应用程序中创建一个插件对象:

BOOL WINAPI Plug_CreateObject(void ** pobj)
{
*pobj = new CPlugA;
return *pobj != NULL;
}

  在前面已经提到过,CPlugA是基类CPlugBase的一个派生类,可以根据需要对CPlugBase的几个虚函数进行重载,以实现本插件所独有的一些功能。另外,由于主体程序是通过GetIcon()来获取插件图标的,因此必须在动态链接库被加载时首先通过LoadIcon()函数将图标装载到内存并保存其句柄于m_hIcon,等待主程序通过GetIcon()函数来获取,该句柄的释放在当动态链接库被释放时由函数DeleteObject()来执行。

  小结

  通过前述方法可以为普通应用程序添加插件支持功能,并可以在软件发布后以插件的形式对软件进行功能上的扩展,操作过程也比较灵活方便。由于经过这种扩展,使软件的各大功能模块分布于不同的插件,在软件升级或维护时只需对相应的插件进行替换即可,这对软件的升级维护可以起到积极的作用。本文所述程序在Windows 98下由Microsoft Visual C++ 6.0编译通过。

精彩图集

赞助商链接