<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    VC++界面編程之--使用分層窗口實現界面皮膚

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    RFID設備管理軟件

    使用分層界面來實現界面皮膚的好處是:可以保證圖片邊緣處理不失真,且能用于異形窗口上,如一些不規則的窗口,你很難用SetWindowRgn來達到理想效果。

    在很多情況下,界面的漂亮與否,取決于PS的制作及創意,而界面編程所需要做的就是將圖片完整無缺的展示給用戶。


    分層窗口的好處就是:用一層窗口來描繪窗口背景,以確保背景圖片不會失真,而另一層窗口用來放置控件,除控件之外的區域全是透明的。為什么要這么麻煩呢?因為我們將要用到UpdateLayeredWindow來實現窗口背景描繪,一旦執行這個函數后,窗口的控件將會被覆蓋,不會再顯示。所以我們要再加一層透明窗口,來放置控件,以確保控件不會受到UpdateLayeredWindow的影響。

    這樣一來,窗口繪圖將不會影響到控件,并且可以達到窗口透明,控件不透明的效果。當然這個只是個別的窗口實現效果需求,這里不做重點討論。

    這里我用了兩個窗口類來完成此項工作,CThemedLayerWnd和CThemedAlphaWnd。CThemedLayerWnd負責截取正常窗口的創建消息,并在正常窗口創建之前,創建CThemedAlphaWnd;CThemedAlphaWnd主要負責窗口的描繪,也就是使用UpdateLayeredWindow來讓Windows自己描繪窗口皮膚。

    正常窗口只需要繼承模板類CThemedLayerWnd,并將CThemedLayerWnd加入到自己的窗口消息鏈中即可:

    [cpp] view plaincopy
    1. class CMainDlg :    public CThemedLayerWnd<CMainDlg>,  
    2.                     public CUpdateUI<CMainDlg>,  
    3.                     public CMessageFilter,  
    4.                     public CIdleHandler  
    5. {  
    6.     BEGIN_MSG_MAP(CMainDlg)  
    7.         CHAIN_MSG_MAP(CThemedLayerWnd<CMainDlg>)  
    8.         REFLECT_NOTIFICATIONS()  
    9.     END_MSG_MAP()  
    10. };  

    在正常窗口執行Create函數時,提前創建CThemedAlphaWnd,這樣一來,CThemedAlphaWnd就是CThemedLayerWnd的父窗口,CThemedLayerWnd理所當然成為子窗口,并自動將窗口位置置于CThemedAlphaWnd之上,這也正是我們想要的效果。

    [cpp] view plaincopy
    1. // Create normal dialog and alpha window.  
    2. HWND Create(const HWND wndParent, const int nImageID)  
    3. {  
    4.     // Create alpha window before normal dialog created.  
    5.     // Do not use WS_CHILD style, we need separated alpha window.  
    6.     m_wndAlpha = new CThemedAlphaWnd;  
    7.     m_wndAlpha->Create(wndParent, CRect(0, 0, 100, 100), NULL, WS_VISIBLE);  
    8.     ATLASSERT(m_wndAlpha->m_hWnd != NULL);  
    9.     SetBackgroundImage(nImageID);  
    10.   
    11.     // Create normal dialog.  
    12.     HWND hwnd = CDialogImpl<T>::Create(m_wndAlpha->m_hWnd);  
    13.   
    14.     // Pass normal window handle.  
    15.     m_wndAlpha->SetNormalWnd(m_hWnd);  
    16.   
    17.     // Set normal dialog style.  
    18.     UpdateWindowStyle();  
    19.     return hwnd;  
    20. }  

    這里還有個關鍵的問題,窗口上面是有控件的,如果控件要獲取父窗口的背景畫刷該怎么辦?而CThemedLayerWnd是透明的,你是沒辦法獲取到透明背景的。所以需要截取CThemedLayerWnd的WM_PAINT消息,當控件想要通過WM_PAINT來獲取窗口背景時,將窗口皮膚圖片傳遞給控件。

    [cpp] view plaincopy
    1. // Only for control get background image.  
    2. void DoPaint(CDCHandle dc)  
    3. {  
    4.     if (m_bmpBack.m_hBitmap != NULL)  
    5.     {  
    6.         HBITMAP hBmp = dc.SelectBitmap(m_bmpBack.m_hBitmap);  
    7.         ATLASSERT(hBmp != NULL);  
    8.     }  
    9. }  

    分層窗口帶來的不便之處就是:你對窗口的操作都是介于兩個窗口之間的,所以你需要在此上面多花費一些功夫,比如移動窗口,實際是移動兩個窗口。再比如正常窗口調用CenterWindow,實際是讓CThemedLayerWnd來移動窗口,你不得不重寫CenterWindow來先移動CThemedAlphaWnd然后再來移動CThemedLayerWnd。

    凡事皆有取舍,一切都根據實際需求做出取舍。正如分層窗口一樣,喪失了一些正常窗口的普通函數操作能力,但換來了界面皮膚的完美顯示。


    本文代碼免費下載鏈接:http://download.csdn.net/detail/renstarone/6361907

     

     

    from:http://blog.csdn.net/renstarone/article/details/12371309

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全