VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]

[ 前言 ]  

准备把自绘控件单独封装到DLL类中,尝试使用“使用共享MFC DLL的规则DLL”建立项目,总是无法找到.lib,最终发现应该使用“MFC扩展DLL”类型建立DLL项目。

        自带的基本控件都不怎么美观,所以一般开发者都会自定义类对控件进行重绘。手里也积累了不少控件的重绘,对对话框、静态文本、列表框等。

      但是每次都要把这些类重新导入到新的工程里,比较麻烦,而且我也不想公开我积累的这些代码,所以想到了封装成库文件,每次只要导入头文件和库就行了,这样别人也看不到内部实现。

现将过程总结如下:

 【一】新建MFC 扩展库项目(本例项目名称为:MFCliabrary2

 VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]_第1张图片

 VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]_第2张图片

 【二】将要封装的类导入到已经建好的项目中如下图所示。

VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]_第3张图片

 【三】以下为要封装的类的头文件和源文件

#ifndef _H_OWNERDRAWCHECKBUTTON
#define _H_OWNERDRAWCHECKBUTTON

#pragma once
#include

class CMyStatic : public CStatic
{
	DECLARE_DYNAMIC(CMyStatic)

public:
	CMyStatic();
	virtual ~CMyStatic();

protected:
	DECLARE_MESSAGE_MAP()
public:
	CFont m_Text;
	bool  SetTextFont(const LOGFONT& lgfnt);
	bool  SetTextFont(LONG nHeight, bool bBold, bool bItalic, const CString& sFaceName);
	afx_msg  HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
	afx_msg  void OnSetFocus(CWnd* pOldWnd);
	afx_msg  void OnKillFocus(CWnd* pNewWnd);
	afx_msg  void m_SetBackClr(COLORREF bKClr);
	afx_msg  void m_SetTextClr(COLORREF textClr);
	afx_msg  void m_SetNormalBk(COLORREF nmBkClr);
	afx_msg  void m_SetNormalText(COLORREF nmTextClr);
	afx_msg  void m_SetBkColor(COLORREF bKColor);
	afx_msg  void m_SetNormalBkColor(COLORREF nbKColor);
	COLORREF m_BkClr;
	COLORREF m_TextClr;
	COLORREF m_NormalBkClr;
	COLORREF m_NomalTextClr;
	COLORREF m_bKColor;
	COLORREF m_bKNormalColor;
	CBrush   m_ClrBrush;
	CBrush   m_ClrNormalBrush;
	BOOL     Is_Focused;
	BOOL     Set_TextColorFlag;
};

#endif
#include "pch.h"
#include "CMyStatic.h"

IMPLEMENT_DYNAMIC(CMyStatic, CStatic)

CMyStatic::CMyStatic()
{
	Is_Focused = FALSE;
	Set_TextColorFlag = TRUE;
	m_BkClr = RGB(255,255,255);
	m_TextClr = RGB(0,0,255);
	m_NormalBkClr = RGB(255, 255, 255);
	m_NomalTextClr = RGB(10,10,10);
	m_bKColor = RGB(0,255,0);
	m_bKNormalColor = RGB(255,255,255);
}

CMyStatic::~CMyStatic()
{
}

BEGIN_MESSAGE_MAP(CMyStatic, CStatic)
	ON_WM_CTLCOLOR_REFLECT()
	ON_WM_SETFOCUS()
	ON_WM_KILLFOCUS()
END_MESSAGE_MAP()

bool CMyStatic::SetTextFont(const LOGFONT& lgfnt)
{
	m_Text.DeleteObject();
	m_Text.CreateFontIndirect(&lgfnt);
	SetFont(&m_Text, TRUE);
	Invalidate();
	return true;
}

bool CMyStatic::SetTextFont(LONG nHeight, bool bBold, bool bItalic, const CString& sFaceName)
{
	LOGFONT lgfnt;
	lgfnt.lfHeight = -MulDiv(nHeight, GetDeviceCaps(GetDC()->m_hDC, LOGPIXELSY), 72);
	lgfnt.lfWidth = 0;
	lgfnt.lfEscapement = 0;
	lgfnt.lfOrientation = 0;
	lgfnt.lfWeight = bBold ? FW_BOLD : FW_DONTCARE;
	lgfnt.lfItalic = bItalic ? TRUE : FALSE;
	lgfnt.lfUnderline = FALSE;
	lgfnt.lfStrikeOut = FALSE;
	lgfnt.lfCharSet = DEFAULT_CHARSET;
	lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS;
	lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS;
	lgfnt.lfQuality = DEFAULT_QUALITY;
	lgfnt.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
	wcscpy_s(lgfnt.lfFaceName, sFaceName);
	return SetTextFont(lgfnt);
}

HBRUSH CMyStatic::CtlColor(CDC* pDC, UINT nCtlColor)
{
	pDC->SetBkMode(TRANSPARENT);
	if (Set_TextColorFlag)
	{
		pDC->SetBkColor(m_BkClr);
		pDC->SetTextColor(m_TextClr);
		return(HBRUSH)m_ClrBrush;
	}
	else
	{
		pDC->SetBkColor(m_NormalBkClr);
		pDC->SetTextColor(m_NomalTextClr);
		return(HBRUSH)m_ClrNormalBrush;
	}
}


void CMyStatic::OnSetFocus(CWnd* pOldWnd)
{
	CStatic::OnSetFocus(pOldWnd);
	Is_Focused = TRUE;

}

void CMyStatic::OnKillFocus(CWnd* pNewWnd)
{
	CStatic::OnKillFocus(pNewWnd);
	Is_Focused = FALSE;
}

void CMyStatic::m_SetBackClr(COLORREF bKClr)
{
	m_BkClr = bKClr;
	Invalidate();
}

