目录

  • CWnd 对象
  • 画图程序
    • 新建MFC项目
    • 鼠标位置成员变量
    • 类向导增加消息处理函数
    • 扩展画线功能
      • LineTo 函数 (wingdi.h)
      • 两种常用画线方式
    • 移动鼠标擦除和绘制线
    • 继续扩展

CWnd 对象

CWnd 对象与 Windows 窗口不同,但这两者紧密相关。 CWnd 对象由 CWnd 构造函数和析构函数进行创建或销毁。 另一方面,Windows 窗口是 Windows 内部的数据结构,由 Create 成员函数创建,并由 CWnd 虚拟析构函数销毁。 DestroyWindow 函数销毁 Windows 窗口而不销毁对象。

CWnd 类和消息映射机制会隐藏 WndProc 函数。 传入的 Windows 通知消息会通过消息映射自动路由到正确的 OnMessageCWnd 成员函数。 可重写 OnMessage 成员函数以在派生类中处理成员的特定消息。

通过 CWnd 类还可以为应用程序创建 Windows 子窗口。 从 CWnd 派生类,然后将成员变量添加到派生类,以存储特定于应用程序的数据。 可派生类中实现消息处理程序成员函数和消息映射,以指定在消息定向到窗口时所发生的情况。

可采用两个步骤创建子窗口。 首先,调用构造函数 CWnd 以构造 CWnd 对象,然后调用 Create 成员函数以创建子窗口,然后将它附加到 CWnd 对象。

当用户终止子窗口时,销毁 CWnd 对象,或调用 DestroyWindow 成员函数以移除窗口并销毁其数据结构。

在 Microsoft 基础类库中,从 CWnd 派生了更多类以提供特定窗口类型。 其中许多类(包括 CFrameWnd、CMDIFrameWnd、CMDIChildWnd、CView 和 CDialog)是为进一步派生而设计的。 派生自 CWnd 的控件类(如 CButton)可以直接使用,也可以用于进一步派生类。
“属性” 说明
CWnd::m_hWnd 指示附加到此 CWnd 的 HWND。

画图程序

新建MFC项目


为视图类编写消息处理函数,我们首先解决鼠标左键消息处理问题,不能使用框架类,因为处理消息层次方面,视图类在前面,框架类在后面。

鼠标位置成员变量

增加一个成员变量,保存鼠标位置
类视图

或类向导
增加一个鼠标起始位置

类向导增加消息处理函数

void CMFCLearn1View::OnLButtonDown(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值m_beginMousePoint = point;CView::OnLButtonDown(nFlags, point);
}

除了上面1处需要加上m_beginMousePoint = point;外,还有以下2处增加了这个函数的相关代码体,不需要修改它们。

class CMFCLearn1View : public CView
{
....
// 生成的消息映射函数
protected:DECLARE_MESSAGE_MAP()
private:CPoint m_beginMousePoint;
public:afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
};
// CMFCLearn1ViewIMPLEMENT_DYNCREATE(CMFCLearn1View, CView)BEGIN_MESSAGE_MAP(CMFCLearn1View, CView)ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

上面是鼠标按下的消息,接下来处理鼠标抬起的消息。

void CMFCLearn1View::OnLButtonUp(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值HDC hdc;hdc = ::GetDC(m_hWnd);MoveToEx(hdc, m_beginMousePoint.x, m_beginMousePoint.y, NULL);LineTo(hdc, point.x, point.y);::ReleaseDC(m_hWnd, hdc);CView::OnLButtonUp(nFlags, point);
}

扩展画线功能

增加鼠标移动处理

LineTo 函数 (wingdi.h)

LineTo 函数从当前位置绘制一行,但不包括指定点。

BOOL LineTo([in] HDC hdc,[in] int x,[in] int y
);

参数

[in] hdc

设备上下文的句柄。

[in] x

指定线条终点的 x 坐标(以逻辑单位为单位)。

[in] y

指定线条终点的 y 坐标(以逻辑单位为单位)。
返回值

如果该函数成功,则返回值为非零值。

如果函数失败,则返回值为零。

该线条是使用当前笔绘制的,如果笔是几何笔,则为当前画笔。
如果 LineTo 成功,则当前位置设置为指定的结束点。

CreatePen 函数 (wingdi.h)

CreatePen 函数创建具有指定样式、宽度和颜色的逻辑笔。 随后可以将笔选入设备上下文,并用于绘制线条和曲线。
HPEN CreatePen( [in] int iStyle, [in] int cWidth, [in]
COLORREF color );

两种常用画线方式

MFC的CClientDC

void CMFCLearn1View::OnLButtonUp(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值m_isMouseDown = false;CPen cPen (PS_SOLID, 2, RGB(100, 200, 50));CClientDC dc(this);CPen* cOldPen = dc.SelectObject(&cPen);dc.MoveTo(m_beginMousePoint);dc.LineTo(point);dc.SelectObject(cOldPen);DeleteObject(cPen);CView::OnLButtonUp(nFlags, point);
}

