目录
使用版本VS2017社区版
菜单栏——新建——项目——(VC++下)MFC项目——(应用程序类型)基于对话框——点完成
命名尽量不要用中文,比如啥静态文本之类的(保不齐后期对dialog对话框操作时会报错)
如果在之前刚写完别的项目不久,那就把目前的项目作为启动项,解决方案资源管理器视图——总的最上面的解决方案"StaticText"右键——属性——启动项目(当前选定内容)
资源视图在菜单栏——视图——其他窗口——资源视图中打开
界面设计的对话框在资源视图文件下的Dialog中,不是aboutbox另一个IDD_STATICTEXT_DIALOG
双击IDD_STATICTEXT_DIALOG即可打开基于对话框的设计界面
在工具箱中拖入static txt 和button
左键选中对应的控件输入内容文字Caption
一个静态文本(写着C++的那个)
两个button按钮(一个写着设置为MFC,一个写着获取内容)
左键选中C++的静态文本,右键选择添加变量,此时会报错,因为它的ID是IDC_STATIC,只需要把STATIC换成别的字母即可比如TEXT,IDC-TEXT
添加变量之后我们如何找到?或者说是在哪里对我们创建的变量进行了关联?
打开类视图(菜单栏——视图——类视图 可以找到)
选中以C开头,我们命名的项目名称为中间文字,Dlg为结尾的文件,CStaticTextDlg
下方找到CStaticTextDlg::DoDataExchange(如果被隐藏了可以拉出来)
双击CStaticTextDlg::DoDataExchange 可以定位到我们刚添加的变量与对话框的关联代码
void CStaticTextDlg::DoDataExchange(CDataExchange* pDX)//继承类DoDataExchange
{
CDialogEx::DoDataExchange(pDX);
//我们的文本名是StaticText,找到类视图-CStaticTextDlg下的DoDataExchange即可定位到这里
//静态文本的ID名IDC_TEXT和变量名m_text
DDX_Control(pDX, IDC_TEXT, m_text);//多了这一行代码DoDataExchange关联变量到dialog中
}
DoDataExchange是将变量名和控件名进行绑定的
要记住我们修改后的C++静态文本的变量名m_text,后续要进行调用关联
看过MFC专栏的前段时间的博文(模态和非模态)的应该知道,双击对应的控件就可以转到相应的控件代码段
主要是设置和获取内容里面的API,API的概念可以进行百度(我也解释不太清楚)
- //设置为MFC button的控件代码
- void CStaticTextDlg::OnBnClickedButton1()
- {
- // TODO: 在此添加控件通知处理程序代码
- //设置文本内容
- m_text.SetWindowTextW(TEXT("MFC"));
- }
此时点击运行就可以执行把静态文本中的C++更换为MFC
获取内容控件代码
- //获取内容button的控件代
- //获取文本中的内容,并且弹出这个内容
- void CStaticTextDlg::OnBnClickedButton2()
- {
- // TODO: 在此添加控件通知处理程序代码
- //创建一个string类型变量,用于接收传递获取的内容
- CString str;
- //获取内容GetWindowTextW的方法
- m_text.GetWindowTextW(str);
- //显示获取到的内容str,弹出内容
- MessageBox(str);
- }
运行截图
SetWindowTextW函数可不止能用在更改文本上,还可以用在更改图片上
static txt显示图片的前提是 目标图片是bmp(位图)格式的图片,其他格式的图片不行,可以通过重命名直接把图片后缀名改为.bmp
还有一个注意点就是,要把图片放到项目文件夹下,不然后面读入图片路径会出错
拉一个static静态文本稍大一点用于显示图片
同样,改掉图片静态文本里的ID,改为IDC_IMG
添加变量改为名 m_img(访问是权限界定,private,public,procte都可以按照需求改)
这里红色波浪线是因为我们刚改了ID,编译器没反应过来
改图片显示的要求为,不用点击任何控件,图片区域也有一张默认的图片,那么久把图片static txt的代码写到初始化里(当然,也可以不按要求,刚开始啥图也没有空空的,那么就只需要把代码写入控件中,点击控件之后才出现图片)
初始化代码在CStaticTextDlg::OnInitDialog中,同样在CStaticTextDlg类里面
双击OnInitDialog 定位到该函数所在位置
在添加代码的地方,return TRUE; // 除非将焦点设置到控件,否则返回 TRUE 这段话的前面
- //(1)首先设置空间风格
- m_img.ModifyStyle(0xf, SS_BITMAP | SS_CENTERIMAGE);
- //(2)获取bitmap句柄
- #define HBMP(filePath, width, height) (HBITMAP)LoadImage(AfxGetInstanceHandle(), filePath, IMAGE_BITMAP, width, height, LR_LOADFROMFILE | LR_CREATEDIBSECTION)
- //(3)获取控件大小
- CRect rect;
- m_img.GetWindowRect(rect);
- //(4)设置图片
- m_img.SetBitmap(HBMP(TEXT("./img.bmp"), rect.Width(), rect.Height()));
我这里无法初始化图片,可能是因为bmp文件放的位置不对,而且这些初始化代码太长了,个人真的很不喜欢这个方法,更加喜欢(控件导入)动态方法,也利于后续开发项目导入文件啥的
动态显示bmp,支持用户手动选择文件导入(但是图片不能太大,如果显示内存不足,则是new申请的内存不够图片用)
- //用控件打开图片
- void CStaticTextDlg::OnBnClickedButton3()
- {
- // TODO: 在此添加控件通知处理程序代码
- //打开文件 定义四种格式的文件bmp gif jpg tiff
- CString filter;
- filter = "所有文件(*.bmp,*.jpg,*.gif,*tiff)|*.bmp;*.jpg;*.gif;*.tiff| BMP(*.bmp)|*.bmp| JPG(*.jpg)|*.jpg| GIF(*.gif)|*.gif| TIFF(*.tiff)|*.tiff||";
- CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter, NULL);
-
-
- //按下确定按钮 dlg.DoModal() 函数显示对话框
- if (dlg.DoModal() == IDOK)
- {
- //打开对话框获取图像信息
- CString BmpName = dlg.GetPathName(); //获取文件路径名 如D:\pic\abc.bmp
- CString EntName = dlg.GetFileExt(); //获取文件扩展名
- EntName.MakeLower(); //将文件扩展名转换为一个小写字符
-
-
- if (EntName.Compare(_T("bmp")) == 0)
- {
- //定义变量存储图片信息
- BITMAPINFO *pBmpInfo; //记录图像细节
- BYTE *pBmpData; //图像数据
- BITMAPFILEHEADER bmpHeader; //文件头
- BITMAPINFOHEADER bmpInfo; //信息头
- CFile bmpFile; //记录打开文件
-
-
- //以只读的方式打开文件 读取bmp图片各部分 bmp文件头 信息 数据
- if (!bmpFile.Open(BmpName, CFile::modeRead | CFile::typeBinary))
- return;
- if (bmpFile.Read(&bmpHeader, sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
- return;
- if (bmpFile.Read(&bmpInfo, sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER))
- return;
- pBmpInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];
- //为图像数据申请空间
- memcpy(pBmpInfo, &bmpInfo, sizeof(BITMAPINFOHEADER));
- DWORD dataBytes = bmpHeader.bfSize - bmpHeader.bfOffBits;
- pBmpData = (BYTE*)new char[dataBytes];
- bmpFile.Read(pBmpData, dataBytes);
- bmpFile.Close();
-
- //显示图像
- CWnd *pWnd = GetDlgItem(IDC_IMG); //获得pictrue控件窗口的句柄
- CRect rect;
- pWnd->GetClientRect(&rect); //获得pictrue控件所在的矩形区域
- CDC *pDC = pWnd->GetDC(); //获得pictrue控件的DC
- pDC->SetStretchBltMode(COLORONCOLOR);
- StretchDIBits(pDC->GetSafeHdc(), 0, 0, rect.Width(), rect.Height(), 0, 0,
- bmpInfo.biWidth, bmpInfo.biHeight, pBmpData, pBmpInfo, DIB_RGB_COLORS, SRCCOPY);
- delete pBmpInfo;
- delete pBmpData;
- }
- }
- }
之前我们用到的控件类别都是 控件(control),现在我们来试一下把控件本身变为值(value)类别
给它添加变量,改类别为:值(value) 改名字为:m_value
可是改不了控件类型,老一点的版本可以把非文本的控件比如button改为值类型,新版(比如2017似乎不行)
所以呢,就只能用static来代替实验值类型了
改ID,添加值类型变量
实现点击值就更换另一个内容显示并且弹出新内容
button是真不能改为值类型,与之对应的SetWindowTextW方法也用不了了,所以,此案例,败,后续找到解决办法在评论区更新
MFC专栏之后的案例博文就没有那么详细了,比如类视图资源视图这些在哪儿找,dialog怎么找,也不会再重复赘述了,讲流程就可以了