聚类算法演示程序-1


程序结构选择

VC内置的向导可以生成三种类型程序的框架:对话框、单文档、多文档

  • 对话框框架程序从CDialog 类起步,更适合在界面上安放各种类型的控件,用来进行人机交互,接受用户的请求,经过内部处理后返回结果。
  • 单文档/多文档框架对菜单、工具条、状态栏等UI元素有更好的包装,适应于需要对程序数据进行较多处理的应用。并且Doc-View模式在逻辑上将数据的存储和显示分开,各负其责,符合设计模式中提到的“单一职责”原则,有利于程序结构模块划分,有助于提高代码可读性和程序的可维护性等等。

这三种本质上都是窗口程序,可以说都可以实现同样的功能。但所谓龙生九子,各有各样,每一个都有自己最适合的功用。一般来说,简单的程序用对话框框架,复杂一些的用文档/视图框架
对这个聚类算法演示程序来说,需要对演示数据编辑/存储/展示,数据量不定,有文件操作需求,所以适合用Doc-View模式。至于到底是单文档还是多文档,则结合后面程序呈现界面再做考虑。

项目文件

聚类演示程序主要功能就是输入一堆数据,然后对这些数据进行聚类,展示聚类算法的执行过程。所以考虑把一次演示示例视为一个项目,输入的数据存储到一个文件中,以便用户体会/重现算法演示过程。这个文件我们就把它称为“项目文件”吧。
基于这个程序只是为了满足在教学中进行演示的目的,并不是个实际的数据分析工具,所以对于处理的数据也没太复杂的要求,就暂定两维数据罢了。
而且这个程序也不太需要考虑项目文件随着软件功能升级版本演进而带来的前后兼容问题,所以简单的存放一个列表就好。
最后定下来的数据就这么简单,直接用STL的vector加个pair就好了:

typedef vector<pair<double, double>> RAWPOINTS_T;
// Attributes
public:
    RAWPOINTS_T m_RawPoints;

数据写入和加载


void CClusterMDIDoc::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        // TODO: add storing code here
        ar << m_RawPoints.size();
        RAWPOINTS_T::const_iterator it;
        for (it = m_RawPoints.begin();it != m_RawPoints.end(); it++)
        {
            ar << (*it).first << (*it).second;
        }

    }
    else
    {
        // TODO: add loading code here
        m_RawPoints.clear();
        size_t sz;
        ar >> sz;

        for (int i = 0;i < sz;i++)
        {
            double x, y;
            ar >> x;
            ar >> y;

            m_RawPoints.push_back(make_pair(x, y));
        }

    }
}

生成的项目文件示例:


项目文件示例

文件开头四个字节为整形数据,表示数据点的总数。后面依次存放各个数据点的两维坐标值,2个double类型,共16字节。上图的文件包含20(0x14)个数据点。
写入数据时,先写入数据点总数,然后依次写入数据点的double对。加载数据时则先读入总数,然后按照总数,把各个点的数据读入到列表中。

界面效果

BCG库

VC本身只包含一些Windows标准控件,如果想把程序做得漂亮个性些,涉及到的界面效果的实现是相当折磨人的。记得6.0年代VC kbase里相当比例的文章就是介绍怎么实现一个带图片的按钮、如何在窗口背景上画上一幅图片等等。这些零零碎碎的个性化控件和一些第三方控件库实现方式五花八门,用起来也颇为繁琐,我估计那时程序员60-70%的精力都在对付程序的界面效果上,小项目时的比例可能还要更多。老板评价员工水平高低往往多从这些视觉效果出发:你看人家实现的按钮,圆角的,标题栏边缘听说还是贝塞尔曲线画出来的,你看你做的方方正正,看起来就呆头呆脑的......最近,我这儿的一个老同志吹嘘他学生做的一个小程序时还这样说,哈哈
所以在当时的应用以MIS系统为主的情况下,RAD工具快速兴起了。PowerBuilder、Delphi、VB这些工具拿鼠标点点放放就能凑出个像样的界面,弄个CURD功能不需要写多少代码。所以那时VC和Delphi的程序经常互相鄙视。
自古以来就文人相轻,一直到现在,在程序设计领域也存在错综复杂的鄙视链,当然那时我是VC党。
记得当时有两个比较完备的控件库,一个忘了名字,一个就是BCG ControlBar。下面引自百度百科

