程序結構選擇
VC內置的向導可以生成三種類型程序的框架:對話框叉存、單文檔阎曹、多文檔雕拼。
- 對話框框架程序從CDialog 類起步纵东,更適合在界面上安放各種類型的控件,用來進行人機交互啥寇,接受用戶的請求偎球,經(jīng)過內部處理后返回結果。
- 單文檔/多文檔框架對菜單辑甜、工具條衰絮、狀態(tài)欄等UI元素有更好的包裝,適應于需要對程序數(shù)據(jù)進行較多處理的應用磷醋。并且Doc-View模式在邏輯上將數(shù)據(jù)的存儲和顯示分開猫牡,各負其責,符合設計模式中提到的“單一職責”原則子檀,有利于程序結構模塊劃分镊掖,有助于提高代碼可讀性和程序的可維護性等等。
這三種本質上都是窗口程序褂痰,可以說都可以實現(xiàn)同樣的功能亩进。但所謂龍生九子,各有各樣缩歪,每一個都有自己最適合的功用归薛。一般來說,簡單的程序用對話框框架匪蝙,復雜一些的用文檔/視圖框架主籍。
對這個聚類算法演示程序來說,需要對演示數(shù)據(jù)編輯/存儲/展示逛球,數(shù)據(jù)量不定千元,有文件操作需求,所以適合用Doc-View模式颤绕。至于到底是單文檔還是多文檔幸海,則結合后面程序呈現(xiàn)界面再做考慮。
項目文件
聚類演示程序主要功能就是輸入一堆數(shù)據(jù)奥务,然后對這些數(shù)據(jù)進行聚類物独,展示聚類算法的執(zhí)行過程。所以考慮把一次演示示例視為一個項目氯葬,輸入的數(shù)據(jù)存儲到一個文件中挡篓,以便用戶體會/重現(xiàn)算法演示過程。這個文件我們就把它稱為“項目文件”吧帚称。
基于這個程序只是為了滿足在教學中進行演示的目的官研,并不是個實際的數(shù)據(jù)分析工具,所以對于處理的數(shù)據(jù)也沒太復雜的要求闯睹,就暫定兩維數(shù)據(jù)罷了阀参。
而且這個程序也不太需要考慮項目文件隨著軟件功能升級版本演進而帶來的前后兼容問題,所以簡單的存放一個列表就好瞻坝。
最后定下來的數(shù)據(jù)就這么簡單蛛壳,直接用STL的vector加個pair就好了:
typedef vector<pair<double, double>> RAWPOINTS_T;
// Attributes
public:
RAWPOINTS_T m_RawPoints;
數(shù)據(jù)寫入和加載
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));
}
}
}
生成的項目文件示例:
文件開頭四個字節(jié)為整形數(shù)據(jù),表示數(shù)據(jù)點的總數(shù)所刀。后面依次存放各個數(shù)據(jù)點的兩維坐標值衙荐,2個double類型,共16字節(jié)浮创。上圖的文件包含20(0x14)個數(shù)據(jù)點忧吟。
寫入數(shù)據(jù)時,先寫入數(shù)據(jù)點總數(shù)斩披,然后依次寫入數(shù)據(jù)點的double對溜族。加載數(shù)據(jù)時則先讀入總數(shù)讹俊,然后按照總數(shù),把各個點的數(shù)據(jù)讀入到列表中煌抒。
界面效果
BCG庫
VC本身只包含一些Windows標準控件仍劈,如果想把程序做得漂亮個性些,涉及到的界面效果的實現(xiàn)是相當折磨人的寡壮。記得6.0年代VC kbase里相當比例的文章就是介紹怎么實現(xiàn)一個帶圖片的按鈕贩疙、如何在窗口背景上畫上一幅圖片等等。這些零零碎碎的個性化控件和一些第三方控件庫實現(xiàn)方式五花八門况既,用起來也頗為繁瑣这溅,我估計那時程序員60-70%的精力都在對付程序的界面效果上,小項目時的比例可能還要更多棒仍。老板評價員工水平高低往往多從這些視覺效果出發(fā):你看人家實現(xiàn)的按鈕悲靴,圓角的,標題欄邊緣聽說還是貝塞爾曲線畫出來的莫其,你看你做的方方正正对竣,看起來就呆頭呆腦的......最近,我這兒的一個老同志吹噓他學生做的一個小程序時還這樣說榜配,哈哈
所以在當時的應用以MIS系統(tǒng)為主的情況下否纬,RAD工具快速興起了。PowerBuilder蛋褥、Delphi临燃、VB這些工具拿鼠標點點放放就能湊出個像樣的界面,弄個CURD功能不需要寫多少代碼烙心。所以那時VC和Delphi的程序經(jīng)衬だ龋互相鄙視。
自古以來就文人相輕淫茵,一直到現(xiàn)在爪瓜,在程序設計領域也存在錯綜復雜的鄙視鏈,當然那時我是VC黨匙瘪。
記得當時有兩個比較完備的控件庫铆铆,一個忘了名字,一個就是BCG ControlBar丹喻。下面引自百度百科
BCGControlBar(Business Components Gallery ControlBa[1] r)專業(yè)版是MFC的一個擴展庫薄货,您可以用來構建類似于Microsoft? Office 2000/XP/2003/2007/2010/2013、Microsoft Visual Studio(打印碍论、用戶定制工具欄谅猾、菜單等)和其他一些知名產(chǎn)品的高級用戶界面,例如:日歷、網(wǎng)格税娜、編輯和甘特圖等坐搔。
BCGControlBar的這個擴展庫包含了300多個經(jīng)過精心設計,測試和具有完備文檔的MFC擴展類敬矩。BCGControlBar控件能輕松的融入應用程序中概行,節(jié)約大量的的開發(fā)和調試時間。
好像從VS2008起谤绳,微軟就把BCG融到MFC中了,但不知為什么BCG還在發(fā)展袒哥?
VS的應用程序向導現(xiàn)在都支持BCG效果了缩筛,但例子不太好找,只好下了個xx版的BCGControlBar Pro25.10堡称。主要是為了借用它其中的Grid控件和工具條設計工具以及DockControlBar的一些功能瞎抛。
界面/功能安排
這個程序的主要功能包含三部分:表格方式編輯數(shù)據(jù),圖形方式編輯數(shù)據(jù)却紧,算法運行演示桐臊。
編輯數(shù)據(jù)時可以選擇用表格方式或圖形方式,各用一個View來實現(xiàn)晓殊。但這兩種方式如何安排好呢断凶?是并排顯示還是相互遮蓋用個命令來相互切換好呢?考慮到每種顯示方式下還有較多的操作巫俺,并排的話比較亂认烁,而且數(shù)據(jù)同步的問題比較麻煩,所以就決定采用遮蓋切換的方式介汹。
算法運行演示和數(shù)據(jù)編輯功能應該隔離開却嗡,運行演示時最好不要修改數(shù)據(jù)。所以把算法運行演示功能放到彈出的模態(tài)對話框中實現(xiàn)嘹承,演示結束關閉對話框回到編輯功能窗价。
單文檔還是多文檔
采取單文檔還是多文檔結構對文檔的數(shù)據(jù)操作部分影響不大,但是對View的管理則區(qū)別較大叹卷。單文檔結構下所有的View共享同一個主框架窗口撼港,切換時主要是設置新的View的ID為AFX_IDW_PANE_FIRST然后隱藏舊的顯示新的。
但是做到一半時骤竹,發(fā)現(xiàn)在圖形編輯界面時餐胀,由于采取在切分窗口里顯示刻度標尺,View也位于某個切分窗口欄下瘤载,這樣窗口層次變成:主窗口->切分窗口->View否灾,和表格編輯界面的:主窗口->View明顯不同。解決方案之一就是把表格編輯View也放到切分窗口下鸣奔,當切換到它時再把標尺窗口隱藏墨技。試了試惩阶,發(fā)現(xiàn)窗口邊緣明顯有個小條條存在,不太美觀扣汪,于是就放棄了断楷,推倒,用多文檔結構重搞崭别。
多文檔結構下每個View都處于單獨的子框架窗口下冬筒,這樣切換View變成了切換子框架窗口。帶來的好處是各個子框架窗口完全自己定制茅主,不會相互影響了舞痰。但這時候要注意要讓每個子框架妥貼的處理各個MDI消息,否則子窗口飄起來了就蓋不住另外的窗口了诀姚。另外由于MFC處理MDI機制問題响牛,在MDI標題欄的文檔名字后顯示窗口編號123等等的,看起來很別扭赫段,也要在OnUpdateFrameTitle中處理掉呀打。
小結
把上面這些問題明確后,就把程序的大致框架確定了下來糯笙。
接下來幾天要回媳婦老家參加侄女婚禮贬丛,等回來了接著寫
原來在PLA時不讓寫博客之類的東西,現(xiàn)在自由了给涕,能寫就多寫點兒
寫這些東西也沒啥用瘫寝,主要最近有點兒失業(yè)焦慮癥,寫點兒東西找點兒事兒做稠炬,哈哈