深入浅出CChart 每日一课——快乐高四第七课 铁蛋的竹马,返璞归真之对话框窗口多区域绘图

上一课笨笨给大家介绍的是在普通窗口上多区域绘图,本课将介绍对话框下的情形。由于对话框的消息循环和普通窗口有一些区别,所以在具体操作上略有不同,下面的处理过程可以供大家参考。

第一步,打开VC,建立一个基于MFC AppWizard(exe)向导的项目LessonA07。向导中选择Dialog Based,其它不做任何更改,直接点Finish。

第二步,拷贝库文件到LessonA07文件夹中,

第三步,在VC界面的资源编辑器中,删除掉对话框中间的“TODO: 在这里设置对话控制。”这个标签,然后再对话框中放置两个Picture控件,并把这两个控件的ID设置为ID_CHART1和ID_CHART2。

第四步,在VC中打开LessonA07文件,在其头部加入CChart头文件和库文件的引用。

第五步,在LessonA07Dlg.h文件中给CLessonA07Dlg类添加CChart类型和CWnd*类型的成员变量。

CChart	m_Chart[2];
CWnd	*m_pWnd[2];

注意这里笨笨用的是数组,其实像上一课那样不用数组也是OK的,只是因为笨笨懒惯了,用数组可以写循环,提升键盘的使用寿命

第六步,在LessonA07Dlg.h文件的OnInitDialog函数中编写如下的初始化代码。

	CRect rt;

	// chart 1
	m_Chart[0].SetType(kTypeXY);

	for(int i=-10; i<=10; i++)
	{
		m_Chart[0].AddPoint2D(i, i*i);
	}

	m_pWnd[0] = GetDlgItem(IDC_CHART1);
	m_pWnd[0]->GetClientRect(&rt);
	m_Chart[0].SetConfineRect(rt);

	m_Chart[0].SetBkgndColor(GetSysColor(COLOR_3DFACE));

	// chart 2
	m_Chart[1].SetType(kTypePie);

	m_Chart[1].AddPie(2, "刘岩");
	m_Chart[1].AddPie(2, "瞿颖");
	m_Chart[1].AddPie(4, "周迅");
	m_Chart[1].AddPie(8, "王菲");

	m_pWnd[1] = GetDlgItem(IDC_CHART2);
	m_pWnd[1]->GetClientRect(&rt);
	m_Chart[1].SetConfineRect(rt);

注意这里和以前一样,利用SetConfineRect确定各个Chart的绘图目标区域。

第七步,在LessonA07Dlg.h文件的OnPaint函数的最前面,添加如下代码。

	for(int i=0; i<2; i++)
	{
		m_Chart[i].OnDraw(m_pWnd[i]->m_hWnd);
	}

现在可以运行了,效果如下。

第八步,添加消息处理例程。由于对话框的消息循环比较特殊,这里我们在PreTranslateMessage中处理。首先需要重载这个函数,然后改写如下。

