绘图
绘图主要就是五个步骤
//这里只写了函数内容,放到OnPaint或者OnDraw中都是可以的。
//1 建立指针,GetDC(); OnDraw函数中不需要这一步
CDC* pDC;
pDC = GetDC();
//2 创建画笔,设置属性
CPen* pNewPen = new CPen;
pNewPen->CreatePen(PS_SOLID, 1, RGB(255, 0, 0));//PS_SOLID属性为实线
//3 将画笔选入环境 [及保存以前的画笔对象]
pDC->SelectObject(pNewPen);
//[CPen* pOldPen = pDC->SelectObject(pNewPen);]
//4 绘制代码 [然后恢复之前的画笔]
pDC->MoveTo(20, 60); // 移动到直线的起点
pDC->LineTo(200, 60); // 画到终点
//[pDC->SelectObject(pOldPen);]
pDC->MoveTo(20, 200); // 移动到直线的起点
pDC->LineTo(200, 200); // 画到终点
//恢复了之前画笔之后再画的就是黑色线了,因为默认画笔是黑色的
//这里的“之前”是指SelectObject函数调用之前,本程序里调用pNewPen之前的画笔是默认画笔,所以恢复了默认画笔
//5 delete画笔释放空间
delete pNewPen;
绘制代码举例
//画线段
pDC->MoveTo(20, 200); // 移动到直线的起点
pDC->LineTo(200, 200); // 画到终点
//画圆或椭圆 ,Ellipse的四个参数分别是左上横纵坐标,右下横纵坐标
CRect r(100, 100, 200, 200);
pDC->Ellipse(r);
//或 pDC->Ellipse(100,100,200,200);
//画矩形 ,Rectangle的四个参数也是左上横纵坐标,右下横纵坐标
CRect r(100, 100, 200, 200);
pDC->Rectangle(r);
//或 pDC->Rectangle(100, 100, 200, 200);
//指哪画哪 ,首先要定义鼠标点击函数。右键类视图->属性->消息 找到 WM_LBUTTONDOWN,添加
void CMFCTestDlg::OnLButtonDown(UINT nFlags, CPoint point)//这个函数是画圆,画其他的请以此类推。
{
CDialogEx::OnLButtonDown(nFlags, point);
CClientDC p(this);
//CPen pNewP;
//pNewP.CreatePen(PS_SOLID, 2, RGB(255, 200, 200));
//p.SelectObject(pNewP);
p.Ellipse(point.x - 10, point.y - 10, point.x + 10, point.y + 10);
//中间的三行可以注释掉,注释掉的话就是使用系统默认的画笔(一般为黑,宽度为1),不注释掉的话就是采用自己创建的画笔。
//顺带一提,这里不定义CClientDC p(this),定义CDC* p = GetDC();也是可以的。不过后面跟着都要改。
}
关于创建画笔的样式属性
图片来源自西南交通大学电气工程学院软件综合设计实验课件
画刷的使用
//画刷的使用和画笔区别不大,画刷是要对一个区域进行填充
//例如把画笔改成画刷就可以画一个纯色的矩形了
CDC* pDC = GetDC(); //获取环境指针,OnDraw函数中不需要这一步
CBrush pNewB; //创建画刷
pNewB.CreateSolidBrush(RGB(250, 204, 192)); //设置画刷
pDC->SelectObject(pNewB); //将画刷选入到环境中
pDC->Rectangle(r); //填充矩形
//这和画笔的操作没什么两样
定时器
设置定时器分为三步,设置定时器、设置回调函数和销毁定时器
SetTimer(1,1000,NULL);
//1代表定时器的ID,1000是间隔时间长为1000毫秒,NULL表示采用系统默认的回调函数(即OnTimer函数)
void CMFCTestDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CDialogEx::OnTimer(nIDEvent);
Invalidate(false);//可以和OnDraw函数配合使之不断重绘
}
//nIDEvent代表定时器的ID
KillTimer(1);
//销毁ID为1的定时器
添加OnTimer函数的方法:
打开类视图,右键点击对话框类(或者视图类,就是你要添加定时器的地方的类),然后选择属性,属性栏选择 消息 ,然后找到WM_TIMER,添加
定时器可以和绘图函数配合使之不断重绘,比如绘制个钟表啥的
控件及事件处理程序
普通的生成控件的方法就是直接从工具箱里拖出来,然后命名,设置ID
事件处理程序就是右键点击->添加事件处理程序,或者直接双击生成默认的函数
这些是由系统自动生成的,所以如果想要修改控件ID或者响应函数名的时候可能会造成一些问题。所以我这里也记录了手动添加控件及事件处理程序的方法,这样我们就知道控件和响应函数是在哪里生成的了,要修改或者删除的话只要把他们一一修改就可以了。
首先是控件,分两步
1 在项目.rc资源文件中添加
我将手动添加一个按钮C
找到这样一个地方,然后在有“确定”“取消”的BEGIN_END之间添加
//我并不是很懂这一句啥意思,我是模仿按钮B和按钮A添加的,后面的数字是类似于坐标一样的参数,PUSHBUTTON应该是按钮控件的类型
PUSHBUTTON "按钮C",IDC_BUTTONC,125,87,50,14
2
在Resouce.h头文件中添加
//在添加响应函数之前,即使不添加这个,控件也会显示出来,程序也能运行。这里是为了让响应函数识别控件
#define IDC_BUTTONC 10001
//数值应该是不和别的重复就可以
然后运行,就可以看到按钮C也显示出来了。
由此我们知道,如果要手动改控件的ID的话,要到.rc文件和Resource.h中改
一般情况下点击.rc文件会直接进入资源视图,这里我们右键.rc文件,然后选择打开方式,选择C++源代码编辑器,就可以看到我上图所示的代码了。
然后是事件处理程序
分三步
1 在.h文件中添加函数声明
//写在public的地方
afx_msg void OnBnClickedButtonC();
2 在.cpp文件的声明消息映射开始和结束之间添加
ON_BN_CLICKED(IDC_BUTTONC, &CMFCTestDlg::OnBnClickedButtonc)
//ON_BN_CLICKED是消息类型,意为单击,IDC_BUTTONC是控件ID
//&CMFCTestDlg::OnBnClickedButtonC是指定在ON_BN_CLICKED时启用这个函数
//声明消息映射。处理ON_BN_CLICKED消息时,如果是IDC_BUTTONC,就启用这个控件的响应函数,这就是把他们绑在一起的操作。
3 在.cpp文件中写响应函数的实现
这个好弄,我就不说了
void CMFCTestDlg::OnBnClickedButtonC()
{
// TODO: 在此添加控件通知处理程序代码
MessageBox(_T("你点击了按钮C"));
}
成员变量
如果想要更改或者删除成员变量,也要把.h文件的声明和.cpp文件中的内容都给改了。
//在头文件中的public处声明,我这个成员变量是EDIT1noV,(意思是EDIT1のVALUE)
CString EDIT1noV;
然后更改.cpp文件中构造函数和DoDataExChange函数中的成员变量名
CMFCTestDlg::CMFCTestDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_MFCTEST_DIALOG, pParent)
, EDIT1noV(_T("")) //这里
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMFCTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDITA, EDIT1noV); //这里
DDV_MaxChars(pDX, EDIT1noV, 20); //还有这里
}
就可以了
弹出对话框
当生成的一个单文档类时,经常就需要弹出对话框,这个操作有点繁琐
//1 在资源视图Dialog的地方右键点击Dialog添加资源,新建Dialog
//2 为这个对话框添加类,双击刚添加的对话框(比如IDD_DIALOG1),进入对话框面板,然后右键点击对话框板,添加类,比如类名设为Ctd,就生成了Ctd.cpp文件和Ctd.h文件
//3 把#include"Ctd.h"添加到.cpp文件中(当然是你在哪要弹出对话框添加到哪的.cpp的文件,比如单文档的xxxView.cpp)
//4 然后在单文档的菜单或者别的什么地方设置事件处理程序,让对话框弹出。
void CMFCTestSDIView::PopupDlg()
{
Ctd td;
// TODO: 在此添加命令处理程序代码
if (td.DoModal() == IDOK) {
}
}
//这是我在菜单栏中添加的事件处理程序
//对对话框进行处理的程序写在if里面,这样就可以获取对话框成员变量的值或者其他操作了。