在使用較長時間的mfc之後,感覺自己需要將零散的mfc知識整合一下,所以開始推出這個系列的博文,首先就從mfc經典的訊息機制入手,來介紹mfc是怎麼運作的。這篇主要介紹一下訊息機制中幾個基礎概念。
這篇主要介紹訊息如何路由到主視窗。
寫過win32程式,肯定只要我們要展示乙個視窗,需要這個入口函式,這個就像控制台程式中main函式,是程式的入口。但是在mfc專案建立之後,我們在專案工程卻找不到這個函式。
其實mfc已經將這個函式內部寫好了,具體在下面這個檔案中。
microsoft visual studio10.0\vc\atlmfc\src\mfc\winmain.cpp
以下winmain函式中的內容,這些**中的大部分我們暫時不做詳細介紹,在之後的篇章中會來討論這些**。
assert(hprevinstance == null);
int nreturncode = -1;
cwinthread*pthread = afxgetthread();
// afx internal initialization
if (!afxwininit(hinstance, hprevinstance, lpcmdline,ncmdshow))
goto initfailure;
goto initfailure;
// perform specific initializations
if (!pthread->initinstance())
nreturncode= pthread->exitinstance();
goto initfailure;
}nreturncode =pthread->run();
initfailure:
#ifdef _debug
// check for missing afxlocktempmap calls
if (afxgetmodulethreadstate()->m_ntempmaplock !=0)
afxlocktempmaps();
afxunlocktempmaps(-1);
#endif
afxwinterm();
return nreturncode;
上訴**中第27行**,我們需要找的訊息迴圈就在run函式中,接下來就看一下這個run函式。
這個類微軟用來封裝mfc的執行緒。
這裡我們主要來討論這個類中的run函式
virtual int cwinthread::run()
do// 空閒處理接觸,進行訊息處理
} while (::peekmessage(&m_msgcur, null, null, null,pm_noremove));
}assert(false);//
}
這裡先說明,以上**包括下面的**都是筆者從網上找到的,所以對於其準確性不能夠保證,但是作為介紹性說明,應該是沒有問題的。
我們按照函式執行順序往下看,首先我們發現了乙個死迴圈,這個死迴圈便是我們要的訊息迴圈。
接下來我們便是idle狀態的處理,沒有訊息處理的時候,執行緒進入idle狀態。其中peekmessage,便是用來判斷訊息佇列中是否有訊息。
再往下看,我們會發現乙個叫pumpmessage,這個函式便是這裡的乙個關鍵函式(從run函式的**中看,好像也沒有其對隊訊息進行處理的函式了)。
接下來就看一下pumpmessage函式的原始碼
bool cwinthread::pumpmessage()
return true;
}
按照執行順序看,我們會注意到getmessage,這個函式這裡暫時不做介紹,就是從執行緒的訊息佇列中獲取訊息,並把訊息內容放入乙個結構的物件中(這裡就放入msgcur)。
接下來便是判斷訊息是否是idle訊息,如果不是就交給pretranslatemessage,這個函式又是乙個關鍵函式,所以我們有必要再次去找到它的原始碼進行分析。
bool cwinthread::pretranslatemessage(msg* pmsg)
return false; // no special processing
}
我們按照函式的執行順序來看,首先判斷一下這個訊息是否是發給視窗的。如果不是,那麼就是乙個執行緒訊息,就交給dispatchthreadmessageex(這裡也暫時不介紹這個函式,不是這篇討論的重點)。
接下面,我們獲得主視窗物件,就把訊息交給walkpretranslatetree處理。
繼續**,我們有需要找到walkpretranslatetree的原始碼。(很抱歉,要看這麼多**)
bool pascal cwnd::walkpretranslatetree(hwnd hwndstop,msg* pmsg)
// got to hwndstop window without interest
if (hwnd == hwndstop)
break;
}return false; // no specialprocessing
}
略去一些空值的檢查,我們看到訊息最後是交給了主視窗的pretranslatemessage函式處理了。接下來就交給主視窗進行訊息處理了。
這裡我們就大致了解了乙個訊息怎麼路由到主視窗的流程。
開始程式設計不久,便接觸到了mfc。用了mfc寫了自己第乙個視窗程式,寫了第乙個遊戲,在學校課題演示的時候也是喜歡用mfc做演示。
現在工作了,專案的介面部分也在使用mfc開發的,值得慶幸的是,現在微軟對於mfc的介面做了很大的改善,想起剛開始不斷重寫控制項類,那個真是記憶猶新。
在平時程式設計的時候,vs這個整合工具確實很方便。但現在想把一些mfc零零碎碎的知識整合起來。所以這個系列可能會深入地去介紹mfc。
訊息和訊息處理之訊息迴圈
在win32程式設計中,訊息迴圈是相當重要的乙個概念,看似很難,但使用起來卻是非常簡單。在winmain函式的最後,有下列 while getmessage msg,null,0,0 windows應用程式可以接收以各種形式輸入的資訊,這包括鍵盤 滑鼠動作 計時器產生的訊息,也可以是其他應用程式發來...
訊息和訊息佇列
在傳統的c 程式當中,我們呼叫 fopen 函式開啟檔案,這個庫函式最終呼叫作業系統 提供的函式 來開啟檔案。而在 windows 中,不僅使用者程式可以呼叫系統的 api函式,反回來,系統也會呼叫使用者程式,這個呼叫是通過訊息來進行的。windows程式設計是一種完全不同於傳統的 dos方式的程式...
訊息佇列 訊息複製
訊息複製需要解決 高效能,高可用,資料一致性 高效能 寫的副本越多,寫的效能越低,讀取不影響 資料一致性,必須採用主從模式的複製方式,同時需要保證在任何時刻,集群的主節點不能超過乙個。高可用 在主節點宕機後,可以盡快選出新的主節點 一 rocketmq 1 傳統複製 複製的基本單位是broker,也...