日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Qt和Windows消息通信機制

作者:z_tt123456789 更新時間: 2022-07-18 編程語言

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

欄目分類
最近更新