深入浅出CChart 每日一课——快乐高四第四课 冰山上的来客,锦上添花之插件菜单篇

来源:互联网 发布:js 瀑布流 实现原理 编辑:程序博客网 时间:2024/06/10 08:29

CChart的交互功能很强,笨笨一向引为自豪。交互功能的一个重要组成部分就是右键菜单。


同学们试一试就能知道,CChart的右键菜单功能是非常丰富的。尤其是还有很多功能在包装类中暂时还没有,只能在右键菜单或对话框中使用。

虽然默认的右键菜单功能已经令笨笨自己满意了,但不见得能让所有的人满意。怎么办呢?那就需要用户自己定制。

定制的方法有两种。

一种方法是革命性的的,那就是把默认的菜单全部替换掉。这个想法非常非常好,但是看起来好像不那么容易,是不是要改源码呀?Oh,NO。完全不需要,笨笨已经贴心地为大家提供了子类化功能。子类化不仅可以修改右键菜单,也可以改变默认的消息响应,甚至显示的图像也可以完全按要求定制。关于子类化功能,以后会专门介绍。

另一种方法那就是康有为、梁启超的办法,改良,君主立宪,不修改默认菜单,而是往菜单里面添加新的菜单项。这个看起来似乎更难了,真的是这样吗?

下面笨笨就给大家介绍第二种方法,在右键菜单中增添插件菜单。

 

第一步,按照第一课的方法建立一个工程,名为LessonA04,具体步骤不再详述。同时按第二课的介绍,激活鼠标双击功能。

 

第二步,定义一个菜单的标识ID。

既然是菜单,就必然有ID。

在WndProc函数的上面定义菜单ID,代码如下。

 const int menuID = 40000; 

这里定义的ID比较大,是为了避免和CChart默认菜单的ID冲突。一般大于32768即可,当然不能大于65535。

 

第三步,编写建立插件菜单项的函数。

 voidAddPluginMenu( void *plot, HMENU addMenu ){AppendMenu(addMenu, MF_SEPARATOR, 0, (LPCTSTR)0 );AppendMenu(addMenu, MF_STRING, menuID, _TEXT("附加菜单项1"));HMENU  subMenu = CreatePopupMenu();AppendMenu(subMenu, MF_STRING, menuID+1, _TEXT("附加菜单项2"));AppendMenu(addMenu, MF_POPUP, (UINT) subMenu, _TEXT("附加弹出项"));DestroyMenu(subMenu);} 

注意函数的形式,包括参数和返回值必须和上面一模一样,否则程序崩溃莫得商量。

可以看见,上面的代码实际增加了两个菜单项,ID分别是menuID和menuID+1,名字分别为“附加菜单项1”和“附加菜单项2”,其中第二个菜单项是放在一个弹出菜单“附加弹出项”中的。

这一套完全是Win32API的玩法,CChart内部所有的右键菜单都是这么做出来的。

 

第四步,建立菜单项的处理函数。

 intIntPluginMenu( void *plot, HWND hWnd, int result ){CChart *pChart = (CChart *)plot;if(result == menuID){const TCHAR *title = pChart->GetTitle();TCHAR str[128];_stprintf(str, _T("图像标题为:%s"), title);MessageBox(hWnd, str, _T("附加菜单"), MB_OK);return -3;}else if(result == menuID + 1){static int count = 4;pChart->AddPoint2D((double)count, (double)count*count);count++;return -3;}return -2;} 

注意上面的代码中,把一个void*指针转换成了我们需要的CChart*指针,有了这个CChart*指针,我们想干啥就可以干啥了,上面第一个菜单项获取了图像标题并显示在消息框里,第二个菜单项在屏幕的曲线上增加一个数据点。真的是很方便呀。

那么,这个指针是从哪里来的呢?别慌,答案在第五步。

还有这里返回值的含义,-3表示更新视图,-2表示不动作,-1表示出错。

由于使用了sprintf,需要在LessonA04.cpp的头部附近增加一行。

 #include <stdio.h> 

第五步,在WM_CREATE的处理例程中增加一行。

 chartWnd.GetChart()->SetPluginMenu(AddPluginMenu, IntPluginMenu, chartWnd.GetChart()); 

注意了,SetPluginMenu有三个参数,前两个参数就是前两步编写的那两个函数,分别建立菜单和处理菜单。特别要注意第三个参数了。看到了吧,这里传进去就是一个CChart*指针。

大家要小心,如果那两个函数定义的方式(包括返回值和形参)不对,或者第三个参数传递不匹配,程序崩溃无商量。

OK,大功告成。

为了确认大家的代码和笨笨的一样,请检查WM_CREATE处理例程是不是下面这样的。

 case WM_CREATE:chartWnd.Attach(hWnd, kTypeXY);chartWnd.GetChart()->SetPluginMenu(AddPluginMenu, IntPluginMenu, chartWnd.GetChart());chartWnd.GetChart()->AddPoint2D(-3.0, 9.0);chartWnd.GetChart()->AddPoint2D(-2.0, 4.0);chartWnd.GetChart()->AddPoint2D(-1.0, 1.0);chartWnd.GetChart()->AddPoint2D(0.0, 0.0);chartWnd.GetChart()->AddPoint2D(1.0, 1.0);chartWnd.GetChart()->AddPoint2D(2.0, 4.0);chartWnd.GetChart()->AddPoint2D(3.0, 9.0);chartWnd.GetChart()->SetTitle(_T("Hello World,我的第一个CChart程序!"));break; 

这段代码主要就是从第一课拷贝过来的,呵呵。

下面看看劳动成果。


大家可以看看两个新菜单项的功能是不是如我们所愿。如果有所差别,肯定是上面的代码写得不一样了,呵呵。

本节课笨笨给大家介绍了CChart的插件菜单功能,这个功能可能不见得能有多实用,但可以展示CChart的强大内核。

下一课笨笨将介绍一个非常实用的功能——客户区自绘,改变CChart的默认显示状态。这个功能应该在非常多的场合都能用到,敬请期待。

提请注意,请到www.cchart.net网站下载最新版本的CChart。旧版本不保证能实现本节课的功能。

7 0
原创粉丝点击