CClientDC 类

处理 Windows 函数 GetDC(在构造时)和 ReleaseDC(在析构时)的调用。

和HDC

void CMFCLearn1View::OnMouseMove(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值if (!m_isMouseDown) {return;}m_tempMousePoint = point;HPEN hPen = CreatePen(PS_SOLID, 2, RGB(100, 200, 50));HDC hdc;hdc = ::GetDC(m_hWnd);HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);   MoveToEx(hdc, m_beginMousePoint.x, m_beginMousePoint.y, NULL);LineTo(hdc, m_tempMousePoint.x, m_tempMousePoint.y);SelectObject(hdc, hOldPen);::ReleaseDC(m_hWnd, hdc);CView::OnMouseMove(nFlags, point);}

HDC

设备上下文的句柄 (DC) 。

此类型在 WinDef.h 中声明,如下所示:

typedef HANDLE HD@TOC

移动鼠标擦除和绘制线

GetBkColor 函数 (wingdi.h)

GetBkColor 函数返回指定设备上下文的当前背景色。 语法 C++

COLORREF GetBkColor( [in] HDC hdc );

参数

[in] hdc

要返回其背景色的设备上下文的句柄。 返回值

如果函数成功,则返回值为当前背景颜色的 COLORREF 值。

如果函数失败,则返回值为 CLR_INVALID。

SetBkColor 函数 (wingdi.h)

SetROP2 函数 (wingdi.h)

SetROP2 函数设置当前的前台混合模式。 GDI 使用前台混合模式将填充对象的笔和内部与屏幕上已有的颜色组合在一起。
前景混合模式定义如何组合画笔或笔中的颜色和现有图像中的颜色。
混合模式 含义

R2_BLACK

像素始终为 0。

R2_COPYPEN

像素是触笔颜色。

R2_MASKNOTPEN

像素是屏幕和笔逆向共有的颜色的组合。

R2_MASKPEN

像素是笔和屏幕通用的颜色的组合。

R2_MASKPENNOT

像素是笔和屏幕反转的常见颜色的组合。

R2_MERGENOTPEN

像素是屏幕颜色和笔色的反数的组合。

R2_MERGEPEN

像素是笔颜色和屏幕颜色的组合。

R2_MERGEPENNOT

像素是笔颜色和屏幕颜色的反转的组合。

R2_NOP

像素保持不变。

R2_NOT

像素是屏幕颜色的反转。

R2_NOTCOPYPEN

像素是触笔颜色的反转。

R2_NOTMASKPEN

像素是R2_MASKPEN颜色的反数。

R2_NOTMERGEPEN

像素是R2_MERGEPEN颜色的反数。

R2_NOTXORPEN

像素是R2_XORPEN颜色的反数。

R2_WHITE

像素始终为 1。

R2_XORPEN

像素是笔和屏幕中颜色的组合,但不在两者中。

选择R2_XORPEN模式 像素是笔和屏幕中颜色的组合,但不在两者中。 绘制出的像素颜色 = NOT (屏幕颜色 XOR 当前颜色)

这种模式第一次画是用笔的颜色,第二次画说法是取反了,等于擦除刚才画的颜色。

void CMFCLearn1View::OnLButtonDown(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值m_beginMousePoint = point;m_prevEndMousePoint = NULL;m_isMouseDown = true;CView::OnLButtonDown(nFlags, point);
}void CMFCLearn1View::OnLButtonUp(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值m_isMouseDown = false;m_prevEndMousePoint = NULL;CPen cPen(PS_SOLID, 3, RGB(255, 0, 0));CClientDC dc(this);CPen* cOldPen = dc.SelectObject(&cPen);dc.MoveTo(m_beginMousePoint);dc.LineTo(point);dc.SelectObject(cOldPen);DeleteObject(cPen);Invalidate(false);CView::OnLButtonUp(nFlags, point);
}void CMFCLearn1View::OnMouseMove(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值if (!m_isMouseDown) {return;}CPoint prevPoint;HDC hdc;hdc = ::GetDC(m_hWnd);HPEN hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);SetROP2(hdc, R2_NOTXORPEN);if (!(m_prevEndMousePoint.x==0 && m_prevEndMousePoint.y==0)) {MoveToEx(hdc, m_beginMousePoint.x, m_beginMousePoint.y, NULL);LineTo(hdc, m_prevEndMousePoint.x, m_prevEndMousePoint.y);}MoveToEx(hdc, m_beginMousePoint.x, m_beginMousePoint.y, NULL);LineTo(hdc, point.x, point.y);m_prevEndMousePoint = point;SelectObject(hdc, hOldPen);Invalidate(false);::ReleaseDC(m_hWnd, hdc);
}

继续扩展

可以调用画圆等API,进一步做可以做出WINDOWS的画图程序来。
在此不描述了。

