MFC下CPictureCtrl控件基于鼠标左键坐标的直线绘图

news2024/11/30 6:40:36

本文仅供学习交流,严禁用于商业用途,如本文涉及侵权请及时联系本人将于及时删除

目录

1.创建自定义类CMyPictureCtrl

2.布局Dlg

3.实验代码

4.运行结果


在基于对话框的MFC应用程序中,通过鼠标操作获取坐标并在CPictureCtrl控件中使用LineTo()函数画直线,涉及以下几个关键步骤:

1.创建自定义类CMyPictureCtrl

创建一个自定义类CMyPictureCtrl,继承自CPictureCtrl(一般继承自CStaic),以便重写绘图方法。并且重载OnPoint()函数,并自定义CPoint m_startPoint, m_endPoint分别用于接受线段的起点、终点坐标值。

//头文件如下
#pragma once
#include "afxwin.h"
class CMyPictureCtrl :
	public CStatic
{
public:
	CMyPictureCtrl();
	~CMyPictureCtrl();
	DECLARE_MESSAGE_MAP()
	afx_msg void OnPaint();
public:
	CPoint m_startPoint, m_endPoint;
};
//源文件如下
#include "stdafx.h"
#include "MyPictureCtrl.h"


CMyPictureCtrl::CMyPictureCtrl()
{
}


CMyPictureCtrl::~CMyPictureCtrl()
{
}
BEGIN_MESSAGE_MAP(CMyPictureCtrl, CStatic)
	ON_WM_PAINT()
END_MESSAGE_MAP()


void CMyPictureCtrl::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO:  在此处添加消息处理程序代码
	// 不为绘图消息调用 CStatic::OnPaint()
	//设置绘图属性 颜色  线宽等等
	dc.SelectStockObject(BLACK_BRUSH);//选择黑色画刷为背景色
	dc.SetBkMode(TRANSPARENT);//设置透明背景模式

	//此处是否需要判断Cpoint两个点为空
	dc.MoveTo(m_startPoint);
	dc.LineTo(m_endPoint);

}

2.布局Dlg

在主对话框中创建CPictureCtrl,控件并绑定自变量(自变量类型为CMyPictureCtrl)

3.实验代码

在主对话框中重载OnMouseMove()、OnLButtonDown()函数

// 画图Dlg.h : 头文件
//

#pragma once
#include "afxwin.h"
#include "MyPictureCtrl.h"


// C画图Dlg 对话框
class C画图Dlg : public CDialogEx
{
// 构造
public:
	C画图Dlg(CWnd* pParent = NULL);	// 标准构造函数

// 对话框数据
	enum { IDD = IDD_MY_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	CStatic m_picture;
	CDC * pDC;
	afx_msg void OnBnClickedBtn1();
	afx_msg void OnBnClickedBtnBack();
	CMyPictureCtrl m_mypicture;
	
	afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
};
// 画图Dlg.cpp : 实现文件
//

#include "stdafx.h"
#include "画图.h"
#include "画图Dlg.h"
#include "afxdialogex.h"
#include <cmath>
#include "MyPictureCtrl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// C画图Dlg 对话框



C画图Dlg::C画图Dlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(C画图Dlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void C画图Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_PICTURE, m_picture);
	DDX_Control(pDX, IDC_MY_PIC, m_mypicture);
}

BEGIN_MESSAGE_MAP(C画图Dlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN1, &C画图Dlg::OnBnClickedBtn1)
	ON_BN_CLICKED(IDC_BTN_BACK, &C画图Dlg::OnBnClickedBtnBack)
	ON_WM_LBUTTONDBLCLK()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()


// C画图Dlg 消息处理程序

BOOL C画图Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO:  在此添加额外的初始化代码
	
	pDC = m_picture.GetDC();                       //获得设备上下文
	CRect rc, rect;
	m_picture.GetClientRect(rect);               //获得控件客户区域
	m_picture.GetWindowRect(rc);                 //获得控件窗口区域
	pDC->FillRect(rect, NULL);                    //填充区域
	//取出中心点
	CPoint center;
	center.x = rc.Width() / 2;
	center.y = rc.Height() / 2;
	pDC->SetViewportOrg(center);                 //设置原点




	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void C画图Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void C画图Dlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR C画图Dlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void C画图Dlg::OnBnClickedBtn1()
{
	// TODO:  在此添加控件通知处理程序代码
	int r = 180, n = 10;
	CPoint P[10];//用于存放顶点数组
	double PI = 3.14;
	double Theta = 2 * PI / n;
	for (int i = 0; i < n; i++)
	{
		//记得包含应用#include<cmath> 头文件
		P[i].x = round(r*cos(i*Theta));
		P[i].y = round(r*sin(i*Theta));
	}
	for (int i = 0; i <= n - 2; i++)
	{
		for (int j = i + 1; j <= n - 1; j++)
		{
			pDC->MoveTo(P[i]);
			pDC->LineTo(P[j]);
		}
	}
}


