先看一下效果圖..
進度條的進度是創建一個新的線程控制,當單擊"開始"按鈕時,就創建一個線程,在這個線程中控制進度條的進度,這樣就可以對窗口進行其他
操作,要是沒有創建一個新的線程控制進度,則整個程序需要等待進度條執行完後才能進行其他操作....
對於進度條控件關聯了一個控件變量m_speed
CProgressCtrl m_speed;
DDX_Control(pDX, IDC_PROGRESS1, m_speed);
在頭文件中
聲明線程函數
static DWORD WINAPI ThreadSpeed(LPVOID lpParameter);
這裏需要注意我爲什麼將線程函數聲明爲靜態函數,後面我會講解
聲明這個句柄是用於接受創建線程時返回的句柄,可以使用這個句柄對線程控制,如掛起,喚醒以及終止等等操作
HANDLE m_ThreadSpeed;
聲明的按鈕函數,雙擊按鈕由編譯器自動生成的
afx_msg void OnBnClickedButton2(); //"開始"按鈕函數
afx_msg void OnBnClickedButton1(); //"掛起"按鈕函數
afx_msg void OnBnClickedButton3(); //"喚醒"按鈕函數
afx_msg void OnBnClickedButton4(); //"終止"按鈕函數
在cpp文件中
線程函數的實現
- DWORD WINAPI CSpeedDlg::ThreadSpeed(LPVOID lpParameter)
- {
- CProgressCtrl *Speed = (CProgressCtrl*)lpParameter;
- Speed->SetRange(0,100000); //設置進度條的範圍
- for (int i = 0; i < 100000; i++)
- {
- Speed->SetPos(i); //進度條的位置
- }
- return 0;
- }
"開始"按鈕函數的實現
- void CSpeedDlg::OnBnClickedButton2()
- { // TODO: 在此添加控件通知處理程序代碼
- m_ThreadSpeed = CreateThread(0,0,ThreadSpeed,&m_speed,0,0); //創建線程
- }
線程掛起時進度條停止前進,當線程喚醒時進度條繼續前進,當線程終止時,進度條永遠不會在前進,除非再次單擊"開始"按鈕創建新線程進度條從新開始
- //掛起線程函數
- void CSpeedDlg::OnBnClickedButton1()
- {
- // TODO: 在此添加控件通知處理程序代碼
- SuspendThread(m_ThreadSpeed); //掛起線程函數,參數爲線程句柄
- }
- //喚醒線程函數
- void CSpeedDlg::OnBnClickedButton3()
- {
- // TODO: 在此添加控件通知處理程序代碼
- ResumeThread(m_ThreadSpeed); //喚醒掛起的線程
- }
- //終止線程函數
- void CSpeedDlg::OnBnClickedButton4()
- {
- // TODO: 在此添加控件通知處理程序代碼
- TerminateThread(m_ThreadSpeed,0); //終止線程
- SendMessage(WM_CLOSE); //發送WM_CLOSE消息關閉窗口,退出程序
- }
這裏我來談談爲什麼線程函數聲明時爲什麼要定義成靜態,如果不是靜態函數則在CreateThread()函數中引用線程函數
出錯,看圖片
因爲我定義的線程函數在類裏,如果不是靜態函數,調用時需要定義一個對象,有對象調用該函數,而我這裏定義爲靜態函數使得這個函數
不屬於任何對象,可以直接調用,就可以解決上面圖片裏出的問題,如果線程函數定義爲一個全局變量,也就是在類的外面定義,則不需要這樣
定義爲靜態函數,
因爲我這裏把線程函數定義爲了靜態變量,而m_spend不是靜態變量,它是進度控件的控件變量,定義爲CProgressCtrl類的對象,我不知怎麼
來把它定義爲靜態的,如果直接static CProgressCtrl m_speed,這樣的話會出錯,這樣m_speed不能在線程函數中使用,出現的錯誤是
所以我的解決辦法是讓m_speed作爲參數傳給線程函數,然後在線程函數中定義一個CProgressCtrl類的指針類型對象來接受m_speed,
不過這裏要記得類型的強制轉換,修改後正如上面線程函數實現代碼一樣