一、变量命名约定
二、vs2019创建MFC项目
应用程序类型:
1. 基于文档/视图:标准的windows应用界面,含菜单栏、工具栏、状态栏;
2. 基于对话框:无菜单栏、工具栏,如果界面较为简单,可使用对话框。
三、消息处理
添加消息处理:
1. 类视图 -- 选择一个窗口类右键 -- 属性 -- 消息:选择一个[事件]添加处理函数
2. 类视图 -- 选择一个窗口类右键 -- 属性 -- 事件:添加某一事件的处理函数
3. 类视图 -- 选择一个窗口类右键 -- 属性 -- 重写:重写某一函数
4. 在视图界面双击空间添加处理函数
四、函数介绍
1. GetDc():获取设备上下文
可以拿到窗口大小,窗口范围,背景颜色,窗口状态(最大化、最小化)等信息;
2. InvalidateRect(NULL):刷新界面
使页面重绘,会调用OnDraw函数(最大化最小化时也会调用这个函数);
3. CPen::CPen(int PemStyle,int Width,RGB):画笔初始化
可以使用该画笔进行绘制,当宽度超过1时,线型会消失
4. CDC::SelectObject(CPen*):切换画笔
返回旧画笔
有其他的重载函数,也可以切换其他部件
5. 宏:TRACE
可在调试时打印日志到【输出】
6. CPen::GetLogPen(LOGPEN*):获取画笔信息
将画笔信息返回到LOGPEN结构体中
7. CDC::FillRect(CRect,CBrush*):用画笔填充某块区域
涂色,若第二个参数为NULL,则使用上下文的画刷
8. CClientDC::GetTextMetrics(TEXTMETRIC*):获取文本信息
CClientDC是CDC的子类,该函数可以获取文本的字体、大小、颜色等信息
9. CreateSolidCaret(int width,int height):设置光标属性
10. ShowCaret():显示光标
11. CClientDC::TextOut(int, int, CString):显示文本
不支持多行显示
12. CDC::GetTextExtent(CString):获取文本宽高
13. SetCaretPos(CPoint):设置光标位置
五、简单绘图与文本编辑
1. 画线 - 鼠标拖动绘制直线
相关类:CMFCPaintView
相关消息:OnLButtonDown、OnLButtonUp、OnMouseMove
相关函数:CDC::MoveTo()、CDC::LineTo()、InvalidateRect()
//.h
CPoint m_start ;//起始点坐标
CPoint m_stop ;//终止坐标
CPoint m_cur ;//当前坐标
bool m_status ;//当前状态
//.cpp
CMFCPaintView::CMFCPaintView() noexcept
{
m_start = { 0,0 };
m_stop = { 0,0 };
m_cur = { 0,0 };
m_status = false;
}
void CMFCPaintView::OnDraw(CDC* pDC)
{
CMFCPaintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
if (m_status) {
pDC->MoveTo(m_start);
pDC->LineTo(m_cur);
}
else {
pDC->MoveTo(m_start);
pDC->LineTo(m_stop);
}
}
void CMFCPaintView::OnLButtonDown(UINT nFlags, CPoint point)
{
m_start = point;
m_status = true;
CView::OnLButtonDown(nFlags, point);
}
void CMFCPaintView::OnLButtonUp(UINT nFlags, CPoint point)
{
m_stop = point;
CDC* pDc = GetDC();
pDc->MoveTo(m_start);
pDc->LineTo(m_stop);
ReleaseDC(pDc);
m_status = false;
CView::OnLButtonUp(nFlags, point);
}
void CMFCPaintView::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_status) {
InvalidateRect(NULL);
m_cur = point;
}
CView::OnMouseMove(nFlags, point);
}
2. 画笔 - 改变线的颜色和线型
在【画线】基础上
相关函数:CPen(),CDC::SelectObject(),TRACE(),CPen::GetLogPen()
ps:如果想在保持线型的基础上增加线的粗度,可以在原线的y轴-1位置再绘制一条线(有bug)
void CMFCPaintView::OnDraw(CDC* pDC)
{
CMFCPaintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
CPen pen(PS_DASH, 1, RGB(255, 0, 0));
CPen* oldPen = pDC->SelectObject(&pen);
LOGPEN logpen;
oldPen->GetLogPen(&logpen);
TRACE("style = %d, color = %08X, width = %d\r\n", logpen.lopnStyle, logpen.lopnColor, logpen.lopnWidth);
if (m_status) {
pDC->MoveTo(m_start);
pDC->LineTo(m_cur);
}
else {
pDC->MoveTo(m_start);
pDC->LineTo(m_stop);
}
pDC->SelectObject(&oldPen);
}
void CMFCPaintView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_stop = point;
/*CDC* pDc = GetDC();
pDc->MoveTo(m_start);
pDc->LineTo(m_stop);
ReleaseDC(pDc);*/
InvalidateRect(NULL);
m_status = false;
CView::OnLButtonUp(nFlags, point);
}
3. 画刷 - 设置画刷颜色填充区域
在【画笔】基础上
相关函数:CBrush(),CDC::SelectObject(),CDC::FillRect()
void CMFCPaintView::OnDraw(CDC* pDC)
{
CMFCPaintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
CPen pen(PS_DASH, 1, RGB(255, 0, 0));
CBrush brushing(RGB(255, 0, 0)), brushed(RGB(0, 255, 255));
CPen* oldPen = pDC->SelectObject(&pen);
CBrush* oldBrush = pDC->SelectObject(&brushing);
if (m_status) {
pDC->FillRect(CRect(m_start, m_cur), NULL);
}
else {
pDC->FillRect(CRect(m_start, m_stop), &brushed);
}
pDC->SelectObject(&oldPen);
pDC->SelectObject(&oldBrush);
}
4. 光标文本 - 显示光标输入文本
相关类:CMFCPaintView
相关消息:OnCreate(在create函数创建完窗口后执行)、OnChar(在有键盘输入时执行)
相关函数:CClientDC::GetTextMetrics()
bug:文本不能多行显示,回车显示异常
//.h
CString m_strText;
//.cpp
void CMFCPaintView::OnDraw(CDC* pDC)
{
pDC->TextOut(0, 0, m_strText);
}
void CMFCPaintView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_strText += (TCHAR)nChar;
InvalidateRect(NULL);
CView::OnChar(nChar, nRepCnt, nFlags);
}
5. 文本换行 - 显示多行文本
相关xx:同上
相关函数:CDC::GetTextExtent() , SetCaretPos()
void CMFCPaintView::OnDraw(CDC* pDC)
{
CString sub = _T("");
int y = 0;
for (int i = 0; i < m_strText.GetLength(); i++) {
if (m_strText.GetAt(i) == '\n' || m_strText.GetAt(i) == '\r') {
pDC->TextOut(0, y, sub);
CSize sz = pDC->GetTextExtent(sub);
sub.Empty();
y += sz.cy;
continue;
}
sub += m_strText.GetAt(i);
}
if(!sub.IsEmpty())
pDC->TextOut(0, y, sub);
CSize sz = pDC->GetTextExtent(sub);
SetCaretPos(CPoint(sz.cx, y));
}
六、菜单与工具栏
0. 基本信息
(1)位置
(2)添加菜单项
描述文字:【名称(&P)】设置快捷键(不在同级菜单的选项快捷键可重复)