BOOL CLessonA07Dlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO: Add your specialized code here and/or call the base class
	CRect rect;
	CPoint pt;
	CWnd *pWnd;
	int i;
	if(pMsg->message==WM_LBUTTONDOWN)
	{
		for(i=0; i<2; i++)
		{
			pWnd=m_pWnd[i];
			pWnd->GetWindowRect(&rect);
			if (rect.PtInRect(pMsg->pt))
			{
				pt = pMsg->pt;
				pWnd->ScreenToClient(&pt);
				if(m_Chart[i].OnLButtonDown(pWnd->m_hWnd, pt, 0))
				{
					m_Chart[i].OnDraw(pWnd->m_hWnd);
				}
			}
		}
	}
	else if(pMsg->message==WM_LBUTTONUP)
	{
		for(i=0; i<2; i++)
		{
			pWnd=m_pWnd[i];
			pWnd->GetWindowRect(&rect);
			if (rect.PtInRect(pMsg->pt))
			{
				pt = pMsg->pt;
				pWnd->ScreenToClient(&pt);
				if(m_Chart[i].OnLButtonUp(pWnd->m_hWnd, pt, 0))
					m_Chart[i].OnDraw(pWnd->m_hWnd);
			}
		}
	}
	else if(pMsg->message==WM_LBUTTONDBLCLK)
	{
		for(i=0; i<2; i++)
		{
			pWnd=m_pWnd[i];
			pWnd->GetWindowRect(&rect);
			if (rect.PtInRect(pMsg->pt))
			{
				pt = pMsg->pt;
				pWnd->ScreenToClient(&pt);
				if(m_Chart[i].OnLButtonDblClk(pWnd->m_hWnd, pt, 0))
					m_Chart[i].OnDraw(pWnd->m_hWnd);
			}
		}
	}
	else if(pMsg->message==WM_MOUSEMOVE)
	{
		for(i=0; i<2; i++)
		{
			pWnd=m_pWnd[i];
			pWnd->GetWindowRect(&rect);
			if (rect.PtInRect(pMsg->pt))
			{
				pt = pMsg->pt;
				pWnd->ScreenToClient(&pt);
				if(m_Chart[i].OnMouseMove(pWnd->m_hWnd, pt, 0))
					m_Chart[i].OnDraw(pWnd->m_hWnd);
			}
		}
	}
	else if(pMsg->message==WM_RBUTTONDOWN)
	{//
		for(i=0; i<2; i++)
		{
			pWnd=m_pWnd[i];
			pWnd->GetWindowRect(&rect);
			if (rect.PtInRect(pMsg->pt))
			{
				pt = pMsg->pt;
				//				pWnd->ScreenToClient(&pt);
				if(m_Chart[i].OnContextMenu(NULL, pWnd->m_hWnd, pt))
					m_Chart[i].OnDraw(pWnd->m_hWnd);
			}
		}
	}

	return CDialog::PreTranslateMessage(pMsg);
}

注意到这里处理消息的位置是在PreTranslateMessage中,原因就是由于对话框消息处理的特殊性。此外,在具体的处理过程中没有响应WM_CONTEXTMENU,而是用WM_RBUTTONDOWN代替,也是出于这个原因。

好了,这一课也结束了,希望这一课的内容能对大家有所参考。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 13:24:25

深入浅出CChart 每日一课——快乐高四第七课 铁蛋的竹马,返璞归真之对话框窗口多区域绘图的相关文章

深入浅出CChart 每日一课——快乐高四第十一课 不离不弃,利用CChartWnd实现多区域绘图

笨笨在前面的课程里面提到,在一个窗口上不能粘多个CChartWnd,否则图像不正常,故而在高四6到8课,均使用CChart类,实现了在普通窗口.对话框窗口.DuiLib窗口上的多区域绘图. 使用CChart类必须手动处理消息,而采用CChartWnd类省去了处理消息的步骤,编程更为简便. 近几天笨笨进行了一些改进,采用CChartWnd类也可以在一个窗口上多区域绘图了. 1 首先按照前面的步骤建立一个基于Win32 Application的程序,名为LessonA11. 2 在WndProc函数

深入浅出CChart 每日一课——快乐高四第十三课 月上柳梢,Win32标准控件ChartCtrl之牵手

