2002-07-15· ·資訊產業部電子第二十二研究所青島分所 郎銳··yesky
引言
如果能在自己的程式中也具備動態更換**的能力,將使軟體平添幾分亮點從而更易博得使用者的青睞。具筆者了解,當前介紹這種技術的文章資料較少,與其流行程度很不協調,而且現有的少量資料也多是針對對話方塊進行的,無非是在對話方塊上覆蓋一層,並通過更換來實現程式的動態換膚。雖然這也是動態換膚的一種,但由於技術過於簡單,本文將著重介紹另外一種動態換膚技術--工具欄的動態換膚技術,這也是ie瀏覽器等軟體所普遍採用的一種換膚技術。
程式支援動態換膚
由於換膚功能是對程式框架的擴充套件,所以相關處理**理所當然地要在主框架類中進行。為了使程式能具備換膚的能力,必須首先使程式具備換膚的基本條件。首先可以明確的是:處理物件為普通的工具條,其基類為c*******。通過msdn幫助可以了解到該類及其"近親"的繼承關係如圖所示。通過對這幾個相關類的查閱,可以發現crebar模擬較特殊,它本身並不用於顯示,而主要用於包容其他的工具條,例如,可以通過其成員函式addbar()將工具條(*******)、對話條(dialogbar)等型別的工具條加入到復合條(rebar),使工具欄中可以顯示多個工具條。所以可以得出這樣的設計思路:程式框架的工具欄不再直接以工具條來實現,而是以復合條為基礎,並通過crebar的addbar()函式將原先的工具條加入其中。**則可以通過設定與crebar相關的rebarbandinfo結構而平鋪於復合條之上,由於有工具條覆於其上,因此必須在建立工具條時修改其風格(style),使其背景為透明,這樣才能透出位於下層的**。
由於在程式設計時使用了crebar,在普通程式中實現起來比較麻煩,可以在建立工程時在第四步選中"internet explorer rebars"選項,這樣建立的工具欄將在復合條上新增乙個工具條和乙個對話條。只需從主框架類的標頭檔案和實現檔案的oncreate()函式裡將對話條cdialogbar的例項物件m_wnddlgbar的宣告部分和部分相關**去除即可。
接下來在工具條建立時需要特別指定tbstyle_transparent等視窗風格來使其背景透明,並在建立完復合條後通過addbar()函式將背景透明的工具條新增其中:
m_wnd*******.createex(this,
tbstyle_flat|tbstyle_transparent,
ws_child|ws_visible|cbrs_align_top,
crect(0,0,0,0),afx_idw_*******)
……m_wndrebar.addbar(&m_wnd*******,
null,null,
rbbs_gripperalways|rbbs_fixedbmp|rbbs_break)
經過上述幾步處理對程式的主框架作了改造,使其基本具備了動態換膚的必要條件。
**的裝載與動態更換
**一般是以外部資源的形式發布,在使用時再由程式動態裝載。**載入到工具欄的過程大致可分兩步:先將**從檔案裝載到記憶體,然後再由記憶體位圖直接繪製到復合條上去。對於第一步,可用api函式loadimage將外部檔案back.bmp從檔案按位圖的格式裝載到記憶體,返回的控制代碼可通過強制轉換得到hbitmap型的點陣圖控制代碼m_bmpback:
m_bmpback=(hbitmap)loadimage(afxgetinstancehandle(), //應用程式例項控制代碼
"back.bmp",image_bitmap,0,0,
lr_loadfromfile|lr_createdibsection);
**裝載到記憶體後,需要通過對rebarbandinfo結構進行設定,才能實現**點陣圖在復合條中的平鋪,該結構有二十多個成員變數,但在此只是用於設定背景點陣圖的平鋪,因此只需設定fmask為rbbim_background以指定hbmback有效,並將前面裝載到記憶體的點陣圖控制代碼m_bmpback傳遞給該成員變數就完成了對**的裝載與顯示,下面就是這部分實現的詳細**:
crebarctrl& rc=m_wndrebar.getrebarctrl(); //獲取復合條控制項指標
rebarbandinfo info;
memset(&info,0,sizeof(rebarbandinfo)); //清零
info.cbsize=sizeof(info);
info.fmask=rbbim_background; //指定hbmback有效
//如果位圖控制代碼不可用則仍為銀灰色背景,否則以此位圖作為復合條的背景
info.hbmback=m_bmpback!=invalid_handle_value?m_bmpback:null;
rc.setbandinfo(0,&info); //進行設定
rc.updatewindow(); //更新視窗
當**已經顯示到工具欄上而對其進行動態更換,則只需要簡單的呼叫拷貝檔案函式將新的**外掛程式以覆蓋的形式複製到back.bmp,並再次呼叫上述兩步對新的**外掛程式進行重新裝載即可實現對程式的動態**更換。拷貝檔案函式一般用api函式copyfile()來實現,該函式的前兩個引數分別為原始檔路徑和目的檔案路徑。最後乙個布林型引數指定檔案拷貝的方式,在此需要指定為false,即如果目的檔案已存在則對其覆蓋,否則將無法實現對**的更換。
小結
本文通過對復合條及crebar類的使用實現了在vc下對應用程式的動態**更換。crebar類的功能非常豐富,本文限於篇幅未能做深入的介紹,關於該類的詳細情況請參閱微軟公司的msdn幫助。本文所述程式在windows 98下,由microsoft visual c++ 6.0編譯通過。
用VC編寫的SN快速輸入工具
用vc編寫的sn快速輸入工具 大家在安裝軟體時,一般都會遇到讓輸入序列號 sn的情況。序列號 sn 通常是由 分隔開的幾部分組成,相應地,安裝軟體輸入序列號的地方通常也是由幾個文字框 textbox 組成的,這時,為了輸入序列號,我們就要在安裝程式和記錄有 sn的檔案之間貼上 複製多次,非常麻煩。從...
自己用qt製作的乙個具有查詢功能的介面
工具 qt sqlserver2008 步驟 1.使用qt連線sqlserver資料庫,並插入一些資料 main.cpp 2.在myqtsql.h中新增我所需要的控制項 3.實現qt的介面,新增查詢功能,並實現模糊查詢。主要 myqtsql.h myqtsql.cpp main.cpp 介面如下 e...
用vc編寫任務管理器殺不掉的程序
記得自己上高中的時候,我們上微機課,那時候每個機子都有個監控程式,很麻煩,老師上課了機子就被鎖住了,什麼也做不了,很不爽,那時候大家都知道用任務管理器結束程序,但是偏偏這個程序結束不了,後來我找到了個方法,在cmd下執行ntsd c q p 程序id,這樣這個監控程式就會結束了。那時候只知道這個方法...