<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    weidagang2046的專欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評論 - 101, 引用 - 0
    數據加載中……

    如何在狀態欄中實現進度指示器控制

    ?? 我最近作了一個C++/MFC程序,這個程序有時要加載大容量文件,為了讓文件加載過程不至于太單調,我想在UI中用進度指示器顯示文件的加載過程,而且我想在程序的狀態欄中使用這個指示器控制。經過一番研究和嘗試,我實現了自己的想法。本文將詳細介紹整個實現過程。希望大家在解決類似的問題時少走一些彎路......
    ??? 盡管MFC提供了標準的進度指示器控件(progress control),但是不能在狀態欄里直接使用這個控件,因此我創建了自己的可重用C++類來實現進度指示。這個類從CStatusBar派生。整個實現過程不是很難,思路是在狀態欄創建一個進度指示器控制,把它作為子窗口來對待,然后根據不同的狀態來顯示或者隱藏進度指示器。本文提供了一個范例程序pgrsbar,這個程序的框架使用了MFC的文檔/視圖結構,在編輯視圖里顯示文本文件。打開文件的時候,pgrsbar仿真長時間的加載過程并在狀態欄里顯示進度指示,如圖一所示。我將這個含有進度指示器的狀態欄封裝在了一個CStatusBar派生的類中——CProgStatusBar。


    圖一 在狀態欄里顯示進度指示

    下面是這個類的詳細說明和使用方法:
    CProgStatusBar是從標準的MFC類CStatusBar派生而來。我在CProgStatusBar派生類中加了一個CProgressCtrl類型的數據成員——m_wndProgBar,并且實現了三個重要的成員函數或方法:OnCreate、OnSize和OnProgress。下面是這三個函數的詳細說明:

    OnCreate負責在狀態欄第一次被創建時接收控制,繼而創建進度指示器并將它初始化為一個子窗口,
    int CProgStatusBar::OnCreate(LPCREATESTRUCT lpcs)
    {
       lpcs->style |= WS_CLIPCHILDREN;
       VERIFY(CStatusBar::OnCreate(lpcs)==0);
       VERIFY(m_wndProgBar.Create(WS_CHILD, CRect(), this, 1));
       m_wndProgBar.SetRange(0,100);
       return 0;
    }      
    ??? OnCreate在狀態欄的式樣中加了一個WS_CLIPCHILDREN,它告訴Windows不要繪制子窗口以下的狀態欄區域,這樣可以減少屏幕閃爍。接著OnCreate創建進度指示器控制并將它的范圍設置成[0,100]。注意在這里創建進度指示器控制時沒有用WS_VISIBLE,因為我想在程序開始的時候隱藏它。
    ??? 無論何時,只要你在某個窗口里添加子窗口,那么一定要負責管理它的大小尺寸,也就是說,當父窗口大小改變后,子窗口的大小也要跟著作相應的改變。一般來說,這個工作在父窗口的WM_SIZE/OnSize處理例程中完成:?
    // 狀態欄大小改變以后,子窗口的尺寸跟著變
    void CProgStatusBar::OnSize(...)
    {
      CStatusBar::OnSize(...);
      CRect rc;
      GetItemRect(0, &rc);
      m_wndProgBar.MoveWindow(&rc,FALSE);
    }      
    ??? CProgStatusBar::OnSize 負責移動進度指示器到你期望的位置:例子程序是把它放在了狀態欄的第一個窗格,這個窗格通常用來顯示程序的“就緒”信息和命令提示信息。注意這里不論進度指示器時處于可見狀態還是隱藏狀態,MoveWindow都照樣起作用——所以即便是進度指示器處于隱藏狀態,其窗口大小同樣是可調的。
    ??? 說完窗口大小的調整,下面我們來看看進度指示器的顯示,進度指示器狀態的顯示在CProgStatusBar::OnProgress中完成。它有一個類型為UINT的入口參數:參數值的范圍從0到100,表示進度百分比,0表示進度沒開始,100表示全部完成。如果這個參數的值大于0,則OnProgress顯示進度控制并設置指示器的位置;如果參數值等于0,則 OnProgress隱藏進度控制。
    ??? 雖然我們常常都把子窗口控制放在父窗口能繪制的區域的最上面,但這樣做在繪制方面是有一定風險的。在你隱藏/顯示進度控制時尤其如此,你會發現有兩個問題:第一,因為進度指示器顯示在狀態欄的第一個窗格位置,所以如果指示器顯示時已經顯示有狀態信息,那么進度指示器和狀態信息文本就會有沖突,相互干擾。如圖二所示。之所以會這樣,是因為進度控制假設其繪制背景是干凈的,并且只繪制進度控制的著色部分。解決這個問題最簡單的方法是調用CStatusBar::SetWindowText(NULL)函數在顯示進度指示器之前打掃一下環境衛生,清除以前的文本。對于狀態欄來說,SetWindowText函數的作用是設置狀態欄第一個窗格的文本。


    圖二 繪制問題

    ??? 反之,當調用OnProgress(0)清除進度控制時也存在類似的問題,CProgStatusBar::OnProgress 隱藏進度控制后,狀態欄第一個窗格該顯示什么信息呢?一般顯示“就緒”或其它的提示信息。當應用程序不做任何事情時,MFC程序總是在這個位置顯示資源串AFX_IDS_IDLEMESSAGE表示的文本,其缺省值為“就緒”,但你可以在RC文件中任意修改這個值。以我個人的觀點,我總是認為在這里顯示就緒信息有點兒土。不管怎樣,在MFC程序的狀態欄中顯示就緒信息很容易:
    // 在 CProgStatusBar::OnProgress函數中
    // WM_SETMESSAGESTRING 的定義在<afxpriv.h>文件
    GetParent()->PostMessage(WM_SETMESSAGESTRING,AFX_IDS_IDLEMESSAGE);      
    ??? 如果你愿意,完全可以創建不同的ID和消息,如用ID_DONE_LOADING表示“加載完成”,以此取代“就緒”。
    ??? CProgStatusBar實現了含有進度控制的狀態欄。它的使用方法很簡單:用CProgStatusBar代替CStatusBar聲明實例,然后在任何想要顯示進度控制指示的地方調用CProgStatusBar::OnProgress。詳細代碼請參考本文例子程序。創建CProgStatusBar很容易,它的原理與標準的狀態欄CStatusBar一樣——你只要明白什么時候以及在哪里調用OnProgress即可。
    ??? 實際應用中要根據你的應用而定。我建議你按照例子程序的方法來使用它。不要直接暴露CProgStatusBar::OnProgress函數,例子程序的主窗口實現了一個特殊的消息——MYWM_PROGRESS,它將WPARAM傳遞到CProgStatusBar::OnProgress:
    // MYWM_PROGRESS  在resource.h文件中定義
    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    ON_MESSAGE(MYWM_PROGRESS,OnProgress)
    END_MESSAGE_MAP()
    
    // 處理MYWM_PROGRESS消息
    LRESULT CMainFrame::OnProgress(WPARAM wp, LPARAM lp)
    {
       m_wndStatusBar.OnProgress(wp);
       return 0;
    }      
    ??? 這樣想要報告進度指示的任何對象都可以通過發送一個消息到主框架來代替直接對狀態欄進行調用。例如,在例子程序中,文檔的Serialize函數利用Sleep函數仿真耗時加載,每隔150毫秒報告一次進度狀態。通常,你肯定想讓文檔這樣的低級對象盡可能少地包含UI代碼。雖然在實踐中很少有程序員遵守這一原則,但最好不用UI操作你的文檔類,因為你很可能有一天想在某個服務中或命令行程序中使用它。不管怎么說,發送消息到框架總比暴露框架的內部成員要好得多。為了安全起見,文檔的Serialize函數在發送消息前最好檢查一下框架是否存在。如果你不想從文檔發送Windows消息,可以用MFC的視圖更新機制來做。你可以發明一個“暗示”代碼以及一個小結構來保存進度百分比數據,并通過向框架發送MYWM_PROGRESS消息調用暗示信息。這是從文檔到視圖/框架傳遞進度控制信息的最省事的方式。
    ??? CProgStatusBar假設你報告的進度指示數據總是0到100的整數,并且假設你中途可以中斷進度指示器。以便你在想要改變設置的時候,可以修改CProgStatusBar或者調用CProgStatusBar::GetProgressCtrl來直接存取進度控制狀態。

    from: http://www.vckbase.com/document/viewdoc/?id=506

    posted on 2006-07-23 20:43 weidagang2046 閱讀(474) 評論(0)  編輯  收藏 所屬分類: Windows

    主站蜘蛛池模板: 亚洲综合无码精品一区二区三区| 大地资源免费更新在线播放 | 久久精品国产亚洲av麻| 精品无码国产污污污免费网站国产| 四虎免费久久影院| 一区二区三区免费在线观看| 亚洲精品无码久久久影院相关影片| 99爱在线精品视频免费观看9| 亚洲视频在线观看视频| 四虎影院在线免费播放| 免费又黄又爽又猛大片午夜| 亚洲人成网站在线观看播放| 亚洲网站在线免费观看| 色噜噜噜噜亚洲第一| 亚洲伊人色欲综合网| AV在线播放日韩亚洲欧| 亚洲精品免费在线视频| 日本在线看片免费人成视频1000 | 免费国产一级特黄久久| 午夜免费啪视频在线观看| 77777午夜亚洲| 亚洲国产精品综合久久网络| 午夜无码A级毛片免费视频| WWW免费视频在线观看播放| 国产美女视频免费观看的网站| 美女露100%胸无遮挡免费观看| 中文字幕亚洲色图| 亚洲综合一区二区精品导航| 国产女高清在线看免费观看| 热re99久久6国产精品免费| 国产麻豆一精品一AV一免费| 国产精品亚洲色图| 91午夜精品亚洲一区二区三区| 亚洲色图综合在线| 国产亚洲视频在线播放| 亚洲精品国精品久久99热一| 亚洲成AV人片一区二区| 亚洲阿v天堂在线2017免费| 亚洲国产综合精品一区在线播放| 91嫩草国产在线观看免费| 一个人免费视频在线观看www|