• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            笑看風云淡

            寵辱不驚,看庭前花開花落;去留無意,望天空云卷云舒
            posts - 96, comments - 48, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 ::  :: 聚合  :: 管理
            引言

              如果能在自己的程序中也具備動態更換皮膚的能力,將使軟件平添幾分亮點從而更易博得用戶的青睞。具筆者了解,當前介紹這種技術的文章資料較少,與其流行程度很不協調,而且現有的少量資料也多是針對對話框進行的,無非是在對話框上覆蓋一層圖片,并通過更換圖片來實現程序的動態換膚。雖然這也是動態換膚的一種,但由于技術過于簡單,本文將著重介紹另外一種動態換膚技術--工具欄的動態換膚技術,這也是IE瀏覽器等軟件所普遍采用的一種換膚技術。

              程序支持動態換膚

              由于換膚功能是對程序框架的擴展,所以相關處理代碼理所當然地要在主框架類中進行。為了使程序能具備換膚的能力,必須首先使程序具備換膚的基本條件。首先可以明確的是:處理對象為普通的工具條,其基類為CToolBar。通過MSDN幫助可以了解到該類及其"近親"的繼承關系如圖所示。通過對這幾個相關類的查閱,可以發現CReBar類比較特殊,它本身并不用于顯示,而主要用于包容其他的工具條,例如,可以通過其成員函數AddBar()將工具條(ToolBar)、對話條(DialogBar)等類型的工具條加入到復合條(ReBar),使工具欄中可以顯示多個工具條。所以可以得出這樣的設計思路:程序框架的工具欄不再直接以工具條來實現,而是以復合條為基礎,并通過CReBar的AddBar()函數將原先的工具條加入其中。皮膚則可以通過設置與CReBar相關的REBARBANDINFO結構而平鋪于復合條之上,由于有工具條覆于其上,因此必須在創建工具條時修改其風格(Style),使其背景為透明,這樣才能透出位于下層的皮膚。

              由于在程序設計時使用了CReBar,在普通程序中實現起來比較麻煩,可以在創建工程時在第四步選中"Internet Explorer ReBars"選項,這樣創建的工具欄將在復合條上添加一個工具條和一個對話條。只需從主框架類的頭文件和實現文件的OnCreate()函數里將對話條CDialogBar的實例對象m_wndDlgBar的聲明部分和部分相關代碼去除即可。

              接下來在工具條創建時需要特別指定TBSTYLE_TRANSPARENT等窗口風格來使其背景透明,并在創建完復合條后通過AddBar()函數將背景透明的工具條添加其中:

            m_wndToolBar.CreateEx(this,
            TBSTYLE_FLAT|TBSTYLE_TRANSPARENT,
            WS_CHILD|WS_VISIBLE|CBRS_ALIGN_TOP,
            CRect(0,0,0,0),AFX_IDW_TOOLBAR)
            ……
            m_wndReBar.AddBar(&m_wndToolBar,
            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編譯通過。

            久久AV高清无码| 久久人人爽人人爽人人片AV高清| 一本久久a久久精品vr综合| 亚洲色欲久久久综合网| 久久香综合精品久久伊人| 久久综合欧美成人| 欧美精品国产综合久久| 青青草国产精品久久| 久久亚洲AV无码精品色午夜| 72种姿势欧美久久久久大黄蕉| 国产成人久久777777| 国产aⅴ激情无码久久| 国内精品欧美久久精品| 久久久久人妻一区精品性色av| 狠狠精品久久久无码中文字幕 | 久久精品国产一区| 欧美激情精品久久久久久久九九九| 国产欧美久久久精品影院| 国产精品久久午夜夜伦鲁鲁| 亚洲v国产v天堂a无码久久| 久久夜色tv网站| 97久久精品无码一区二区| 97视频久久久| 一极黄色视频久久网站| 国产精品无码久久久久 | 国产精品一区二区久久国产| 中文成人无码精品久久久不卡 | 精品国产乱码久久久久软件| 亚洲嫩草影院久久精品| 久久久久女人精品毛片| 国产成人无码精品久久久性色| 久久一本综合| 亚洲国产成人久久笫一页| 久久国产成人精品国产成人亚洲| 嫩草影院久久国产精品| 精品免费久久久久久久| 久久久一本精品99久久精品88| 亚洲中文久久精品无码ww16 | 日本道色综合久久影院| 国产精品一久久香蕉国产线看观看| 亚洲综合精品香蕉久久网|