網站首頁 編程語言 正文
Qt和Windows消息通信機制
Qt
Qt是以事件驅動的UI工具集。 大家熟知Signals/Slots在多線程的實現也依賴于Qt的事件處理機制。
在Qt中,事件被封裝成一個個對象,所有的事件均繼承自抽象類QEvent.? 接下來依次談談Qt中有誰來產生、分發、接受和處理事件:
1、誰來產生事件: 最容易想到的是我們的輸入設備,比如鍵盤、鼠標產生的
keyPressEvent,keyReleaseEvent,mousePressEvent,mouseReleaseEvent事件(他們被封裝成QMouseEvent和QKeyEvent),這些事件來自于底層的操作系統,它們以異步的形式通知Qt事件處理系統,后文會仔細道來。當然Qt自己也會產生很多事件,比如QObject::startTimer()會觸發QTimerEvent. 用戶的程序可還以自己定制事件。
2、誰來接受和處理事件:答案是QObject。在Qt的內省機制剖析一文已經介紹QObject 類是整個Qt對象模型的心臟,事件處理機制是QObject三大職責(內存管理、內省(intropection)與事件處理制)之一。任何一個想要接受并處理事件的對象均須繼承自QObject,可以選擇重載QObject::event()函數或事件的處理權轉給父類。
3、誰來負責分發事件:對于non-GUI的Qt程序,是由QCoreApplication負責將QEvent分發給QObject的子類-Receiver. 對于Qt GUI程序,由QApplication來負責。
?Qt進入QApplication的event loop,經過層層委任,最終QEventloop的processEvent將通過與平臺相關的QAbstractEventDispatcher的子類QEventDispatcherWin32獲得用戶的用戶輸入事件,并將其打包成message后,通過標準Windows API ,把消息傳遞給了Windows OS,Windows OS得到通知后回調QtWndProc,
Windows
https://www.jianshu.com/p/5fd5bdaac69c---MFC消息機制
Windows:是事件驅動(event-driven),應用程序不是通過顯示的函數調用來獲取輸入,而是等待系統將輸入傳遞給它們。
系統將屬于某個應用程序的輸入傳遞給這個應用程序窗口。每一個窗口都有一個叫“窗口過程(window proceduce)”的函數,當窗口有輸入的時候系統便會自動調用窗口函數,窗口函數處理結束后將控制權返回給系統。如果一個頂層窗口幾秒內沒有消息響應,系統默認無響應。
Windows消息(Windows Messages)
系統通過消息(message)的方式將輸入傳遞給“窗口過程”,應用程序和系統都可以產生消息。系統會在每個輸入事件產生消息(例如,用戶敲擊鍵盤,移動鼠標,點擊控件)。系統也會為由應用程序引起的系統改變(像應用程序改變了系統的字體資源池或者調整了窗口大小)而產生消息。應用程序產生的消息,可以傳遞給自己的窗口以執行一些任務,也可以用來與其他應用程序的窗口通信。
系統發送給“窗口過程”的消息包含4個參數:一個窗口句柄,一個消息標識,以及兩個稱為消息參數(message parameters)的參數值。
- 窗口句柄標識了這個消息是要傳遞給哪個窗口的,系統通過它來決定調用哪個“窗口過程”。
- 消息標識是一個用來表示消息的用途的常量。“窗口過程”收到消息后,通過消息標識來決定如何處理消息。例如,消息標識WM_PAINT告訴“窗口過程”窗口客戶區改變了,窗口需要重繪。
- 消息參數指出“窗口過程”處理消息使用的數據或數據地址,參數值的意義決定于消息標識。參數值可以是整數,位掩碼,指向結構體的指針等。當消息不需要參數值時,參數值通常設置為NULL。“窗口過程”必須通過消息標識來確定如何解析消息參數。
從消息隊列中取出一個消息之后,應用程序可以調用DispatchMessage來引導系統將消息傳遞給“窗口過程”。
一個簡單的消息循環函數需要調用GetMessage, TranslateMessage, and DispatchMessage。注意,GetMessage如果發生錯誤會返回-1,因此需要特別判斷。
MSG msg;
BOOL bRet;
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
?“窗口過程”(Window Procedure)
“窗口過程”是接收并處理所有傳遞給窗口的消息的函數。每個窗口類(Windows Class)都有一個“窗口過程”,每個用窗口類創建的窗口都使用相同的“窗口過程”來處理消息。
系統通過把消息數據以參數的形式傳給“窗口過程”來傳遞消息給“窗口過程”,接著“窗口過程”根據消息執行相應的操作。“窗口過程”檢查消息標識,在處理消息時使用消息參數指示的信息。
“窗口過程”一般不會忽略消息,如果它不處理消息,則必須把消息返回給系統以進行默認處理,這是通過調用DefWindowProc來實現的。DefWindowProc進行默認處理并返回結果,“窗口過程”必須把這個結果返回。大部分“窗口過程”只處理一些消息,通過調用DefWindowProc把其它的消息都交給系統處理。
因為一個“窗口過程”是被所有由同一個窗口類創建的窗口共用的,所以它能夠處理幾種不同窗口的消息。“窗口過程”可以通過檢查消息中的窗口句柄來識別消息所影響的窗口。更多信息見Window Procedures主題。
原文鏈接:https://blog.csdn.net/z_tt123456789/article/details/108366454
相關推薦
- 2022-03-27 3個適合新手練習的python小游戲_python
- 2022-06-23 C++11中模板隱式實例化與顯式實例化的定義詳解分析_C 語言
- 2022-07-09 利用Python上傳日志并監控告警的方法詳解_python
- 2022-04-12 iOS?block的值捕獲與指針捕獲詳解_IOS
- 2022-09-25 nginx平滑升級、nginx支持的kill信號
- 2022-06-27 nginx中配置使用proxy?protocol協議的全過程_nginx
- 2022-12-14 Jetpack?Compose重寫TopAppBar實現標題多行折疊詳解_Android
- 2022-06-29 python人工智能tensorflow函數np.random模塊使用_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支