分类:
2009-10-12 10:30:25
DLL类型 | 入口函数 |
非 MFC DLL | 编程者提供DllMain函数 |
MFC规则 DLL | CWinApp对象的InitInstance 和 ExitInstance |
MFC扩展 DLL | MFC DLL向导生成DllMain 函数 |
宏 | 定义 |
AFX_CLASS_IMPORT | __declspec(dllexport) |
AFX_API_IMPORT | __declspec(dllexport) |
AFX_DATA_IMPORT | __declspec(dllexport) |
AFX_CLASS_EXPORT | __declspec(dllexport) |
AFX_API_EXPORT | __declspec(dllexport) |
AFX_DATA_EXPORT | __declspec(dllexport) |
AFX_EXT_CLASS | #ifdef _AFXEXT AFX_CLASS_EXPORT #else AFX_CLASS_IMPORT |
AFX_EXT_API | #ifdef _AFXEXT AFX_API_EXPORT #else AFX_API_IMPORT |
AFX_EXT_DATA | #ifdef _AFXEXT AFX_DATA_EXPORT #else AFX_DATA_IMPORT |
static AFX_EXTENSION_MODULE ExtDllDLL = { NULL, NULL }; extern "C" int APIENTRY DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ) { // Remove this if you use lpReserved UNREFERENCED_PARAMETER( lpReserved ); //说明:lpReserved是一个被系统所保留的参数,对于隐式链接是一个非零值,对于显式链接值是零 if (dwReason == DLL_PROCESS_ATTACH) { TRACE0( "EXTDLL.DLL Initializing!\n" ); // Extension DLL one-time initialization if ( !AfxInitExtensionModule( ExtDllDLL, hInstance )) return 0; // Insert this DLL into the resource chain new CDynLinkLibrary( ExtDllDLL ); } else if (dwReason == DLL_PROCESS_DETACH) { TRACE0( "EXTDLL.DLL Terminating!\n" ); // Terminate the library before destructors are called AfxTermExtensionModule( ExtDllDLL ); } return 1; // ok } |
struct AFX_EXTENSION_MODULE { BOOL bInitialized; HMODULE hModule; HMODULE hResource; CRuntimeClass* pFirstSharedClass; COleObjectFactory* pFirstSharedFactory; }; |
图15 MFC扩展DLL中的对话框 |
class AFX_EXT_CLASS CExtDialog : public CDialog { public: CExtDialog( CWnd* pParent = NULL ); enum { IDD = IDD_DLL_DIALOG }; protected: virtual void DoDataExchange( CDataExchange* pDX ); DECLARE_MESSAGE_MAP() }; |
图16 MFC扩展DLL调用工程中的对话框 |
// LoadExtDllDlg.cpp : implementation file // #include "..\ExtDialog.h" #pragma comment( lib, "ExtDll.lib" ) 而“调用DLL”按钮的单击事件的消息处理函数为: void CLoadExtDllDlg::OnDllcallButton() { CExtDialog extDialog; extDialog.DoModal(); } |
HINSTANCE AFXAPI AfxLoadLibrary( LPCTSTR lpszModuleName ); |
BOOL AFXAPI AfxFreeLibrary( HINSTANCE hInstLib ); |
void CLoadExtDllDlg::OnDllcallButton() { HINSTANCE hDll = AfxLoadLibrary( "ExtDll.dll" ); if(NULL == hDll) { AfxMessageBox( "MFC扩展DLL动态加载失败" ); return; } CExtDialog extDialog; extDialog.DoModal(); AfxFreeLibrary(hDll); } |
LoadExtDllDlg.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall CExtDialog::~CExtDialog(void)" (__imp_??1CExtDialog@@UAE@XZ) LoadExtDllDlg.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall CExtDialog::CExtDialog(class CWnd *)" (__imp_??0CExtDialog@@QAE@PAVCWnd@@@Z) |
error LNK2001: unresolved external symbol …....... |
//临时改变宏的含义“输出”为“输入” #undef AFX_EXT_CLASS #undef AFX_EXT_API #undef AFX_EXT_DATA #define AFX_EXT_CLASS AFX_CLASS_IMPORT #define AFX_EXT_API AFX_API_IMPORT #define AFX_EXT_DATA AFX_DATA_IMPORT //包含被调用MFC扩展DLL的头文件 #include "CalledDLL.h" //恢复宏的含义为输出 #undef AFX_EXT_CLASS #undef AFX_EXT_API #undef AFX_EXT_DATA #define AFX_EXT_CLASS AFX_CLASS_EXPORT #define AFX_EXT_API AFX_API_EXPORT #define AFX_EXT_DATA AFX_DATA_EXPORT |
//global.h:MFC扩展DLL导出变量和函数的声明 extern "C" { int AFX_EXT_DATA total; //导出变量 int AFX_EXT_API add( int x, int y ); //导出函数 } //global.cpp:MFC扩展DLL导出变量和函数定义 #include "StdAfx.h" #include "global.h" extern "C" int total; int add(int x,int y) { total = x + y; return total; } |
#include #include //AFX_EXT_DATA、AFX_EXT_API宏的定义在afxver_.h头文件中 #pragma comment ( lib, "ExtDll.lib" ) #include "..\global.h" int main(int argc, char* argv[]) { cout << add(2,3) << endl; cout << total; return 0; } |
class AFX_EXT_CLASS CMultiColorStatic : public CStatic { // Construction public: CMultiColorStatic(); virtual ~CMultiColorStatic(); // Attributes protected: CString m_strCaption; COLORREF m_BackColor; COLORREF m_TextColor; // Operations public: void SetTextColor( COLORREF TextColor ); void SetBackColor( COLORREF BackColor ); void SetCaption( CString strCaption ); // Generated message map functions protected: afx_msg void OnPaint(); DECLARE_MESSAGE_MAP() }; |
BEGIN_MESSAGE_MAP(CMultiColorStatic, CStatic) //{{AFX_MSG_MAP(CMultiColorStatic) ON_WM_PAINT() //为这个类定义WM_PAINT消息处理函数 //}}AFX_MSG_MAP END_MESSAGE_MAP() |
//为CMultiColorStatic类添加“设置文本颜色”接口 void CMultiColorStatic::SetTextColor( COLORREF TextColor ) { m_TextColor = TextColor; //设置文字颜色 } //为CMultiColorStatic类添加“设置背景颜色”接口 void CMultiColorStatic::SetBackColor( COLORREF BackColor ) { m_BackColor = BackColor; //设置背景颜色 } //为CMultiColorStatic类添加“设置标题”接口 void CMultiColorStatic::SetCaption( CString strCaption ) { m_strCaption = strCaption; } //重画Static,颜色和标题的设置都依赖于这个函数 void CMultiColorStatic::OnPaint() { CPaintDC dc(this); // device context for painting CRect rect; GetClientRect( &rect ); dc.SetBkColor( m_BackColor ); dc.SetBkMode( TRANSPARENT ); CFont *pFont = GetParent()->GetFont();//得到父窗体的字体 CFont *pOldFont; pOldFont = dc.SelectObject( pFont );//选用父窗体的字体 dc.SetTextColor( m_TextColor );//设置文本颜色 dc.DrawText( m_strCaption, &rect, DT_CENTER );//文本在Static中央 dc.SelectObject( pOldFont ); } |
图17 扩展的CStatic类调用演示 |
#include "..\MultiColorStatic.h" #pragma comment ( lib, "ColorStatic.lib" ) // CCallDllDlg dialog class CCallDllDlg : public CDialog { public: CCallDllDlg(CWnd* pParent = NULL); // standard constructor enum { IDD = IDD_CALLDLL_DIALOG }; CMultiColorStatic m_colorstatic; //包含一个CMultiColorStatic的实例 protected: virtual void DoDataExchange(CDataExchange* pDX);//DDX/DDV support HICON m_hIcon; // Generated message map functions //{{AFX_MSG(CCallDllDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnRedButton(); afx_msg void OnBlueButton(); afx_msg void OnGreenButton(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; |
void CCallDllDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CCallDllDlg) DDX_Control(pDX, IDC_COLOR_STATIC, m_colorstatic); //使m_colorstatic与IDC_COLOR_STATIC控件关联 //}}AFX_DATA_MAP } BOOL CCallDllDlg::OnInitDialog() { … // TODO: Add extra initialization here // 初始static控件的显示 m_colorstatic.SetCaption("最开始为黑色"); m_colorstatic.SetTextColor(RGB(0,0,0)); return TRUE; // return TRUE unless you set the focus to a control } //设置static控件文本颜色为红色 void CCallDllDlg::OnRedButton() { m_colorstatic.SetCaption( "改变为红色" ); m_colorstatic.SetTextColor( RGB( 255, 0, 0 ) ); Invalidate( TRUE ); //导致发出WM_PAINT消息 } //设置static控件文本颜色为蓝色 void CCallDllDlg::OnBlueButton() { m_colorstatic.SetCaption( "改变为蓝色" ); m_colorstatic.SetTextColor( RGB( 0, 0, 255 ) ); Invalidate( TRUE ); //导致发出WM_PAINT消息 } //设置static控件文本颜色为绿色 void CCallDllDlg::OnGreenButton() { m_colorstatic.SetCaption( "改变为绿色" ); m_colorstatic.SetTextColor( RGB(0,255,0) ); Invalidate( TRUE ); //导致发出WM_PAINT消息 } |