windows应用(vc++2022)MFC基础到实战(4)-画线程序相关推荐

  1. VC++ 利用MFC的CWindowDC类实现画线功能 在桌面窗口中画线 绘制彩色线条 CPen nPenStyle nWidth crColor

    目录 利用MFC的CWindowDC类实现画线功能 在桌面窗口中画线 绘制彩色线条 CPen nPenStyle nWidth crColor 接上:VC++ 绘制线条 OnLButtonDown函数 ...

  2. VC++ 绘制线条 OnLButtonDown函数(DrawView.cpp) 利用SDK全局函数实现画线功能 利用MFC的CDC类实现画线功能 利用MFC的CClientDC类实现画线功能

    目录 绘制线条 OnLButtonDown函数(DrawView.cpp) 利用SDK全局函数实现画线功能 利用MFC的CDC类实现画线功能 利用MFC的CClientDC类实现画线功能 接上:VC+ ...

  3. windows应用(vc++2022)MFC基础到实战(1)-基础(1)

    目录 vc++概述 特点 概述 MFC 框架 概述 MFC 框架 SDI 和 MDI 文档.视图和框架 窗口对象 文档/视图体系结构 第一个应用 自动生成的主框架类源码 vc++概述 Microsof ...

  4. XMU 数字图像处理实验4 VC/VS MFC 编写JPEG图象读/写程序

    不要照抄!不要照抄!不要照抄! 首先需要用到老师给的JpegDecoder和jpeglib(需要自己生成), 使用VS的命令行来生成jpeglib,具体步骤为 使用libjpeg源代码实现读取jpeg ...

  5. 用CFree写的Windows SDK 画线程序

    1 新建窗口程序 纯C语言: 2 添加代码 在文件头部加入四个变量, POINT startPoint; POINT endPoint; int m_LineWidth; //线宽 COLORREF ...

  6. 最新郁金香VC++基础项目实战(完整)

    郁金香VC++基础视频教程课程目录 下载地址:百度网盘 一.前言  1. C,C++,VC之间的关系,VC环境的安装配置 ---第1课      A.C,C++,VC之间的关系,VC环境的安装配置  ...

  7. VC++6.0及MFC基础知识

    VC++6.0及MFC基础知识 这是早期的学习笔记,今天翻出来,觉得还有点价值,就转发到这里. Visual C++ 6.0的主界面 VC++6.0的MFC Windows 的三大模块就是以DLL( ...

  8. VC++之MFC从零开始实现windows系统任务管理器(一、windows任务管理器界面的制作)

    VC++之MFC从零开始实现windows系统任务管理器(一.windows任务管理器界面的制作) 通过本例程从零开始使用VC++与MFC实现一个基于windows的任务管理器. 最终效果图 软件工具 ...

  9. mfc基础教程(学习笔记)

    目录 mfc基础教程 第一章:CDC的使用 第二章:文本编程 第三章:菜单 第四章:对话框 第五章:对话框(二) 第六章:样式 第七章:创建兼容DC 第八章:图形的保存与重绘 第九章:文件 第十章:文 ...

最新文章

  1. TypePerf收集服务器性能
  2. Hbase之protobuf的使用
  3. SAP CRM系统到底有多少种订单类型
  4. 如何打卡后缀为3ds的文件
  5. Confluence 6 从外部目录中同步数据支持的目录类型
  6. 演示对sys用户和普通用户进行审计的示例
  7. shell中 if条件的格式要求
  8. js实现购物车,原理简单,代码解释-->详细
  9. D-S envidence theory(DS 证据理论)的基本概念和推理过程
  10. matlab车牌匹配时读取,基于matlab+模板匹配的车牌识别(程序+照片+论文)
  11. 使用 Kubernetes Ingress 对外暴露服务
  12. 电脑没有使用计算机进入睡眠状态,电脑打不开,屏上显示:无视频输入,进入睡眠模式。怎么处理...
  13. ArcGIS山体坡度、坡向分析
  14. SPI和IIC异同点
  15. 第三章 迭代器(iterators)概念与traits编程技法
  16. 刚才玩了下Steganos Internet Anonym,IP伪装器,每一秒自动换一IP
  17. C# 按Esc键关闭窗体
  18. pwn题堆利用的一些姿势 -- IO_FILE
  19. 单选框与复选框数据回填
  20. 周赛题1(leetcode)

热门文章

  1. 企业办公wifi提高网络安全解决方案
  2. Linux C 进程间的IPC通信 之 消息队列(1)
  3. C'EST UN TEST de français
  4. 使用OpenCV+Python构建运动热图视频
  5. 谁考了第k名c语言源代码,排序入门练习题3 谁考了第k名 题解
  6. python财务案例分析考试答案_《财务案例分析》作业及答案(三次).
  7. 【苹果相册推iMessage】软件NSSet setWithArray:product
  8. 网络工程师【软考】01
  9. python单线程和多线程的区别
  10. 数美科技CEO唐会军受聘中国信通院互联网新技术新业务安全评估中心高级评估专家