上节课笨笨介绍了新增加的ChartCtrl控件,是在对话框中使用的.本节课简单介绍这个控件的另一种用法. 首先按照以前的步骤建立一个Win32Application. 增加WM_CREATE消息的响应例程如下. case WM_CREATE: HWND hW; hW = CreateWindow(_T("ChartCtrl"), _T("Cap"), WS_CHILD | WS_VISIBLE, 20, 20, 600, 400, hWnd, NULL, hInst

深入浅出CChart 每日一课——快乐高四第十课 见微知著,CChart内置功能介绍之数据处理篇

CChart内置数据处理功能默认是不打开的.要打开数据处理功能,请点击菜单"绘图状态-->特别功能-->允许数据处理",这时菜单"曲线数据-->数据名"下,将多出一个"数据处理"菜单,如图所示. 可以看到,笨笨内置了四种数据处理功能,线性变换.微积分.数据平滑.数据拟合. A10.1线性变换 "线性变换"菜单提供了三个功能,分别是偏移.缩放.变换.这三个功能都非常简单,只要看看弹出的对话框就全明白了. 可见,

深入浅出CChart 每日一课——快乐高四第十四课 枝头红杏,Win32标准控件ChartCtrl之围城

本节课笨笨继续介绍ChartCtrl控件在DuiLib中的应用. 请大家先复习高四第三课. 本节课的方法和这一课的方法差不多,由于笨笨提供了ChartCtrl这个新工具,所以编程可以有一定的简化. 首先,XML文件和高四第三课完全一样. 其次,cpp文件只有CreateControl部分有所修改,如下.当然,前面那个CChartWnd变量不需要了. virtual CControlUI* CreateControl(LPCTSTR pstrClassName) { if (_tcsicmp(ps

深入浅出CChart 每日一课——快乐高四第十六课 老马识途,ChartCtrl控件在WTL中的使用

这几天有个朋友想在WTL下使用ChartCtrl控件,因此笨笨在这里也写一个简单的教程. 要使用WTL当然要先安装它. 笨笨在这里介绍两个例子,一个是WTL对话框界面,一个是WTL单文档SDI界面. A16.1 WTL对话框界面 第一步,首先用AppWizard建立一个基于对话框的WTL程序LessonA16. 第二步,在主对话框资源IDD_MAINDLG上添加一个Custom Control控件,其ID设置为IDC_CHART,class设置为ChartCtrl. 第三步,拷贝库文件. 第四步

深入浅出CChart 每日一课——快乐高四第九课 于无声处,CChart内置功能介绍之数据存取篇

笨笨长期以来一直使用Origin软件画图和处理数据,但Origin软件没有编程语言的接口.笨笨开发CChart的一个潜在的目标.是想实现Origin软件的功能.当然这是一个不可能达到的目标.Origin软件的功能太强了.笨笨仅仅能膜拜. 下节课将介绍CChart内置的数据处理功能,这是笨笨向Origin的致敬. 在这之前.本节课首先介绍一下CChart内置的数据存取功能. A9.1 CChart数据保存 假定我们绘制了如图的两条曲线. 假设要保存全部曲线数据,请点击右键菜单"曲线数据-->

深入浅出CChart 每日一课——必也正名,Win32标准控件ChartCtrl之初识

各位用过CChart的小伙伴们,笨笨的这个控件还算好使吧. 慢着,慢着,让我想想,CChart是一个控件吗?好像顶多就是一个类库吧,根本就不是正儿八经的控件. 呵呵,本节课就给大家介绍一下CChart怎么作为一个Windows标准控件来使用. 还是按前面的规矩吧. 第一步,建立一个基于对话框的MFC程序LessonA12. 第二步,在LessonA12.h文件的头部加入CChart头文件和函数库的引用. 第三步,在主对话框中删除掉原来那个标签,并添加一个Custom Control控件.设置其I

NeHe OpenGL教程 第四十二课:多重视口

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第四十二课:多重视口 多重视口 画中画效果,很酷吧.使用视口它变得很简单,但渲染四次可会大大降低你的显示速度哦:) 欢迎来到充满趣味的另一课.这次我将向你展示怎样在单个窗口内显示多个视口.这些视口在窗口模式下能正确的调整大小.其中有

2018-09-08 第四十、四十一次课

第四十.四十一次课 Docker入门 目录 一. docker简介 二. 安装docker 三. 镜像管理 四. 通过容器创建镜像 五. 通过模板创建镜像 六. 容器管理 七. 仓库管理 八. 数据管理 九. 数据卷备份恢复 十. docker网络模式 十一. opration not permitted 十二. 配置桥接网络 十三. Dockerfile格式 十四. Dockerfile示例(安装nginx) 十五. 用docker compose部署服务 十六. docker compose