Windows消息和事件的区别 VC++解惑
?? ??事件就是“當(dāng)....的時候”,事件總是和一個ID有關(guān) ? ?
??? ?消息就是“嗨!你該干....了”?,VS2005以上的“消息”標(biāo)簽中就是VC6 Windows Messages Handler中的內(nèi)容
???? 我們一般都是在 "當(dāng)...的時候" 干 XXX0 或者 XXX1 XXX2 .... 也可以 “這件事情我不想理會”(讓W(xué)indows去干)。 我們也可能在正干XXXn中突然想起: “嗨!我該晚餐了!” 再附上不經(jīng)典的描述:事件是一個動作——用戶觸發(fā)的動作。 消息是一個信息——傳遞給系統(tǒng)的信息。?事件與消息的概念在計算機中較易混淆,但本質(zhì)不同: 事件由用戶(操作電腦的人)觸發(fā)且只能由用戶觸發(fā),操作系統(tǒng)能夠感覺到由用戶觸發(fā)的事件,并將此事件轉(zhuǎn)換為一個(特定的)消息發(fā)送到程序的消息隊列中。 這里強調(diào)的是: 可以說“用戶觸發(fā)了一個事件”,而不能說“用戶觸發(fā)了一個消息”。 用戶只能觸發(fā)事件,而事件只能由用戶觸發(fā)。 一個事件產(chǎn)生后,將被操作系統(tǒng)轉(zhuǎn)換為一個消息,所以一個消息可能是由一個事件轉(zhuǎn)換而來(或者由操作系統(tǒng)產(chǎn)生)。 一個消息可能會產(chǎn)生另一個消息,但一個消息決不能產(chǎn)生一個事件——時間只能由用戶觸發(fā)。 ?
?? ? 總結(jié)(事件,消息的來源):
??? 事件:只能由用戶通過外設(shè)的輸入產(chǎn)生。
??? 消息:(產(chǎn)生消息的來源有三個) (1) 由操作系統(tǒng)產(chǎn)生。 (2) 由用戶觸發(fā)的事件轉(zhuǎn)換而來。 (3) 由另一個消息產(chǎn)生。
(一) 利用用戶定義的消息通信
?????? 在Windows程序設(shè)計中,應(yīng)用程序的每一個線程都擁有自己的消息隊列,甚至工作線程也不例外,這樣一來,就使得線程之間利用消息來傳遞信息就變的非常簡單。首先用戶要定義一個用戶消息,如下所示:
#define WM_USERMSG WMUSER+100;在需要的時候,在一個線程中調(diào)用::PostMessage((HWND)param,WM_USERMSG,0,0)或CwinThread::PostThradMessage()來向另外一個線程發(fā)送這個消息,上述函數(shù)的四個參數(shù)分別是消息將要發(fā)送到的目的窗口的句柄、要發(fā)送的消息標(biāo)志符、消息的參數(shù)WPARAM和LPARAM。
?????? 下面的代碼的結(jié)果是在線程結(jié)束時顯示一個對話框,提示線程結(jié)束:
UINT ThreadFunction(LPVOID pParam)
{
while(!bend)
{
Beep(100,100);
Sleep(1000);
}
::PostMessage(hWnd,WM_USERMSG,0,0);
return 0;
}
WM_USERMSG消息的響應(yīng)函數(shù)為OnThreadended(WPARAM wParam,LPARAM lParam)
LONG CTestView::OnThreadended(WPARAM wParam,LPARAM lParam)
{ AfxMessageBox("Thread ended."); Retrun 0;}
??? 上面的例子是工作者線程向用戶界面線程發(fā)送消息,對于工作者線程,如果它的設(shè)計模式也是消息驅(qū)動的,那么調(diào)用者可以向它發(fā)送初始化、退出、執(zhí)行某種特定的處理等消息,讓它在后臺完成。在控制函數(shù)中可以直接使用::GetMessage()這個SDK函數(shù)進行消息分檢和處理,自己實現(xiàn)一個消息循環(huán)。GetMessage()函數(shù)在判斷該線程的消息隊列為空時,線程將系統(tǒng)分配給它的時間片讓給其它線程,不無效的占用CPU的時間,如果消息隊列不為空,就獲取這個消息,判斷這個消息的內(nèi)容并進行相應(yīng)的處理。
(二)用事件對象實現(xiàn)通信
在線程之間傳遞信號進行通信比較復(fù)雜的方法是使用事件對象,用MFC的Cevent類的對象來表示。事件對象處于兩種狀態(tài)之一:有信號和無信號,線程可以監(jiān)視處于有信號狀態(tài)的事件,以便在適當(dāng)?shù)臅r候執(zhí)行對事件的操作。上述例子代碼修改如下:
Cevent threadStart ,threadEnd;
UINT ThreadFunction(LPVOID pParam)
{
::WaitForSingleObject(threadStart.m_hObject,INFINITE);
AfxMessageBox("Thread start.");
while(!bend)
{
????? Beep(100,100);
Sleep(1000);
Int result=::WaitforSingleObject(threadEnd.m_hObject,0); //等待threadEnd事件有信號,無信號時線程在這里懸停
????? If(result==Wait_OBJECT_0)
??? Bend=TRUE;
}
::PostMessage(hWnd,WM_USERMSG,0,0);
return 0;
}
///
/Void CtestView::OninitialUpdate()
{ hWnd=GetSafeHwnd();
threadStart.SetEvent();//threadStart事件有信號
pThread=AfxBeginThread(ThreadFunction,hWnd);//啟動線程
pThread->m_bAutoDelete=FALSE;
Cview::OnInitialUpdate);
}
Void CtestView::OnDestroy()
{ threadEnd.SetEvent();
WaitForSingleObject(pThread->m_hThread,INFINITE);
d elete pThread;
Cview::OnDestroy();
}
總結(jié)
以上是生活随笔為你收集整理的Windows消息和事件的区别 VC++解惑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php打印错误日志到本地,nginx+p
- 下一篇: arguments 类数组