In program development, we cannot implement all the functions at once, so we should leave some interfaces for other functions to be added to our program in the form of plug-ins, in this way, our program can add many new functions without any changes. Our commonly used software, such as Excel and Photoshop, all have these functions. How can we achieve this? This article uses a simple example.
Tool used: vs2008
Language: C ++
Development steps:
1. Plug-in APP 1.1 create dialog box app
1.2 new base class
1.3 Add the basic class pure virtual function plugpeople. h
#pragma oncetypedef bool (*LPFNREGISTER)(void**);class CPlugPeople{public:CPlugPeople(void){};~CPlugPeople(void){};virtual void Show(void){};};1.4 load the dynamic library and add a list on the display effect interface to display the path name of the dynamic library
// Set the attribute to m_list.modifystyle (lvs_typemask, lvs_report & lvs_typemask | lvs_singlesel); // important for showdword dwstyle = ignore (); transform (dwstyle | ignore); m_list.insertcolumn (0, _ T ("pathname"), lvcfmt_left );Add a button to select a folder, enumerate the selected folder, and display the dynamic library path name to the list
Void cplugappdemodlg: onbnclickedbtnload () {// todo: add the control notification handler code char szdir [max_path]; browseinfo Bi; itemidlist * pidl; bi. hwndowner = This-> m_hwnd; bi. pidlroot = NULL; bi. pszdisplayname = (lpwstr) szdir; bi. lpsztitle = _ T ("select a directory"); // strdlgtitle; bi. ulflags = bif_returnonlyfsdirs; bi. lpfn = NULL; bi. lparam = 0; bi. iimage = 0; pidl = shbrowseforfolder (& BI); If (pidl = NULL) return; If (! Shgetpathfromidlist (pidl, (lpwstr) szdir) return; cstring stargetfullpath = _ T (""); stargetfullpath. format (_ T ("% s"), szdir); If (stargetfullpath. isempty () {return;} partial (); int Index = 0; cstring strpath = stargetfullpath; cstring strfullname = _ T (""); win32_find_data findfiledata; bool bfinishfind = false; zeromemory (& findfiledata, sizeof (win32_find_data); strpath + = _ T ("\\*. * "); handle Hfindfile = findfirstfile (strpath, & findfiledata); If (hfindfile = invalid_handle_value) // enumeration failure {return;} while (hfindfile! = Invalid_handle_value & getlasterror ()! = Error_no_more_files) {If (_ tcscmp (findfiledata. cfilename, _ T (". ") = 0 | (_ tcscmp (findfiledata. cfilename, _ T (".. ") = 0) {findnextfile (hfindfile, & findfiledata); continue;} If (findfiledata. dwfileattributes & volumes) // recursive enumeration folder {findnextfile (hfindfile, & findfiledata); setlasterror (0); continue;} strfullname = stargetfullpath + _ T ("\\") + findfiledata. cfilename; cstring strtype = strfullname. right (4); strtype. makelower (); If (_ T (". DLL ") = strtype) {m_list.insertitem (index, strfullname); index ++;} findnextfile (hfindfile, & findfiledata );}}Click the dynamic library in the list to display the corresponding dynamic library information.
Void cplugappdemodlg: onnmclicklistdll (nmhdr * pnmhdr, lresult * presult) {// lpnmitemactivate pnmitemactivate = reinterpret_cast <nmitemactivate> (pnmhdr); // todo: add the control notification handler code nm_listview * pnmlistview = (nm_listview *) pnmhdr; int nitem = pnmlistview-> iItem; If (-1 = nitem) {return ;} else {rundll (m_list.getitemtext (nitem, 0);} * presult = 0;} void cplugappdemodlg: rundll (cstring strpathname) {cplugpeople * pplug = NULL; hinstance hin = NULL; hin = loadlibrary (strpathname); If (hin! = Invalid_handle_value) {} else {MessageBox (_ T ("load DLL error"); return;} lpfnregister = NULL; char P [256] = {0 }; cstring STR = _ T ("Createobject"); int CNT = Str. getlength (); For (INT I = 0; I <CNT; I ++) {P [I] = Str. getat (I);} lpfnregister = (lpfnregister) getprocaddress (Hin, P); bool result = false; If (lpfnregister) {result = (* lpfnregister) (void **) & pplug) ;}else {freelibrary (HIN); Return ;}if (result) {}else {MessageBox (_ T ("create object error ")); freelibrary (HIN); return;} pplug-> show (); Delete pplug; pplug = NULL; freelibrary (HIN );}
2. Plug-in dynamic library 2.1 new dynamic library
2.2 Add a base class file
2.3 derive your own class plugchild. h from the base class
#pragma once#include "plugpeople.h"class CPlugChild :public CPlugPeople{public:CPlugChild(void);~CPlugChild(void);void Show(void);};2.4 rewrite the virtual function plugchild. cpp
# Include "stdafx. H" # include "plugchild. H" cplugchild: cplugchild (void) {} cplugchild ::~ Cplugchild (void) {} void cplugchild: Show (void) {afxmessagebox (_ T ("little guy eats grapes ..."));}2.5 Add a unified dynamic library function interface to pass your own classes
Plugdllchilddemo. cpp
extern "C"__declspec(dllexport) bool CreateObject(void** pObj){*pObj = new CPlugChild;return true;}
3. Calling plug-in 3.1 in applications
3.2 select a dynamic library folder
3.3 effect after selection
3.4 click Effect
Source code download
Vs plug-in implementation