void C画图Dlg::OnBnClickedBtnBack()
{
	// TODO:  在此添加控件通知处理程序代码
	delete pDC; //释放内存空间,指示系统随时可回收内存,指针指向地址不变
	pDC = NULL;
	this->DestroyWindow();
}


void C画图Dlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值

	CDialogEx::OnLButtonDblClk(nFlags, point);
}


void C画图Dlg::OnLButtonUp(UINT nFlags, CPoint point)
{
	 TODO:  在此添加消息处理程序代码和/或调用默认值
	//if (nFlags&MK_LBUTTON)
	{
	//m_mypicture.m_endPoint = point;
	//m_mypicture.Invalidate();//触发控件重绘
	}


	CDialogEx::OnLButtonUp(nFlags, point);
}


void C画图Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值
	//m_mypicture.m_startPoint = m_mypicture.m_endPoint = point;
	m_mypicture.m_startPoint = point;
	//m_mypicture.Invalidate();//初始位置绘制,//触发控件重绘

	CDialogEx::OnLButtonDown(nFlags, point);
}


void C画图Dlg::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值
	//if (nFlags&MK_LBUTTON)//如果左键按下
	if (nFlags&MK_LBUTTON)
	{
		m_mypicture.m_endPoint = point;
		m_mypicture.Invalidate();//触发控件重绘
	}
	CDialogEx::OnMouseMove(nFlags, point);
}

4.运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1602935.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电商技术揭秘系列文章合集(上)

电商技术揭秘系列文章&#xff08;上&#xff09; 电商技术揭秘一&#xff1a;电商架构设计与核心技术 电商技术揭秘二&#xff1a;电商平台推荐系统的实现与优化 电商技术揭秘三&#xff1a;电商平台的支付与结算系统 电商技术揭秘四&#xff1a;电商平台的物流管理系统 …

越来越多服务区安装智慧公厕是什么原因

随着社会的不断发展&#xff0c;人们对生活质量的要求也越来越高。在这种背景下&#xff0c;越来越多的服务区开始安装智慧公厕&#xff0c;以满足人们在出行过程中的生活需求。那么&#xff0c;为什么越来越多的服务区选择安装智慧公厕呢&#xff1f;这其中究竟有哪些原因呢&a…

手机副业赚钱秘籍:让你的手机变成赚钱利器

当今社会&#xff0c;智能手机已然成为我们生活不可或缺的一部分。随着技术的飞速进步&#xff0c;手机不再仅仅是通讯工具&#xff0c;而是化身为生活伴侣与工作助手。在这个信息爆炸的时代&#xff0c;我们时常会被一种焦虑感所困扰&#xff1a;如何能让手机超越消磨时光的定…

不说成为Linux高级工程师,但成为合格的软件开发人员还是够了,一文深入浅出的精炼总结Linux核心知识点,掌握Linux的使用与高阶技巧

不说成为Linux高级工程师&#xff0c;但成为合格的软件开发人员还是够了&#xff0c;一文深入浅出的精炼总结Linux核心知识点&#xff0c;掌握Linux的使用与高阶技巧。 Linux 的学习对于一个程序员的重要性是不言而喻的。前端开发相比后端开发&#xff0c;接触 Linux 机会相对…

JVM之方法区的详细解析

方法区 方法区&#xff1a;是各个线程共享的内存区域&#xff0c;用于存储已被虚拟机加载的类信息、常量、即时编译器编译后的代码等数据&#xff0c;虽然 Java 虚拟机规范把方法区描述为堆的一个逻辑部分&#xff0c;但是也叫 Non-Heap&#xff08;非堆&#xff09; 设置方法…

STC89C52学习笔记(九)

STC89C52学习笔记&#xff08;九&#xff09; 综述&#xff1a;本文主要介绍了蜂鸣器、蜂鸣器如何使用以及如何利用蜂鸣器播放不同频率声音。 一、蜂鸣器 1.定义和作用 电信号→声音信号&#xff0c;常用来产生按键音和报警音。 2.分类 有源&#xff1a;自带振荡器&#…

基于Python的机器学习的文本分类系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

单独使用YOLOV9的backbone网络

