深入浅出CChart 每日一课――第十七课 时尚加潮流,DirectUI之炫彩界面库

笨笨是一个因循守旧的人,一向对新潮的东西不感冒,如今21世纪都过去百分之十几了,笨笨还在使用二十世纪的VC6。而IT领域是一个长江后浪推前浪,前浪死在沙滩上的世界,所以至今为止,笨笨还被IT领域拒之门外。

虽然笨笨是个老古板,但偶尔追追潮流也是可以的嘛。这些年DirectUI好像红透大江南北。笨笨也稍微了解了一下,觉得这种编程思想是值得提倡的。

目前优秀的DirectUI库,商业的就不说了,开源的笨笨知道的有DuiLib和炫彩界面库。

DuiLib是一款优秀的国产开源DirectUI库。笨笨在VS2010上把其例子跑通过,但VC6下不行。接触其代码不多,反正觉得有些不习惯。

炫彩界面库是另一款优秀的过程开源DirectUI库。笨笨对这个库用起来感觉非常顺手,而且不仅在VS2010上,在笨笨亲爱的VC6上也跑通了。所以笨笨决定跟定炫彩了,今生非她不娶。

经过一段时间的调试,目前CChart和炫彩界面库已经完美兼容了。

有一点要说明。炫彩界面库基于无窗口的思想,里面只有一个主窗口,其它窗口都是自绘的;而CChart还是原始的Windows编程思想,里面操作都基于窗口。当CChart爱上炫彩后,爱情的结晶就是一个混血儿。唯一的问题是用CChart弹出的对话框和炫彩本身的对话框风格不一样。如果不用交互功能,不弹出对话框的话,那就没有风格不同的问题了。

下面笨笨向大家展示小伙CChart追求妙龄少女炫彩姑娘的全过程。

作为准备工作,需要同学们在炫彩界面库的官方网站www.xcgui.com上下载最新的炫彩库。

Now,letsgo!

第一步,用VC建立一个Win32Application工程,名为Lesson17。注意在向导中选择Anemptyproject,即空工程。

第二步,把CChart的五个库文件Chart.hPlotDll_d.libPlotDll_d.dllPlotDll.libPlotDll.dll拷贝到Lesson17文件夹中,同时解压缩炫彩的压缩包,在lib目录里找到xcgui.hxcguid.libxcguid.dllxcgui.libxcgui.dll这五个库文件,同样拷贝到Lesson17文件夹中。

第三步,在VC中新建一个Lesson17.cpp文件,添加进工程,并在这个文件中输入下列从炫彩帮助文档中拷贝出来的内容。

//包含炫彩界面库文件
#include "xcgui.h"
#ifdef _DEBUG
#pragma comment(lib, "XCGUId.lib")
#else
#pragma comment(lib, "XCGUI.lib")
#endif

//CXEventMsg  : C++消息事件接口类
//CMyWnd      : 我的窗口类
class CMyWnd : public CXEventMsg
{
public:
	HWINDOW m_hWindow; //窗口句柄
    
	BOOL Create() //创建窗口和按钮
	{
		m_hWindow=XWnd_CreateWindow(0,0,400,300,L"炫彩界面库-窗口"); //创建窗口
		if(m_hWindow)
		{
			XWnd_ShowWindow(m_hWindow,SW_SHOW); //显示窗口
			return true;
		}
		return false;
	}
};

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow)
{
	XInitXCGUI(); //初始化
	
	CMyWnd  MyWnd;
	if(MyWnd.Create())
	{
		XRunXCGUI(); //运行
	}
	return 0;
}
 
编译并运行,效果如下。

SouthEast

炫彩的窗口出来啦!下面我们就在这个窗口上,开展我们的工作。

第四步,加入CChart的头文件和库文件。

#include "Chart.h"
#ifdef _DEBUG
#pragma comment(lib, "PlotDll_d.lib")
#else
#pragma comment(lib, "PlotDll.lib")
#endif
 
第五步,加入数学库头文件。
#include <math.h>
 
第六步,定义CChart变量。在HWINDOWm_hWindow;这一行下面,输入以下代码。
CChart m_Chart;
第七步,修改OnCreate函数。改后如下。
BOOL Create() //创建窗口和按钮
{
	m_hWindow=XWnd_CreateWindow(0,0,800,600,L"炫彩界面库-窗口"); //创建窗口
	if(m_hWindow)
	{
		HWND hWnd = XWnd_GetHWnd(m_hWindow);
		
		m_Chart.SetType(kTypeXY, hWnd);
		
		const int nLen = 501;
		double pX[nLen], pY[nLen];
		int i, dataID;
		for(i=0; i<nLen; i++)
		{
			pX[i]=2.0/(nLen-1.0)*i;
			pY[i]=2*sin(pX[i]*8.0*myPi) + (2.0*rand()/RAND_MAX-1.0)*0.3;
		}
		dataID = m_Chart.AddCurve(pX, pY, nLen);
		m_Chart.SetDataTitle("Test data 1", 0, 0);
			
		for(i=0; i<nLen; i++)
		{
			pX[i]=2.0/(nLen-1.0)*i;
			pY[i]=(i-nLen/2.0)*(i-nLen/2.0)/nLen/nLen*20.0 + (2.0*rand()/RAND_MAX-1.0)*0.1;
		}
		dataID = m_Chart.AddCurve(pX, pY, nLen);
		m_Chart.SetDataTitle("Test data 2", 1, 0);
		m_Chart.SetTitle("在炫彩界面库中绘图");
			
		XCGUI_RegWndMessage(m_hWindow, WM_PAINT, &CMyWnd::OnWndPaint);
		XCGUI_RegWndMessage(m_hWindow, WM_LBUTTONDOWN, &CMyWnd::OnWndLButtonDown);
		XCGUI_RegWndMessage(m_hWindow, WM_LBUTTONUP, &CMyWnd::OnWndLButtonUp);
		XCGUI_RegWndMessage(m_hWindow, XWM_MOUSEDBCLICK, &CMyWnd::OnWndLButtonDblClk);
		XCGUI_RegWndMessage(m_hWindow, WM_MOUSEMOVE, &CMyWnd::OnWndMouseMove);
		XCGUI_RegWndMessage(m_hWindow, WM_KEYDOWN, &CMyWnd::OnWndKeyDown);
		XCGUI_RegWndMessage(m_hWindow, WM_RBUTTONDOWN, &CMyWnd::OnWndRButtonDown);
			
		XWnd_ShowWindow(m_hWindow,SW_SHOW); //显示窗口
		return true;
	}
	return false;
}
第八步,建立OnPaint函数,实现绘图功能。
RECT rect;
int dx, dy;
	
