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

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

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

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

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

 

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

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

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

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

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

	// 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_Chart[0].SetBkgndColor(GetSysColor(COLOR_3DFACE));
	
	// chart 2
	m_Chart[1].SetType(kTypePie);
	
	m_Chart[1].AddPie(2, _T("刘岩"));
	m_Chart[1].AddPie(2, _T("瞿颖"));
	m_Chart[1].AddPie(4, _T("周迅"));
	m_Chart[1].AddPie(8, _T("王菲"));
	
	m_pWnd[1] = GetDlgItem(IDC_CHART2);

第七步,在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);
				m_Chart[i].OnLButtonDownR(pWnd->m_hWnd, pt, 0);
			} 
		}
	}
	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);
				m_Chart[i].OnLButtonUpR(pWnd->m_hWnd, pt, 0);
			} 
		}
	}
	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);
				m_Chart[i].OnLButtonDblClkR(pWnd->m_hWnd, pt, 0);
			} 
		}
	}
	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);
				m_Chart[i].OnMouseMoveR(pWnd->m_hWnd, pt, 0);
			} 
		}
	}
	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);
				m_Chart[i].OnContextMenuR(NULL, pWnd->m_hWnd, pt);
			} 
		}
	}
	
	return CDialog::PreTranslateMessage(pMsg);
}

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

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

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值