
概述 1. 概述 Miranda 提供了一套非常灵活的
插件机制, 使得用户可以很方便的通过增减插件来添加或去除一些扩展功能. 源码里有一个testplug project, 演示了实现一个Miranda插件的基本方法,下面就通过对testplug project的
分析, 来学习Miranda的插件技术. 2. Miranda插件分类 基本插件: srmm.dll,clist_modern.
1. 概述 Miranda 提供了一套非常灵活的插件机制,使得用户可以很方便的通过增减插件来添加或去除一些扩展功能. 源码里有一个testplug project,演示了实现一个Miranda插件的基本方法,下面就通过对testplug project的分析,来学习Miranda的插件技术.
2. Miranda插件分类 基本插件: srmm.dll,cList_modern.dll,dbx_3x.dll 协议插件: jabber,msn,qq等 辅助插件: png2dib等
3. 一个插件需要实现的基本接口与变量
3.1.基本变量 这个通过分析testplug project可以很清楚的看到,一个插件有三个基本全局变量: HINSTANCE hInst;
//记录该插件的模块句柄 PLUGINlink *pluginlink; //用来登记通用的 *** 作插件的函数指针 PLUGININFO pluginInfo; //该插件的描述信息
3.2.基本接口 BOol WINAPI DllMain(HINSTANCE hinstDLL,DWORD fDWReason,LPVOID lpvReserved) {
hInst=hinstDLL; return TRUE; } //这是一个菜单命令的响应函数 static int PluginMenuCommand(WParaM wParam,LParaM lParam) {
MessageBox(NulL,"Just groovy,baby!","Plugin-o-rama",MB_OK); return 0; } __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) {
return &pluginInfo; } int __declspec(dllexport) Load(PLUGINlink *link) {
pluginlink=link;
//下面这段代码在主菜单里插入菜单项 "&Test Plugin..." //当单击该菜单项时PluginMenuCommand将被调用
CListMENUITEM mi; CreateServiceFunction("TestPlug/MenuCommand",PluginMenuCommand); ZeroMemory(&mi,sizeof(mi)); mi.cbSize=sizeof(mi); mi.position=-0x7FFFFFFF; mi.flags=0; mi.hIcon=LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); mi.pszname="&Test Plugin..."; mi.pszService="TestPlug/MenuCommand"; CallService(MS_CList_ADDMAINMENUITEM,(LParaM)&mi); return 0; } int __declspec(dllexport) Unload(voID) {
return 0; }
3.3.插件如何添加并响应自己的菜单命令 参考3.2 基本接口 中Load函数中加载菜单项 "&Test Plugin..."的方法.
4. 主要数据结构:
4.1.PLUGINlink typedef struct {
HANDLE (*CreateHookableEvent)(const char *); int (*DestroyHookableEvent)(HANDLE); int (*NotifyEventHooks)(HANDLE,WParaM,LParaM); HANDLE (*HookEvent)(const char *,MIRANDAHOOK); HANDLE (*HookEventMessage)(const char *,HWND,UINT); int (*UnhookEvent)(HANDLE); HANDLE (*CreateServiceFunction)(const char *,MIRANDASERVICE); HANDLE (*CreateTransIEntServiceFunction)(const char *,MIRANDASERVICE); int (*DestroyServiceFunction)(HANDLE); int (*CallService)(const char *,LParaM); int (*ServiceExists)(const char *); //v0.1.0.1+ int (*CallServiceSync)(const char *,LParaM); //v0.3.3+ int (*CallFunctionAsync) (voID (__stdcall *)(voID *),voID *); //v0.3.4+ int (*SetHookDefaultForHookableEvent) (HANDLE,MIRANDAHOOK); // v0.3.4 (2004/09/15) } PLUGINlink; extern PLUGINlink *pluginlink; #define CreateHookableEvent(a)
pluginlink->CreateHookableEvent(a) #define DestroyHookableEvent(a)
pluginlink->DestroyHookableEvent(a) #define NotifyEventHooks(a,b,c)
pluginlink->NotifyEventHooks(a,c) #define HookEventMessage(a,c)
pluginlink->HookEventMessage(a,c) #define HookEvent(a,b)
pluginlink->HookEvent(a,b) #define UnhookEvent(a)
pluginlink->UnhookEvent(a) #define CreateServiceFunction(a,b)
pluginlink->CreateServiceFunction(a,b) #define CreateTransIEntServiceFunction(a,b) pluginlink->CreateTransIEntServiceFunction(a,b) #define DestroyServiceFunction(a)
pluginlink->DestroyServiceFunction(a) #define CallService(a,c)
pluginlink->CallService(a,c) #define ServiceExists(a)
pluginlink->ServiceExists(a) #define CallServiceSync(a,c)
pluginlink->CallServiceSync(a,c) #define CallFunctionAsync(a,b)
pluginlink->CallFunctionAsync(a,b) #define SetHookDefaultForHookableEvent(a,b) pluginlink->SetHookDefaultForHookableEvent(a,b)
4.2.pluginEntry typedef struct pluginEntry {
char pluginname[64]; //插件的名称
unsigned int pclass; // PCLASS_* BASIC_PLUGIN_INFO bpi; struct pluginEntry * nextclass; } pluginEntry;
4.3.PLUGININFO typedef struct {
int cbSize; char *shortname; DWORD version; char *description; char *author; char *authorEmail; char *copyright; char *homepage; BYTE isTransIEnt; //leave this as 0 for Now int replacesDefaultModule; //one of the DEFMOD_ constants in m_plugins.h or zero //if non-zero,this will supress the loading of the specifIEd built-in module //with the implication that this plugin provIDes back-end-compatible features } PLUGININFO;
4.4.BASIC_PLUGIN_INFO typedef struct { // can all be NulL
HINSTANCE hInst; Miranda_Plugin_Load Load; Miranda_Plugin_Unload Unload; Miranda_Plugin_Info Info; Database_Plugin_Info DbInfo; CList_Initialise cListlink; PLUGININFO * pluginInfo; // must be freed if hInst==NulL then its a copy DATABASElink * dblink; // only valID during module being in memory } BASIC_PLUGIN_INFO;
5. 主要全局变量: SortedList pluginList = { 0 }, pluginListAddr = { 0 }; PLUGINlink pluginCorelink; char
mirandabootini[MAX_PATH]; static DWORD mirandaVersion; static pluginEntry * pluginListDb; static pluginEntry * pluginListUI; static pluginEntry * pluginList_png2dib = NulL; static HANDLE hPluginListHeap = NulL;//插件用到的堆 static pluginEntry * pluginDefModList[DEFMOD_HIGHEST+1]; // do not free this memory static int askAboutIgnoredplugins;
6. 辅助函数: 3.1 HINSTANCE GetInstByAddress( voID* codePtr )
根据一个函数的地址返回函数所在的模块的句柄
3.2 enumPlugins(scanPluginsDir,0);
枚举所有的插件
3.3 checkAPI
动态加载一个插件,并检查该插件的API函数
Load,Unload,MirandaPluginInfo 三个基本的API函数 总结
以上是内存溢出为你收集整理的Miranda插件分析全部内容,希望文章能够帮你解决Miranda插件分析所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
评论列表(0条)