BOOL OnWndPaint(HWINDOW hWindow, HDRAW hDraw)
{
	XWnd_GetDrawRect(hWindow, &rect);
	HDC hDC = XDraw_GetHDC_(hDraw);

	XDraw_GetOffset_(hDraw, &dx, &dy);
	rect.left += dx;
	rect.top += dy;
	rect.right -= dx;
	rect.bottom -= dx;
	m_Chart.OnDraw(hDC, rect);
	return FALSE;
}
 


注意这里在OnWndPaint的前面定义了几个变量,这些变量在OnWndPaint函数中有用,定义在函数外面的目的是后面的消息响应函数也要用到。

在炫彩界面库中,不能直接在炫彩中主窗口的客户区上绘图,必须加上偏移。因为炫彩的主窗口整个都是客户区,其标题栏等元素是在客户区上画出来的,直接在主窗口客户区绘图就会和标题栏以及边框等元素重叠。

上面的代码展示了从炫彩获得客户区HDC并加上偏移的处理方法。

第九步,实现交互功能的消息处理。代码如下。

BOOL OnWndLButtonDown(HWINDOW hWindow,UINT flags,POINT *pPt)
{
	HWND hWnd = XWnd_GetHWnd(hWindow);
	POINT point = *pPt;
	point.x += dx;
	point.y += dy;
	
	if(m_Chart.OnLButtonDown(hWnd, point))
	{
		XWnd_RedrawWnd(hWindow);
	}
	return FALSE;
}
BOOL OnWndLButtonUp(HWINDOW hWindow,UINT flags,POINT *pPt)
{
	HWND hWnd = XWnd_GetHWnd(hWindow);
	POINT point = *pPt;
	point.x += dx;
	point.y += dy;
	
	if(m_Chart.OnLButtonUp(hWnd, point))
	{
		XWnd_RedrawWnd(hWindow);
	}
	return FALSE;
}
BOOL OnWndLButtonDblClk(HWINDOW hWindow,POINT *pPt)
{
	HWND hWnd = XWnd_GetHWnd(hWindow);
	POINT point = *pPt;
	point.x += dx;
	point.y += dy;
	
	if(GetCapture())
	{
		ReleaseCapture();
	}
	
	if(m_Chart.OnLButtonDblClk(hWnd, point))
	{
		XWnd_RedrawWnd(hWindow);
	}
		
	return FALSE;
}
BOOL OnWndMouseMove(HWINDOW hWindow,UINT flags,POINT *pPt)
{
	HWND hWnd = XWnd_GetHWnd(hWindow);
	POINT point = *pPt;
	point.x += dx;
	point.y += dy;
	
	if(m_Chart.OnMouseMove(hWnd, point))
	{
		XWnd_RedrawWnd(hWindow);
	}
	return FALSE;
}
BOOL OnWndKeyDown(HWINDOW hWindow,WPARAM wParam,LPARAM lParam)
{
	HWND hWnd = XWnd_GetHWnd(hWindow);
	UINT	key = wParam;
	
	if(m_Chart.OnKeyDown(hWnd, key))
	{
		XWnd_RedrawWnd(hWindow);
	}
	return FALSE;
}
BOOL OnWndRButtonDown(HWINDOW hWindow,UINT flags,POINT *pPt)
{
	HWND hWnd = XWnd_GetHWnd(hWindow);
	POINT point = *pPt;
	point.x += dx;
	point.y += dy;
	ClientToScreen(hWnd, &point);
	
	if(m_Chart.OnContextMenu(NULL, hWnd, point))
	{
		XWnd_RedrawWnd(hWindow);
	}
	return FALSE;
}
 


上面的代码利用CChart的消息处理函数,根据炫彩的实际情况处理各种消息。

好,准备收工了。看看我们的劳动成果。

SouthEast

哈哈,真不错哟。

下面我们看看CChart的右键菜单,如图。

SouthEast

和原来没有什么变化嘛。

再看看CChart的对话框。

SouthEast

果然是混血型,呵呵。

本节课的代码看似较多,实际上都是可以拷贝的,实际编码量不算大,而这些代码的含义是非常容易理解的。

到目前为止,我们的帅小伙CChart终于成功牵手梦中情人炫彩。耶!

你可能感兴趣的:(教程,数据可视化,CChart,炫彩界面库)