BCGControlBar(Business Components Gallery ControlBa[1] r)专业版是MFC的一个扩展库,您可以用来构建类似于Microsoft® Office 2000/XP/2003/2007/2010/2013、Microsoft Visual Studio(打印、用户定制工具栏、菜单等)和其他一些知名产品的高级用户界面,例如:日历、网格、编辑和甘特图等。
BCGControlBar的这个扩展库包含了300多个经过精心设计,测试和具有完备文档的MFC扩展类。BCGControlBar控件能轻松的融入应用程序中,节约大量的的开发和调试时间。

好像从VS2008起,微软就把BCG融到MFC中了,但不知为什么BCG还在发展?
VS的应用程序向导现在都支持BCG效果了,但例子不太好找,只好下了个xx版的BCGControlBar Pro25.10。主要是为了借用它其中的Grid控件和工具条设计工具以及DockControlBar的一些功能。

界面/功能安排

这个程序的主要功能包含三部分:表格方式编辑数据,图形方式编辑数据,算法运行演示
编辑数据时可以选择用表格方式或图形方式,各用一个View来实现。但这两种方式如何安排好呢?是并排显示还是相互遮盖用个命令来相互切换好呢?考虑到每种显示方式下还有较多的操作,并排的话比较乱,而且数据同步的问题比较麻烦,所以就决定采用遮盖切换的方式。
算法运行演示和数据编辑功能应该隔离开,运行演示时最好不要修改数据。所以把算法运行演示功能放到弹出的模态对话框中实现,演示结束关闭对话框回到编辑功能。

单文档还是多文档

采取单文档还是多文档结构对文档的数据操作部分影响不大,但是对View的管理则区别较大。单文档结构下所有的View共享同一个主框架窗口,切换时主要是设置新的View的ID为AFX_IDW_PANE_FIRST然后隐藏旧的显示新的。
但是做到一半时,发现在图形编辑界面时,由于采取在切分窗口里显示刻度标尺,View也位于某个切分窗口栏下,这样窗口层次变成:主窗口->切分窗口->View,和表格编辑界面的:主窗口->View明显不同。解决方案之一就是把表格编辑View也放到切分窗口下,当切换到它时再把标尺窗口隐藏。试了试,发现窗口边缘明显有个小条条存在,不太美观,于是就放弃了,推倒,用多文档结构重搞。
多文档结构下每个View都处于单独的子框架窗口下,这样切换View变成了切换子框架窗口。带来的好处是各个子框架窗口完全自己定制,不会相互影响了。但这时候要注意要让每个子框架妥贴的处理各个MDI消息,否则子窗口飘起来了就盖不住另外的窗口了。另外由于MFC处理MDI机制问题,在MDI标题栏的文档名字后显示窗口编号123等等的,看起来很别扭,也要在OnUpdateFrameTitle中处理掉。

小结

把上面这些问题明确后,就把程序的大致框架确定了下来。
接下来几天要回媳妇老家参加侄女婚礼,等回来了接着写
原来在PLA时不让写博客之类的东西,现在自由了,能写就多写点儿
写这些东西也没啥用,主要最近有点儿失业焦虑症,写点儿东西找点儿事儿做,哈哈

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,050评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,943评论 4 60
  • 程序框架搭建 上一篇文章提到了使用的BCG版本是BCGControlBar Pro25.10,安装过程中会识别安装...
    有理想的大脸猫阅读 777评论 0 0
  • 电影 这两天看了两部非常值得推荐的电影《知无涯者》和《血钻》。 《知无涯者》是个真事改编来的,讲述一个天才的印度数...
    liang_echo阅读 409评论 0 0
  • 诗歌 / 赋 是谁 催老了岁月 是谁 模糊了双眼 岁月染指 风华已不在 皱纹布满了脸颊 眼睛也失去了年青时神采奕...
    晓月煜焥阅读 422评论 0 2