void CMyStatic::m_SetTextClr(COLORREF textClr)
{
	m_TextClr = textClr;
	Invalidate();
}

void CMyStatic::m_SetNormalBk(COLORREF nmBkClr)
{
	m_NormalBkClr = nmBkClr;
	Invalidate();
}

void CMyStatic::m_SetNormalText(COLORREF nmTextClr)
{
	m_NomalTextClr = nmTextClr;
	Invalidate();
}

void CMyStatic::m_SetBkColor(COLORREF bKColor)
{
	m_bKColor = bKColor;
	m_ClrBrush.Detach();
	m_ClrBrush.CreateSolidBrush(m_bKColor);
	Invalidate();
}

void CMyStatic::m_SetNormalBkColor(COLORREF nbKColor)
{
	m_bKNormalColor = nbKColor;
	m_ClrNormalBrush.Detach();
	m_ClrNormalBrush.CreateSolidBrush(m_bKNormalColor);
	Invalidate();
}

 【四】将已导入的类的声明改为如下所示

class AFX_EXT_CLASS CMyStatic : public CStatic
#ifndef _H_OWNERDRAWCHECKBUTTON
#define _H_OWNERDRAWCHECKBUTTON

#pragma once
#include

class AFX_EXT_CLASS CMyStatic : public CStatic
{
	DECLARE_DYNAMIC(CMyStatic)

public:
	CMyStatic();
	virtual ~CMyStatic();

protected:
	DECLARE_MESSAGE_MAP()
public:
	CFont m_Text;
	bool  SetTextFont(const LOGFONT& lgfnt);
	bool  SetTextFont(LONG nHeight, bool bBold, bool bItalic, const CString& sFaceName);
	afx_msg  HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
	afx_msg  void OnSetFocus(CWnd* pOldWnd);
	afx_msg  void OnKillFocus(CWnd* pNewWnd);
	afx_msg  void m_SetBackClr(COLORREF bKClr);
	afx_msg  void m_SetTextClr(COLORREF textClr);
	afx_msg  void m_SetNormalBk(COLORREF nmBkClr);
	afx_msg  void m_SetNormalText(COLORREF nmTextClr);
	afx_msg  void m_SetBkColor(COLORREF bKColor);
	afx_msg  void m_SetNormalBkColor(COLORREF nbKColor);
	COLORREF m_BkClr;
	COLORREF m_TextClr;
	COLORREF m_NormalBkClr;
	COLORREF m_NomalTextClr;
	COLORREF m_bKColor;
	COLORREF m_bKNormalColor;
	CBrush   m_ClrBrush;
	CBrush   m_ClrNormalBrush;
	BOOL     Is_Focused;
	BOOL     Set_TextColorFlag;
};

#endif

 【五】以上步骤完成后编译工程,编译完成后如下所示

VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]_第4张图片

 【六】编译完成后在项目文件夹的"Release"文件夹下回出现“MFCLibrary2.dll”文件和“MFCLibrary2.lib”文件。如下图所示

VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]_第5张图片

 【七】新建MFC对话框类工程(MFCApplication1)用于测试封装完成的类是否正确,能否正常使用。在工程文件下新建“Cbinclude”文件夹用于存放DLL库文件的头文件“CMyStatic.h”文件,新建“Cblib”文件夹用于存放“MFCLibrary2.lib”文件。将“MFCLibrary2.dll”文件分别放入项目文件夹下的"Debug""Release"文件夹下。如下图所示。VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]_第6张图片

【八】在项目属性中打开“MFCApplication1”项目属性对话框如下图所示。

 VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]_第7张图片

 【九】在项目属性中打开“MFCApplication1”项目属性对话框如下图所示。选中“C/C++”属性,在右边的“附加包含目录”中选择“Cbinlude”文件夹所在的目录。

 VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]_第8张图片

 【十】选中“连接器”属性中选择“输入”属性,在右边的“附加依赖项”添加MFCLibrary2.lib。如下图所示。

VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]_第9张图片

 【十一】选中“连接器”属性中选择“常规”属性,在右边的“附加库目录”中添加MFCLibrary2.lib库所在文件夹“Cblib”文件夹所在的路径。如下图所示。

 VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]_第10张图片

  【十二】用同样的方法配置项目“Releas”属性,配置完成后在项目对话框中增加一个ID为IDC_STATICDDDDText Control控件并为控件增加变量m_idcttt。在MFCApplication1Dlg.h头文件中包含“CMyStatic.h”如下图所示。并将IDC_STATICDDDD控件变量类型改为CMyStatic类型。

 VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]_第11张图片

 【十三】在项目对话框初始化OnInitDialog函数中添加如下代码。编译并运行项目。

    m_idcttt.SetWindowText(_T("Hello Word"));
	m_idcttt.SetTextFont(24, FALSE, FALSE, L"Magneto");
	m_idcttt.m_SetBkColor(RGB(0,0,255));
	m_idcttt.m_SetTextClr(RGB(243, 249, 241));

  VS2019 MFC DLL动态链接库(MFC 扩展库)封装例程 MFC 扩展库[一]_第12张图片

【结束语】

        如上图所示为导出MFC DLL并导入到工程应用的实例,从实例看出导出的MFC DLL能正常使用,说明导出过程正确无误。C++的动态链接库封装是一个较为复杂的工程,本人也是通过应用了解到其中的冰山一角,希望能跟大家一起进一步升入学习和了解DLL的运行机制。

 完整封装项目文件和工程应用文件已经上传到资源文件,下载地址如下:

https://download.csdn.net/download/lzc881012/86397065https://download.csdn.net/download/lzc881012/86397065

你可能感兴趣的:(C++,MFC,mfc,c++,windows,visual,studio,开发语言)