[发布] 多选控件和时钟控件
關(guān)鍵字:自定義控件(Custom Control),C++,WIN32 SDK
本文發(fā)布的是我在工作中開發(fā)的自定義控件。第一個(gè)是多選控件,該控件主要啟發(fā)來自于 ExplorerBar,即資源管理器左側(cè)的 DirectDraw 部分,例如打開文件夾,位于左側(cè)的那個(gè)可以擴(kuò)展收縮的多面板組成的“文件夾任務(wù)”等。本控件的開發(fā)需求主要是用于在很多個(gè)Items中進(jìn)行快速方便的選擇和定位,因此我稱它為多選控件。從外觀上來看,它是由一些列面板從上到下的方式排列而成(我們把一個(gè)Group稱為控件的一個(gè)Child,即第一層子結(jié)點(diǎn)的LineSize = 1),它和 Outlook 側(cè)邊欄的主要區(qū)別是,outlook側(cè)欄是多個(gè)面板共享一個(gè)公用的較大客戶區(qū),即同一時(shí)刻通常僅可見一個(gè)面板(這一點(diǎn)類似TabControl),顯然這個(gè)特征有時(shí)是我們需要的,但有時(shí)是我們不希望的。即 ExploerBar 和本控件則是多個(gè)面板同時(shí)可見的。比如說,TabPage上通常是按照功能分組歸類到多個(gè)頁面,這些頁面彼此之間獨(dú)立性較強(qiáng),互相不依賴,因此在同一時(shí)刻只見到一個(gè)頁面是比較符合用戶意愿的。而我們要做的多選空間,他們都是本質(zhì)上相同的,因此我希望隨意組合式的多頁面展示,這樣可以給我們一個(gè)靈活又廣闊的全局和局部視角組合,這種特點(diǎn)就是ExploreBar的特點(diǎn)。
因此總結(jié)下這個(gè)控件的誕生需求:是我們需要多選,多個(gè)面板保證靈活和快速定位的需求,即我們需要對(duì)Items進(jìn)行一些分類并放入面板,可以任何折疊。使得提供靈活的視圖。面板內(nèi)部,由于Items的特征小而多,因此采用類似ListView的圖標(biāo)視圖的做法,將他們從左到右進(jìn)行布局。這樣就可以比 TreeView 節(jié)省垂直方向的空間(因?yàn)門reeview每個(gè)節(jié)點(diǎn)都要占據(jù)一行),在這個(gè)控件里主要是各個(gè)元素之間都有邊框,元素之間的間隔,邊距等元素,這些元素顯然會(huì)浪費(fèi)一些空間。
本控件的組織架構(gòu)是有頂層的代表窗口的一個(gè)類來管理的,下設(shè)Group集合。每個(gè)Group下面含有Items。每個(gè)Item為最基本單位,類似一個(gè)CheckBox。每個(gè) Group 由Header和“客戶區(qū)”組成。點(diǎn)擊Header可以對(duì)其展開和折疊,同時(shí)左側(cè)的按鈕采用的是七幀圖片得到旋轉(zhuǎn)動(dòng)畫。截圖如下所示:
另一個(gè)控件是時(shí)鐘控件,該控件模仿的是 windows mobile 系統(tǒng)上的鬧鐘設(shè)置控件。主要用于設(shè)置時(shí)刻(例如鬧鐘),里面內(nèi)置兩個(gè)屬性,Hour 和 minute,沒有日期。因此這是它和 DateTimePicker 的主要區(qū)別。用戶可以用鼠標(biāo)拖動(dòng)分針和時(shí)針,進(jìn)行時(shí)刻的設(shè)置。時(shí)鐘控件由于主要時(shí)為用戶設(shè)置時(shí)間而提供,因此繪制上追求的原則是高效和對(duì)時(shí)間清楚的示意性,而不在于界面的美觀和華麗,因此它在外觀上顯得“樸素”。控件內(nèi)默認(rèn)的分針拖動(dòng)單位是5分鐘(也可以設(shè)置為最小的 1 分鐘分辨率,則拖動(dòng)時(shí)的運(yùn)動(dòng)會(huì)更加平穩(wěn)),指針捕捉誤差緩沖為 3 分鐘左右。
此兩個(gè)控件都采用了內(nèi)存繪制技術(shù)用于防止閃爍。
由于開發(fā)的比較緊急,因此尤其多選控件還缺乏足夠的測(cè)試,可能有些接口方法還需要進(jìn)一步改進(jìn),一些接口也有待于增加。具體用法由于精力所限,我就不在這里用代碼做示范了,可以參考 Demo 項(xiàng)目的代碼。在發(fā)行文件夾里有一個(gè)MulSelCtl.h 頭文件,模仿windows sdk的做法我已經(jīng)定義了一些對(duì)應(yīng)的宏。因?yàn)闀r(shí)間原因,我還沒有寫出具體的說明文檔。
最后增加一些技術(shù)總結(jié):
(1)讀寫文本文件時(shí),應(yīng)該盡量避免使用unicode版本的函數(shù)(fgetws等),因?yàn)樽x寫中文時(shí)可能亂碼。因此本控件中先把 unicode 轉(zhuǎn)換到ansi 再和文件進(jìn)行交互。
(2)寫文本文件時(shí),應(yīng)該把“\r\n"轉(zhuǎn)換成單個(gè)”\n“,否則寫入文本文件時(shí),由于底層函數(shù)自作主張的翻譯,會(huì)把\r\n寫成\r\r\n。在文本框文本和文件之間交換數(shù)據(jù)時(shí),這一點(diǎn)尤其需要注意。
(3)自定義控件要寫成DLL被其他進(jìn)程加載和使用,則ClassStyle中需要添加CS_GLOBAL樣式,否則其他進(jìn)程無法創(chuàng)建其實(shí)例。
(4)自定義控件由于可能被創(chuàng)建出多個(gè)實(shí)例,因此其窗口過程不能使用 Static 變量持有和窗口實(shí)例相關(guān)的內(nèi)部數(shù)據(jù)(狀態(tài))。這一點(diǎn)和我們寫普通窗口(主窗口,模態(tài)對(duì)話框)過程時(shí)不同,因?yàn)樗鼈兺ǔr(shí)進(jìn)程范圍內(nèi)唯一的,因此可以使用 Static 變量持有窗口數(shù)據(jù),這一點(diǎn)尤其要注意。正確做法時(shí)在注冊(cè)窗口類時(shí),告知系統(tǒng)為每個(gè)窗口保留其窗口數(shù)據(jù)額外空間的大小,在 WM_NCCREATE 時(shí)分配和填寫數(shù)據(jù)。
Demo項(xiàng)目和控件發(fā)行包(*.h, *.lib, *.dll)的下載連接如下:
http://files.cnblogs.com/hoodlum1980/MulSelCtl_BIN.zip
?
【更新】
[1]. 修復(fù)多選控件中的一個(gè)BUG,點(diǎn)擊 GroupHeader 上的 CheckBox 時(shí),由于沒有更新內(nèi)部狀態(tài)。會(huì)造成后續(xù)點(diǎn)擊時(shí),CheckBox 狀態(tài)錯(cuò)誤。2013-5-5;
[2]. DEMO項(xiàng)目對(duì)話框上,新增時(shí)鐘控件的拖動(dòng)單位設(shè)置(1或5分鐘)。2013-5-5。
總結(jié)
以上是生活随笔為你收集整理的[发布] 多选控件和时钟控件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 领导,你可以做得更好
- 下一篇: android 中ImageView的s