封装
1、使用VS新建一个空项目(有的说也可以新建一个专门的dl
文件什么的)
2、新建一个.h文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS //为了避免的一个错误警告(出现错误提示再加)
#define FENGZHUANG_API __declspec(dllexport)
宏定义 FENGZHUANG_API 等价于后面那个
//把这个类TEST_1 导出,方便外部函数调用
class FENGZHUANG_API TEST_1
{
public:
static TEST_1* createInterface(); //定义了一个静态接口函数
virtual void init() = 0;
virtual void Destroy() = 0;
virtual char* Getname() = 0;
};
3、.cpp文件,实现上面那个.h文件的定义
#include "fengzhuang.h"
#include <iostream>
//又定义了一个类,继承头文件里面的那个接口类,那个接口类是抽象类
class CHello : public TEST_1
{
public:
CHello();
virtual void init(); //重写基类的函数
virtual void Destroy();
virtual char* Getname();
private:
char name[256];
};
CHello::CHello()
{
memset(name, 0, sizeof(name));
strcpy(name, "测试");
}
void CHello::init()
{
printf("%s\n", "初始化");
}
void CHello::Destroy()
{
memset(name, 0, sizeof(name));
}
char* CHello::Getname()
{
return name;
}
//头文件里面的那个静态函数
//功能:返回CHello这个类的一个对象的指针,当用户调用这个函数的时候就可以操作函数
TEST_1* TEST_1::createInterface()
{
return new CHello();
}
4、函数写完以后,生成lib文件的话要把配置类型的那个
.exe 改成lib 和dll,生成两次,
出现这样就OK了
生成的lib和dll文件在debug目录下面(就是exe文件那个地方)
5、整合成下面的方式
6、如果改动了封装里面函数的内容,记得要重新生成lib文件和dll文件
调用封装
1、建立新项目,引用封装的那个.h文件(添加现有项放到对应的项目里面去),然后在需要引用该库的地方添加对应的头文件,如果不放在和.cpp文件处在同一级目录下,就要添加附加包含目录和添加库目录
记得把改成64位的模式,不管是封装还是调用封装都需要保持一致,64位或32位,debug或release
#include "fengzhuang.h"
#include <iostream>
这个是放在封装的.h文件里面的
//#ifdef TEST
//#define FENGZHUANG_API __declspec(dllexport)
//#else
//#define FENGZHUANG_API __declspec(dllimport)
//#endif
这个和链接器-》输入-》附加依赖项那个添加lib名字相同的效果
//#pragma comment(lib,"Test_fengzhuang.lib")
int main()
{
TEST_1* test = TEST_1::createInterface();
std::cout << test->Getname() << std::endl;
return 0;
}
2、输入的附加依赖项那里添加库名字
3、把dll和lib添加到exe运行文件那里
MFC 带界面的封装
新建工程 MFC-》动态链接库,其他的设置一般不需要改,点击完成
模态对话框的显示
工程建立好了以后,资源视图添加对话框,为对话框添加类,其他的可按照前面封装教程里面得来,不过显示对话框的时候要注意下面的代码
注意:生成lib库和dll库的时候,最好先生成lib库再生成dll库
AFX_MANAGE_STATE(AfxGetStaticModuleState());
一定要加,否则对话框就显示不了
void CTestDlg::createInterface1()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CTestDlg *ph = new CTestDlg;
ph->DoModal(); //new出来的指针要记得释放
delete ph;
}
void CTestDlg::createInterface2() //ok
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CTestDlg ph;
ph.DoModal();
}
非模态对话框的显示
void CTestDlg::createInterface10() //ok
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CTestDlg* ph = new CTestDlg;
ph->Create(IDD_DIALOG1);
ph->ShowWindow(SW_SHOWNORMAL);
//delete ph; //不能delete,会看不到对话框的弹出
}
//也会失败
void CTestDlg::createInterface12() //NO
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CTestDlg ph3;
ph3.Create(IDD_DIALOG1);
ph3.ShowWindow(SW_SHOWNORMAL);
}
上面的只适用于那种弹出式对话框,如果要封装为child的形式,请看下面的代码
记得把封装里面的style改为child,对话框类型改为NONE
来源:
https://bbs.csdn.net/topics/390948839
static CTestDlg* InitData(CWnd * pWnd);
CTestDlg * CTestDlg::InitData(CWnd * pWnd/*父窗口指针,由调用者传入,一般是主对话框*/)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CTestDlg * pDlg = new CTestDlg;
if (pDlg->Create(IDD_DIALOG1, CWnd::FromHandle(pWnd->GetSafeHwnd())))
{
pDlg->SetParent(pWnd);
pDlg->ShowWindow(SW_SHOW);
return pDlg;
}
return NULL;
}
调用封装
和上面C++一样,加头文件,加lib名字在链接器的输入里面,在运行目录下加dll和lib库
CC假设是主界面
CComplex cc;
cc.DoModal();
在主界面的类函数里面
OnInitDialog或者OnShowWIndow
添加相应的处理代码
void CComplex::OnShowWindow(BOOL bShow, UINT nStatus)
{
CDialogEx::OnShowWindow(bShow, nStatus);
// TODO: 在此处添加消息处理程序代码
if (bShow)
{
RECT myRect;
GetDlgItem(IDC_STATIC)->GetClientRect(&myRect);
//dlg2.MoveWindow(&myRect);
CTestDlg* test = CTestDlg::InitData(this);
//CTestDlg* test = CTestDlg::createInterface7();
test->MoveWindow(&myRect);
//test->CenterWindow();
}
}
运行结果如下: