久久―日本道色综合久久,亚洲欧美精品在线,狼狼色丁香久久婷婷综合五月,香蕉人人超,日本网站黄,国产在线观看不卡免费高清,无遮挡的毛片免费

2025年度未來(lái)銀行科技服務(wù)商TOP100
全世界各行各業(yè)聯(lián)合起來(lái),internet一定要實(shí)現(xiàn)!

VC在狀態(tài)欄中實(shí)現(xiàn)進(jìn)度指示器控制

2004-02-23 eNet&Ciweek

源碼

  盡管MFC提供了標(biāo)準(zhǔn)的進(jìn)度指示器控件(progress control),但是不能在狀態(tài)欄里直接使用這個(gè)控件,因此我創(chuàng)建了自己的可重用C++類(lèi)來(lái)實(shí)現(xiàn)進(jìn)度指示。這個(gè)類(lèi)從CStatusBar派生。整個(gè)實(shí)現(xiàn)過(guò)程不是很難,思路是在狀態(tài)欄創(chuàng)建一個(gè)進(jìn)度指示器控制,把它作為子窗口來(lái)對(duì)待,然后根據(jù)不同的狀態(tài)來(lái)顯示或者隱藏進(jìn)度指示器。本文提供了一個(gè)范例程序pgrsbar,這個(gè)程序的框架使用了MFC的文檔/視圖結(jié)構(gòu),在編輯視圖里顯示文本文件。打開(kāi)文件的時(shí)候,pgrsbar仿真長(zhǎng)時(shí)間的加載過(guò)程并在狀態(tài)欄里顯示進(jìn)度指示,如圖一所示。我將這個(gè)含有進(jìn)度指示器的狀態(tài)欄封裝在了一個(gè)CStatusBar派生的類(lèi)中——CProgStatusBar。



下面是這個(gè)類(lèi)的詳細(xì)說(shuō)明和使用方法:
CProgStatusBar是從標(biāo)準(zhǔn)的MFC類(lèi)CStatusBar派生而來(lái)。我在CProgStatusBar派生類(lèi)中加了一個(gè)CProgressCtrl類(lèi)型的數(shù)據(jù)成員——m_wndProgBar,并且實(shí)現(xiàn)了三個(gè)重要的成員函數(shù)或方法:OnCreate、OnSize和OnProgress。下面是這三個(gè)函數(shù)的詳細(xì)說(shuō)明:

OnCreate負(fù)責(zé)在狀態(tài)欄第一次被創(chuàng)建時(shí)接收控制,繼而創(chuàng)建進(jìn)度指示器并將它初始化為一個(gè)子窗口,

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在狀態(tài)欄的式樣中加了一個(gè)WS_CLIPCHILDREN,它告訴Windows不要繪制子窗口以下的狀態(tài)欄區(qū)域,這樣可以減少屏幕閃爍。接著OnCreate創(chuàng)建進(jìn)度指示器控制并將它的范圍設(shè)置成[0,100]。注意在這里創(chuàng)建進(jìn)度指示器控制時(shí)沒(méi)有用WS_VISIBLE,因?yàn)槲蚁朐诔绦蜷_(kāi)始的時(shí)候隱藏它。

無(wú)論何時(shí),只要你在某個(gè)窗口里添加子窗口,那么一定要負(fù)責(zé)管理它的大小尺寸,也就是說(shuō),當(dāng)父窗口大小改變后,子窗口的大小也要跟著作相應(yīng)的改變。一般來(lái)說(shuō),這個(gè)工作在父窗口的WM_SIZE/OnSize處理例程中完成: // 狀態(tài)欄大小改變以后,子窗口的尺寸跟著變
void CProgStatusBar::OnSize(...)
{
CStatusBar::OnSize(...);
CRect rc;
GetItemRect(0, rc);
m_wndProgBar.MoveWindow(rc,FALSE);
}
CProgStatusBar::OnSize 負(fù)責(zé)移動(dòng)進(jìn)度指示器到你期望的位置:例子程序是把它放在了狀態(tài)欄的第一個(gè)窗格,這個(gè)窗格通常用來(lái)顯示程序的“就緒”信息和命令提示信息。注意這里不論進(jìn)度指示器時(shí)處于可見(jiàn)狀態(tài)還是隱藏狀態(tài),MoveWindow都照樣起作用——所以即便是進(jìn)度指示器處于隱藏狀態(tài),其窗口大小同樣是可調(diào)的。
說(shuō)完窗口大小的調(diào)整,下面我們來(lái)看看進(jìn)度指示器的顯示,進(jìn)度指示器狀態(tài)的顯示在CProgStatusBar::OnProgress中完成。它有一個(gè)類(lèi)型為UINT的入口參數(shù):參數(shù)值的范圍從0到100,表示進(jìn)度百分比,0表示進(jìn)度沒(méi)開(kāi)始,100表示全部完成。如果這個(gè)參數(shù)的值大于0,則OnProgress顯示進(jìn)度控制并設(shè)置指示器的位置;如果參數(shù)值等于0,則 OnProgress隱藏進(jìn)度控制。

雖然我們常常都把子窗口控制放在父窗口能繪制的區(qū)域的最上面,但這樣做在繪制方面是有一定風(fēng)險(xiǎn)的。在你隱藏/顯示進(jìn)度控制時(shí)尤其如此,你會(huì)發(fā)現(xiàn)有兩個(gè)問(wèn)題:第一,因?yàn)檫M(jìn)度指示器顯示在狀態(tài)欄的第一個(gè)窗格位置,所以如果指示器顯示時(shí)已經(jīng)顯示有狀態(tài)信息,那么進(jìn)度指示器和狀態(tài)信息文本就會(huì)有沖突,相互干擾。如圖二所示。之所以會(huì)這樣,是因?yàn)檫M(jìn)度控制假設(shè)其繪制背景是干凈的,并且只繪制進(jìn)度控制的著色部分。解決這個(gè)問(wèn)題最簡(jiǎn)單的方法是調(diào)用CStatusBar::SetWindowText(NULL)函數(shù)在顯示進(jìn)度指示器之前打掃一下環(huán)境衛(wèi)生,清除以前的文本。對(duì)于狀態(tài)欄來(lái)說(shuō),SetWindowText函數(shù)的作用是設(shè)置狀態(tài)欄第一個(gè)窗格的文本。


反之,當(dāng)調(diào)用OnProgress(0)清除進(jìn)度控制時(shí)也存在類(lèi)似的問(wèn)題,CProgStatusBar::OnProgress 隱藏進(jìn)度控制后,狀態(tài)欄第一個(gè)窗格該顯示什么信息呢?一般顯示“就緒”或其它的提示信息。當(dāng)應(yīng)用程序不做任何事情時(shí),MFC程序總是在這個(gè)位置顯示資源串AFX_IDS_IDLEMESSAGE表示的文本,其缺省值為“就緒”,但你可以在RC文件中任意修改這個(gè)值。以我個(gè)人的觀點(diǎn),我總是認(rèn)為在這里顯示就緒信息有點(diǎn)兒土。不管怎樣,在MFC程序的狀態(tài)欄中顯示就緒信息很容易: // 在 CProgStatusBar::OnProgress函數(shù)中
// WM_SETMESSAGESTRING 的定義在文件
GetParent()->PostMessage(WM_SETMESSAGESTRING,AFX_IDS_IDLEMESSAGE);
如果你愿意,完全可以創(chuàng)建不同的ID和消息,如用ID_DONE_LOADING表示“加載完成”,以此取代“就緒”。
CProgStatusBar實(shí)現(xiàn)了含有進(jìn)度控制的狀態(tài)欄。它的使用方法很簡(jiǎn)單:用CProgStatusBar代替CStatusBar聲明實(shí)例,然后在任何想要顯示進(jìn)度控制指示的地方調(diào)用CProgStatusBar::OnProgress。詳細(xì)代碼請(qǐng)參考本文例子程序。創(chuàng)建CProgStatusBar很容易,它的原理與標(biāo)準(zhǔn)的狀態(tài)欄CStatusBar一樣——你只要明白什么時(shí)候以及在哪里調(diào)用OnProgress即可。
實(shí)際應(yīng)用中要根據(jù)你的應(yīng)用而定。我建議你按照例子程序的方法來(lái)使用它。不要直接暴露CProgStatusBar::OnProgress函數(shù),例子程序的主窗口實(shí)現(xiàn)了一個(gè)特殊的消息——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;
}
這樣想要報(bào)告進(jìn)度指示的任何對(duì)象都可以通過(guò)發(fā)送一個(gè)消息到主框架來(lái)代替直接對(duì)狀態(tài)欄進(jìn)行調(diào)用。例如,在例子程序中,文檔的Serialize函數(shù)利用Sleep函數(shù)仿真耗時(shí)加載,每隔150毫秒報(bào)告一次進(jìn)度狀態(tài)。通常,你肯定想讓文檔這樣的低級(jí)對(duì)象盡可能少地包含UI代碼。雖然在實(shí)踐中很少有程序員遵守這一原則,但最好不用UI操作你的文檔類(lèi),因?yàn)槟愫芸赡苡幸惶煜朐谀硞€(gè)服務(wù)中或命令行程序中使用它。不管怎么說(shuō),發(fā)送消息到框架總比暴露框架的內(nèi)部成員要好得多。為了安全起見(jiàn),文檔的Serialize函數(shù)在發(fā)送消息前最好檢查一下框架是否存在。如果你不想從文檔發(fā)送Windows消息,可以用MFC的視圖更新機(jī)制來(lái)做。你可以發(fā)明一個(gè)“暗示”代碼以及一個(gè)小結(jié)構(gòu)來(lái)保存進(jìn)度百分比數(shù)據(jù),并通過(guò)向框架發(fā)送MYWM_PROGRESS消息調(diào)用暗示信息。這是從文檔到視圖/框架傳遞進(jìn)度控制信息的最省事的方式。
CProgStatusBar假設(shè)你報(bào)告的進(jìn)度指示數(shù)據(jù)總是0到100的整數(shù),并且假設(shè)你中途可以中斷進(jìn)度指示器。以便你在想要改變?cè)O(shè)置的時(shí)候,可以修改CProgStatusBar或者調(diào)用CProgStatusBar::GetProgressCtrl來(lái)直接存取進(jìn)度控制狀態(tài)。


相關(guān)頻道: eNews

您對(duì)本文或本站有任何意見(jiàn),請(qǐng)?jiān)谙路教峤?,謝謝!

投稿信箱:tougao@enet16.com