插件機制讓軟件功能擴展不再侷限於廠商,第三方開發者遵循接口標準即可無縫整合,實現用戶個性化定制。同時便於模塊化升級維護,只需替換對應 DLL。
應用程式啟動時掃描指定目錄(如 Plugins)下的所有 .dll,動態加載;退出時釋放。
Plug_CreateObjectBOOL Plug_CreateObject(void** pobj) {
*pobj = new CPlugA;
return *pobj != NULL;
}
主程式調用此函數獲取插件對象指針。
CPlugBase 定義核心契約class CPlugBase {
public:
virtual HICON GetIcon() = 0; // 取得工具欄圖標
virtual void Interface(int k) = 0; // 功能入口
virtual void Release() = 0; // 釋放資源
};
PLUG_ST 與 CArraytypedef struct {
CPlugBase* pObj;
HINSTANCE hIns;
} PLUG_ST, *LPPLUG_ST;
CArray m_arrPlugObj;
CString strPath = ...\\Plugins;
CString strFind = strPath + _T("*.dll");
WIN32_FIND_DATA wfd;
HANDLE hf = FindFirstFile(strFind, &wfd);
if (hf != INVALID_HANDLE_VALUE) {
do {
CreatePlug(strPath + _T("\\") + wfd.cFileName);
} while (FindNextFile(hf, &wfd));
FindClose(hf);
}
CreatePlug 實現void CreatePlug(LPCTSTR szPlug) {
PLUG_ST st; ZeroMemory(&st, sizeof(st));
st.hIns = LoadLibrary(szPlug);
auto pFunc = (PFN_Plug_CreateObject)GetProcAddress(st.hIns, _T("Plug_CreateObject"));
if (pFunc && pFunc((void**)&st.pObj))
m_arrPlugObj.Add(st);
}
GetIcon() 返回的圖標加入。ID_PLUG_POINTER 起遞增,樣式 TBSTYLE_BUTTON。ON_COMMAND_RANGE 映射命令範圍至 OnPlugHit。OnPlugHit
void CMainFrame::OnPlugHit(UINT nID) {
int id = nID - ID_PLUG_POINTER;
if (id >= 0 && id < m_arrPlugObj.GetSize() && 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();
Use MFC in a Static Library),確保資源內嵌。Plug_CreateObject(.def 文件指定)。CPlugA : public CPlugBase,重寫虛函數;在 DllMain 或構造函數中 LoadIcon 並保存句柄,Release 時 DeleteObject。此架構實現了主程式與插件的完全解耦,支援無限擴展,且升級維護極為方便。