上节课对CChart在新版炫彩界面库中的使用进行了详细说明,大家看到CChart对炫彩界面库具有完美的兼容性。
但是呢,大家也发现了,要实现CChart的完整功能,需要用户编写的代码不少,杂七杂八地接近100行。虽然每行代码的作用都很容易理解,但这么多代码还是容易劝退很多人。
为此,针对炫彩界面库,笨笨进行了一个简单包装,以简化用户代码,包装代码位于一个头文件XCChart.h之中。
利用这个文件,只需要4行代码即可完美支持CChart!
该头文件的内容主要分以下几部分。
CChart相关文件支持:
#include "Chart.h"
#if defined(_UNICODE) || defined(UNICODE)
# pragma comment(lib,"CChartu.lib")
#else
# pragma comment(lib,"CChart.lib")
#endif
using namespace NsCChart;
#include <math.h>
DirectUI修正宏命令:
#define XC_CChart_EleMsgRepair(hWindowM, chartM, IDS) {\
HELE hMyPanel = (HELE)XC_GetObjectByIDName(hWindowM, IDS);\
RECT rect;\
XEle_GetWndClientRect(hMyPanel, &rect);\
chartM.SetAdditionalCanvasOffset(rect.left, rect.top);\
chartM.SetDuiRepair(true);\
}\
CChart消息注册宏命令
#define XC_CChart_RegEleEventCPP(XCWinClass, hWindowM, IDS) {\
HELE hMyPanel = (HELE)XC_GetObjectByIDName(hWindowM, IDS);\
XEle_RegEventCPP(hMyPanel, XE_PAINT, &##XCWinClass##::OnEleDraw);\
XEle_RegEventCPP(hMyPanel, XE_LBUTTONDOWN, &##XCWinClass##::OnEleLButtonDown);\
XEle_RegEventCPP(hMyPanel, XE_LBUTTONUP, &##XCWinClass##::OnEleLButtonUp);\
XEle_RegEventCPP(hMyPanel, XE_LBUTTONDBCLICK, &##XCWinClass##::OnEleLButtonDblClk);\
XEle_RegEventCPP(hMyPanel, XE_RBUTTONDOWN, &##XCWinClass##::OnEleRButtonDown);\
XEle_RegEventCPP(hMyPanel, XE_MOUSEMOVE, &##XCWinClass##::OnEleMouseMove);\
XEle_RegEventCPP(hMyPanel, XE_MOUSEWHEEL, &##XCWinClass##::OnEleMouseWheel);\
XEle_RegEventCPP(hMyPanel, XE_KEYDOWN, &##XCWinClass##::OnEleKeyDown);\
XEle_EnableEvent_XE_MOUSEWHEEL(hMyPanel, TRUE);\
}\
CChart消息定义宏命令:
#define XC_CChart_DecEleEventCPP(hWindowM, chartM, IDS)\
int OnEleDraw(HDRAW hDraw, BOOL *pbHandled)\
{\
RECT rect;\
HELE hMyPanel = (HELE)XC_GetObjectByIDName(hWindowM, IDS);\
XEle_GetClientRect(hMyPanel, &rect);\
HDC hDC = XDraw_GetHDC(hDraw);\
XEle_DrawEle(hMyPanel, hDraw);\
if(XC_IsEnableD2D())\
{\
chartM.OnDraw(hDC, rect);\
}\
else\
{\
chartM.OnDraw(hDC, rect);\
}\
\
*pbHandled=TRUE;\
return 0;\
}\
int OnEleLButtonDown(UINT nFlags, POINT *pPt, BOOL *pbHandled)\
{\
HWND hWnd = XWnd_GetHWND(hWindowM);\
if(chartM.OnLButtonDown(hWnd, *pPt, 0))\
{\
XWnd_Redraw(hWindowM);\
}\
*pbHandled = FALSE;\
return 0;\
}\
int OnEleLButtonUp(UINT flags, POINT *pPt, BOOL *pbHandled)\
{\
HWND hWnd = XWnd_GetHWND(hWindowM);\
if(chartM.OnLButtonUp(hWnd, *pPt, 0))\
{\
XWnd_Redraw(hWindowM);\
}\
*pbHandled = FALSE;\
return 0;\
}\
int OnEleLButtonDblClk(UINT nFlags, POINT *pPt, BOOL *pbHandled)\
{\
HWND hWnd = XWnd_GetHWND(hWindowM);\
if(chartM.OnLButtonDblClk(hWnd, *pPt, 0))\
{\
XWnd_Redraw(hWindowM);\
}\
*pbHandled = FALSE;\
return 0;\
}\
int OnEleRButtonDown(UINT nFlags, POINT *pPt, BOOL *pbHandled)\
{\
HELE hMyPanel = (HELE)XC_GetObjectByIDName(hWindowM, IDS);\
XEle_PointClientToWndClient(hMyPanel, pPt);\
\
HWND hWnd = XWnd_GetHWND(hWindowM);\
ClientToScreen(hWnd, pPt);\
if(chartM.OnContextMenu(NULL, hWnd, *pPt))\
{\
XWnd_Redraw(hWindowM);\
}\
*pbHandled = FALSE;\
return 0;\
}\
int OnEleMouseMove(UINT nFlags, POINT *pPt, BOOL *pbHandled)\
{\
HWND hWnd = XWnd_GetHWND(hWindowM);\
if(chartM.OnMouseMove(hWnd, *pPt, 0))\
{\
XWnd_Redraw(hWindowM);\
}\
*pbHandled = FALSE;\
return 0;\
}\
int OnEleMouseWheel(UINT nFlags,POINT *pPt,BOOL *pbHandled)\
{\
HWND hWnd = XWnd_GetHWND(hWindowM);\
if(chartM.OnMouseWheel(hWnd, *pPt, 0))\
{\
XWnd_Redraw(hWindowM);\
}\
*pbHandled = FALSE;\
return 0;\
}\
int OnEleKeyDown(WPARAM wParam, LPARAM lParam, BOOL *pbHandled)\
{\
HWND hWnd = XWnd_GetHWND(hWindowM);\
UINT key = (UINT)wParam;\
if(chartM.OnKeyDown(hWnd, key))\
{\
XWnd_Redraw(hWindowM);\
}\
*pbHandled = FALSE;\
return 0;\
}\
可以看到,上一课的所有代码,除了CChart添加数据这一部分外,都可以用三个宏命令来解决。
消息响应函数定义宏:
XC_CChart_DecEleEventCPP(hWindowM, chartM, IDS)
第一个参数是HWINDOW变量,也就是炫彩主窗口变量。
第二个参数是一个CChart变量,需要用户提前放置好。
第三个参数是绘图所用元素的ID,用字符串表示,例如L”ID_PICTURE_1”。
消息注册宏:
XC_CChart_RegEleEventCPP(XCWinClass, hWindowM, IDS)
第一个参数是C++类名,如上一课中的CMyWindowDemo。
第二个参数是HWINDOW变量,也就是炫彩主窗口变量。
第三个参数是绘图所用元素的ID,用字符串表示,例如L”ID_PICTURE_1”。
DirectUI修正宏
XC_CChart_EleMsgRepair(hWindowM, chartM, IDS)
第一个参数是HWINDOW变量,也就是炫彩主窗口变量。
第二个参数是一个CChart变量,需要用户提前放置好。
第三个参数是绘图所用元素的ID,用字符串表示,例如L”ID_PICTURE_1”。
好,现在所有问题都阐释清楚了,下面利用新出炉的XCChart.h,重新编写上一课代码。
1、用炫彩设计器建一个和上一课完全一样的界面工程Simple,直接复制上一课的内容亦可。
2、新建一个VC6的Win32 Application空工程LessonA58,注意是空工程。
3、拷贝炫彩界面库文件xcgui.h、XCGUI.lib、XCGUI.dll到LessonA58文件夹,拷贝CChart库文件Chart.h、Chart.lib、Chart.dll、Chartu.lib、Chartu.dll到LessonA58文件夹。
4、按上面内容新建XCChart.h。实际上笨笨已经建立好了这个文件,拷贝过去即可。
5、新建一个LessonA58.cpp并加入到工程,从炫彩界面库的说明书中,拷贝一个以cpp方式加载界面布局文件的模板,并在抬头加上#include <windows.h>。这和上一课完全一样,不赘述。如果不好找,直接从上一课拷贝。
写入正确的xml布局文件路径。
XC_LoadResource(L".\\Simple\\resource.res");
HXCGUI hXCGUI=XC_LoadLayout(L".\\Simple\\main.xml");
6、添加CChart支持
#include "XCChart.h"
够简单吧!
7、添加一个CChart变量
CChart m_Chart;
这句话放置在模板文件的HWINDOW m_hWindow;之后即可。
8、定义消息响应函数
XC_CChart_DecEleEventCPP(m_hWindow, m_Chart, L"ID_PICTURE_1");
这句话放置在上一句话CChart m_Chart;之后即可。
9、注册消息响应函数
XC_CChart_RegEleEventCPP(CMyWindowDemo, m_hWindow, L"ID_PICTURE_1");
这句话只要在Init()函数里面即可,位置没有特定要求。这里我们把它放置XWnd_ShowWindow(m_hWindow,SW_SHOW);这一行之后。
10、DirectUI修正
XC_CChart_EleMsgRepair(m_hWindow, m_Chart, L"ID_PICTURE_1");
这句话的位置有一定要求,要放置在Init()函数里面,XWnd_ShowWindow(m_hWindow,SW_SHOW);这一行之后。这里直接放置在上一句代码之后。
基本快打完收工了, 只用了4句话就完美支持CChart了,多么的easy!
运行一下。
咦,没有东西啊?
原来我们还没有添加数据!
在Init()函数里面,添加和上一课同样的代码,就得到和上一课同样的图像。
double pi=4.0*atan(1.0);
for(int i=0; i<720; ++i)
{
m_Chart.AddPoint2D(i, 1.3*sin(i*2.0*pi/360));
}
m_Chart.SetTitle(_T("炫彩界面库"));
这样也忒没意思了,我们还是换一个图像吧,画一个饼图,代码改成这样。
m_Chart.SetType(kTypePie);
m_Chart.AddPie(3, _T("一饼"));
m_Chart.AddPie(4, _T("二饼"));
m_Chart.AddPie(5, _T("三饼"));
m_Chart.SetTitle(_T("炫彩界面库画饼图"));
结果如图。
这一课就结束了。采用本课的方法,在炫彩界面库中使用CChart,只需要几行代码即可,非常简便!