前言 YOLO系列的网络结构都是通过.yaml来进行配置的,当要单独想使用其中的backbone网络时,可以通过yaml配置文件来进行网络搭建。 backbone的yaml配置文件与网络结构 backbone:[[-1, 1, Silence, []], # conv<

linux中级课程:延迟任务的设置(at 命令)

1.首先在系统中建立easylee账户&#xff0c;并且设置密码为easylee 2.延迟任务由root账户设置&#xff0c;要求在5小时后备份系统中的用户信息文件到/backup中&#xff0c;确保延迟任务是使用非交互模式建立 此时创建了一个test.sh脚本&#xff0c;并且使用非交互的形式进行编辑…

实在智能携AI Agent智能体亮相2024年度QCon全球软件开发大会

4月11日-13日&#xff0c;以“全面进化”作为2024年度主题的「QCon全球软件开发大会暨智能软件开发生态展」在北京隆重举行。作为AI准独角兽和超自动化头部企业&#xff0c;实在智能应邀出席发表《面向办公自动化领域的AI Agent建设思考与分享》演讲及圆桌交流&#xff0c;展示…

HDLbits 刷题 -- Mux9to1v

Create a 16-bit wide, 9-to-1 multiplexer. sel0 chooses a, sel1 chooses b, etc. For the unused cases (sel9 to 15), set all output bits to 1. Expected solution length: Around 15 lines. 译&#xff1a; 创建一个16位宽的9对1多路复用器。Sel 0选择a, Sel 1选择b&a…

硬刚Suno?StabilityAI推出Stable Audio 2.0,可生成三分钟44.1kHz立体声的高质量完整曲目

StabilityAI公司最新推出音频生成模型Stable Audio 2.0&#xff0c;该模型可通过单一自然语言提示以44.1kHz立体声播放具有连贯音乐结构的高质量、完整曲目&#xff0c;长达三分钟。 新模型超越了文本到音频的范围&#xff0c;还包括音频到音频的功能。用户现在可以上传音频样…

华为海思校园招聘-芯片-数字 IC 方向 题目分享——第四套

华为海思校园招聘-芯片-数字 IC 方向 题目分享——第四套 (共9套&#xff0c;有答案和解析&#xff0c;答案非官方&#xff0c;仅供参考&#xff09;&#xff08;共九套&#xff0c;每套四十个选择题&#xff09; 部分题目分享&#xff0c;完整版获取&#xff08;WX:didadida…

20240417,友元 FRIEND

本来要学习的吃瓜吃了一下午 目录 3.1 全局函数做友元 3.2 友元类 3.3 成员函数做友元 三&#xff0c;友元 3.1 全局函数做友元 #include<iostream> using namespace std; class Building {friend void goodGay(Building* building);//好朋友&#xff0c;可以访问…

香港科技大学广州|数据科学与分析学域硕博招生宣讲会—华东师范大学专场

时间&#xff1a;2024年4月25日&#xff08;星期四&#xff09;13:30 地点&#xff1a;华东师范大学普陀校区文附楼507 报名链接&#xff1a;https://www.wjx.top/vm/Q0cKTUI.aspx# 跨学科研究领域 *数据驱动的人工智能和机器学习 *统计学习和建模 工业和商业分析 *特定行业…

【R语言】动画图:散点图

绘制成如下的散点图&#xff1a; 如果数据量大&#xff0c;有多个年份&#xff0c;就会生成多张图&#xff0c;例如&#xff1a; 具体代码如下&#xff1a; library(gapminder)#加载 gapminder 包&#xff0c;其中包含了从 1952 年至 2007 年各个国家的 GDP、预期寿命和人口数据…

<router-link>出现Error: No match for {“name“:“home“,“params“:{}}

在将<a></a>标签换到<router-link></router-link>的时候出现No match for {"name":"home","params":{}}这样的错误&#xff0c;其中格式并无错误&#xff0c; <router-link class"navbar-brand active" …

Resilience中的RateLimiter

Resilience中的RateLimiter 一、RateLimiter&#xff08;限流&#xff09;1.常见的限流算法漏桶算法&#xff08;Leaky Bucket&#xff09;令牌桶算法&#xff08;Token Bucket&#xff09;——Spring cloud 默认使用该算法滚动时间窗口&#xff08;tumbling time window&#…

多轴机械臂/正逆解/轨迹规划/机器人运动学/Matlab/DH法 学习记录03——机械臂运动学逆解

系列文章目录 本科毕设正在做多轴机械臂相关的内容&#xff0c;这里是一个学习机械臂运动学课程的相关记录。 如有任何问题&#xff0c;可发邮件至layraliufoxmail.com问询。 1. 数学基础 2. 机械臂几何法与DH表示法 3. 机械臂运动学逆解 文章目录 系列文章目录一、引言1.手臂…

ESP8266闪存文件系统(SPIFFS)

开发环境&#xff1a; 1、安装ESP8266的开发环境&#xff0c;如Arduino IDE。 2、下载并安装ESP8266的相关开发库和工具。 我们使用的是Arduino IDE。 基本介绍&#xff1a; 每一个ESP8266都配有一个闪存&#xff0c;这个闪存很像是一个小硬盘&#xff0c;我们上传的文件就被…