Windows图形编程-MFC

2 篇文章 0 订阅
1 篇文章 0 订阅

一、变量命名约定

二、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)】设置快捷键(不在同级菜单的选项快捷键可重复)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值