Author: du chunhui
Download source code
I. There are articles about the implementation of common DLL plug-ins in the VC knowledge base, but this method is not used in many large software (such as ArcGIS and office, com-based plug-ins are widely used in today's large-scale software.
2. Implementing plug-ins is inseparable from three elements
- Plug-in Manager (that is, the main program to use these plug-ins)
- The basic interface of the plug-in (that is, the interface standard recognized by the plug-in and the manager). In the DLL plug-in, this element is usually a standard C ++ header file, in the com plug-in, we often use an interface com that contains the base class. In this COM, it only defines the interface, without any implementation.
- Plug-in COM. In these com, they only implement the interfaces of the base class com library and do not have their own interfaces.
In this example, testsvr is the first element, plug-in manager, and the two projects under the plug-in directory are the third element: plug-in COM, the project under the interface code Directory provides the basic class COM, which is the second element we mentioned above.
3. In DLL plug-ins, we search for plug-ins by storing the plug-ins in a directory that is relatively fixed with the main program. The main program searches for plug-ins by searching for directory files, in the com plug-in, we cannot use this method to search for plug-ins. Here we use the method of adding each COM plug-in to a fixed Com group, the main program searches for INS in the com group.
The following code registers and unregisters a com instance to a Com group:
void SpecialReg(GUID ID_SubItem,BOOL bRegister){ICatRegister* pICatRegister = NULL ;HRESULT hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_ALL, IID_ICatRegister, (void**)&pICatRegister) ;if (FAILED(hr)){ErrorMessage("Could not create the ComCat component.", hr);return ;}CATEGORYINFO CatInfo ;CatInfo.catid = CATID_MyCategory ;CatInfo.lcid = LOCALE_SYSTEM_DEFAULT ;wcscpy(CatInfo.szDescription,sCateGoryName) ;if (bRegister){hr = pICatRegister->RegisterCategories(1, &CatInfo) ;hr = pICatRegister->RegisterClassImplCategories(ID_SubItem, 1, &CATID_MyCategory) ;}else{hr = pICatRegister->UnRegisterClassImplCategories(ID_SubItem, 1, &CATID_MyCategory);ICatInformation* pICatInformation = NULL ;hr = pICatRegister->QueryInterface(IID_ICatInformation, (void**)&pICatInformation) ;IEnumCLSID* pIEnumCLSID = NULL ;hr = pICatInformation->EnumClassesOfCategories(1, &CATID_MyCategory, 0, NULL, &pIEnumCLSID) ;CLSID clsid ;hr = pIEnumCLSID->Next(1, &clsid, NULL) ;if (hr == S_FALSE){hr = pICatRegister->UnRegisterCategories(1, &CATID_MyCategory) ;}pIEnumCLSID->Release() ;pICatInformation->Release() ;}if (pICatRegister){pICatRegister->Release() ;}}
The following code lists COM components from the Com group:
ICatInformationPtr pICatInformation(CLSID_StdComponentCategoriesMgr);IEnumCLSID* pIEnumCLSID = NULL ;HRESULT hr = pICatInformation->EnumClassesOfCategories(1, &CATID_RdExcelExportCategory, 0, NULL, &pIEnumCLSID) ;ASSERT(SUCCEEDED(hr)) ;long nComandID = _BASE_COMMAND_ID_;CLSID clsid ;while ((hr = pIEnumCLSID->Next(1, &clsid, NULL)) == S_OK){RDINTERFACELib::ICommandPtr pCommand(clsid);}