【VC编程技巧】动态链接库☞1.3MFC扩展类的导出

MFC常规DLL和扩展DLL相同点在于在于在两种DLL的内部都可以使用MFC类库,FC扩展DLL的含义在于它是MFC的扩展,其主要功能是实现从现有MFC库类中派生出可重用的类。MFC扩展DLL必须使用MFC 动态链接库版本。


1.对于扩展DLL我们首先要了解系统提供的宏,先来看一下微软定义宏:

文件:AFXV_DLL.H

// default AFX_EXT_DATA and AFX_EXT_DATADEF macros for using or
//  creating MFC extension DLLs, depending on _AFX_EXT_IMPL
// AFX_EXT_CLASS can be used to import or export entire classes
//  in an extension DLL without the hassle of creating a .DEF file
//  with decorated names.
...
#ifndef AFX_EXT_DATA
	#ifdef _AFXEXT
		#define AFX_EXT_CLASS       AFX_CLASS_EXPORT
		#define AFX_EXT_API         AFX_API_EXPORT
		#define AFX_EXT_DATA        AFX_DATA_EXPORT
		#define AFX_EXT_DATADEF
	#else
		#define AFX_EXT_CLASS       AFX_CLASS_IMPORT
		#define AFX_EXT_API         AFX_API_IMPORT
		#define AFX_EXT_DATA        AFX_DATA_IMPORT
		#define AFX_EXT_DATADEF
	#endif
#endif

文件:AFXVER_.H

...
// The following macros are used to enable export/import

// for data
#ifndef AFX_DATA_EXPORT
	#define AFX_DATA_EXPORT __declspec(dllexport)
#endif
#ifndef AFX_DATA_IMPORT
	#define AFX_DATA_IMPORT __declspec(dllimport)
#endif

// for classes
#ifndef AFX_CLASS_EXPORT
	#define AFX_CLASS_EXPORT __declspec(dllexport)
#endif
#ifndef AFX_CLASS_IMPORT
	#define AFX_CLASS_IMPORT __declspec(dllimport)
#endif

// for global APIs
#ifndef AFX_API_EXPORT
	#define AFX_API_EXPORT __declspec(dllexport)
#endif
#ifndef AFX_API_IMPORT
	#define AFX_API_IMPORT __declspec(dllimport)
#endif
...
从文件AFXV_DLL.H的注释中可以看出微软给我们类 导出提供非常有用的 宏AFX_EXT_CLASS,它既可以是导出类的宏也可以是导入类的宏,更重要的是它自己能判断此时自己是导入或者导出。因为微软在EXE模块编译中没加入宏_AFXEXT,所以宏[AFX_EXT_CLASS]在被加载时是导入接口,而在扩展DLL编译中加入宏,这时宏[AFX_EXT_CLASS]是导出接口。 因此要用扩展DLL导出类,只需在CLASS和类名中间加入宏[AFX_EXT_CLASS]


2.下面我用扩展DLL来导出MFC中CToolTipCtrl的派生类。

  • 先创建扩展MFC(使用MFC动态链接库)。工程名:CToolTipCtrlEx
  • 创建基于MFC类CToolTipCtrl的派生类CToolTipCtrlEx
  • 想派生类 中增加扩展函数,代码如下:
    /
    // CToolTipCtrlEx message handlers
    //向指定控件添加Tip功能
    BOOL CToolTipCtrlEx::AddTool(UINT nID, LPCTSTR lpszText)
    {
    	TOOLINFO ti;
    	memset(&ti, 0, sizeof(TOOLINFO));
    	//结构体大小,必须填
    	ti.cbSize = sizeof(TOOLINFO);
    	//ToolTip显示的Flag
    	ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS;
    	//ToolTip的宿主(控件的父窗口句柄)
    	ti.hwnd = GetOwner() -> GetSafeHwnd();
    	//应该监视的控件句柄
    	ti.uId = ( UINT )((GetParent() -> GetDlgItem( nID )) -> m_hWnd);
    	//Tip上的提示信息
    	ti.lpszText = (LPSTR)lpszText;	
    
    	//发送消息给控件
    	return ( BOOL )SendMessage( TTM_ADDTOOL, 0, ( LPARAM )&ti );
    }
    
    //向指定区域添加Tip功能
    BOOL CToolTipCtrlEx::AddArea(UINT nID, LPRECT lpRect, LPCTSTR lpszText)
    {
    	//以下OOLINFO参数含义参考函数[AddTool]
    	TOOLINFO ti;
    	memset(&ti, 0, sizeof(TOOLINFO));
    	ti.cbSize = sizeof(TOOLINFO);
    	ti.uFlags = TTF_SUBCLASS;
    	ti.hwnd = GetOwner() -> GetSafeHwnd();
    	//自定义ID,以后修改ToolTip的内容
    	ti.uId = nID;
    	ti.lpszText = (LPSTR)lpszText;	
    	memcpy( &ti.rect, lpRect, sizeof( RECT ) );
    
    	return ( BOOL )SendMessage( TTM_ADDTOOL, 0, ( LPARAM )&ti );
    }
    
  • 编译生成MFC扩展DLL,对于导出类接口一般我们提供三个文件:接口定义的头文件.H,记录接口位置文件LIB,动态库DLL
  • 项目工程中会把需要扩展的MFC类做成扩展动态库(经验);


3.接着 我们写例子程序去加载扩展DLL(CToolTipCtrlEx.dll);

  • 创建简单的MFC对话框程序,工程名:TipTest;
  • 一般对于扩展类导出我们都采用静态链接的方式,在 这需要三个文件(CToolTipCtrlEx.h,CToolTipCtrlEx.lib,CToolTipCtrlEx.dll);
  • 对话框头文件TipTestDlg.h中定义CToolTipCtrlEx的对象m_toolTip;
  • 利用对象m_toolTip去实现当鼠标移动到“确认”按钮上,提示“红色OK”信息;当鼠标移动到蓝色区域时,提示“红色Hello”;
  • 主要代码:
    /
    // CTipTestDlg message handlers
    
    BOOL CTipTestDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    ...
    	
    	// TODO: Add extra initialization here
    	m_toolTip.Create(this);
    	m_toolTip.AddTool(IDOK, "OK");
    
    	CRect rect(0,0,100,20); 
    	m_toolTip.AddArea(0, &rect, "Hello");
    	m_toolTip.SetTipBkColor(RGB(255, 0, 0));
    	m_toolTip.Activate(TRUE);
    	return TRUE;  // return TRUE  unless you set the focus to a control
    }
    
  • 效果图:


有不合适的地方欢迎大家讨论。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值