QT c++ 中使用PostMessage/SendMessage实例
PostMessage是Windows API(應用程序接口) 中的一個常用函數,用于將一條消息放入到消息隊列中。并且不會等待響應的線程處理消息,而是直接返回。(簡單的理解就是異步)。
而SendMessage作用一樣,但是會等待結果返回(同步)
我們先來看PostMessage函數的原型:
BOOL WINAPI PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含義的兩個值:
HWND_BROADCAST:消息被寄送到系統的所有頂層窗口,包括無效或不可見的非自身擁有的窗口、 被覆蓋的窗口和彈出式窗口。消息不被寄送到子窗口
NULL:此函數的操作和調用參數dwThread設置為當前線程的標識符PostThreadMessage函數一樣
Msg:指定被寄送的消息。
wParam:指定附加的消息特定的信息。
LParam:指定附加的消息特定的信息。
返回值:如果函數調用成功,返回非零,否則函數調用返回值為零
接收的時候,使用QT5中的方法是 在接收的類中,重新實現 nativeEvent函數(Qt4的時候使用的是winEvent,從Qt5開始,就使用nativeEvent),這個方法既可以攔截系統消息,也可以攔截通過postMessage,sendMessage發送的自定義消息。
[virtual protected] bool QWidget::nativeEvent(const QByteArray &eventType, void *message, long *result);
其中:
eventType: windows平臺的值就是“windows_generic_MSG”;
message: 類型為MSG*, 存儲的就是PostMessage中的Msg。
Result:類型為LRESULT,返回的值。
如果返回ture:表示停止這個消息。如果返回false:這個消息就繼續傳遞給Qt,Qt會將這個消息轉變為Qt event并將它發送給響應的控件。
我們用Qt環境下來舉個栗子:
先是使用SendMessage來向頂層窗口發送消息
? ? HWND m_wnd = ::FindWindowA(("ClientMainWindow"), NULL);//通過主窗口類名尋找主窗口句柄
? ? WId wid = this->winId(); //這個窗口的winid
? ? if (NULL != m_wnd)
? ? {
? ? ? ? std::thread th([=](){ //單獨啟動一個線程進行數據傳遞
? ? ? ? ? ? QString command = QString("Command=ChangeCode=%1\r\n").arg(code);//傳遞的內容
? ? ? ? ? ? std::string param = command.toStdString();
? ? ? ? ? ? COPYDATASTRUCT data; ? ?//使用COPYDATA的方式進行數據傳遞
? ? ? ? ? ? data.dwData = 0;
? ? ? ? ? ? data.cbData = param.length();
? ? ? ? ? ? data.lpData = ¶m[0];
? ? ? ? ? ? ::SendMessage(m_wnd, WM_COPYDATA, (WPARAM)wid, (LPARAM)&data);
? ? ? ? });
?
? ? ? ? th.detach();//傳遞結束后,進行關閉線程
? ? }
同時,在接收的頂層窗口中,重寫nativeEvent函數
bool EmbededWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
?? ?if (eventType == "windows_generic_MSG") //windows平臺
?? ?{
?? ??? ?MSG* msg = reinterpret_cast<MSG*>(message); //
?
?? ??? ?if(msg->message == WM_COPYDATA)//消息類型
?? ??? ?{
?? ??? ??? ?COPYDATASTRUCT *data = reinterpret_cast<COPYDATASTRUCT*>(msg->lParam);
?? ??? ??? ?QTextCodec *gbk = QTextCodec::codecForName("GB18030");
?? ??? ??? ?QString recevice = gbk->toUnicode((char *)(data->lpData));//轉碼
?
?? ??? ??? ?if(recevice.contains("Command="))
?? ??? ??? ?{
?? ??? ??? ? ? return true;//消息不再進行傳遞,不再處理
?? ??? ??? ?}
?
?? ??? ??? ?m_wnd = reinterpret_cast<HWND>(msg->wParam);//高地址的參數
?
?? ??? ?}
?? ?}
?
?? ?return QWidget::nativeEvent(eventType, message, result);//交給Qt處理
}
使用PostMessage發送消息用法完全一樣。無論使用SendMessage還是使用PostMessage發送消息,接收函數都是nativeEvent。
?
總結
以上是生活随笔為你收集整理的QT c++ 中使用PostMessage/SendMessage实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: qt-编码问题解答
- 下一篇: QT-子线程或自定义类操作访问主界面UI