mfc中的訊息的應用 (轉)
mfc中的訊息莫是相對於虛表來說到底有什麼優勢?有人說是空間上面有好處。既可以省下長長的虛擬函式表的。比如:
用虛擬函式的話,window的基類會是
class window
{
virtual OnSize() = 0;
virtual OnMove() = 0;
virtual OnContextMenu() = 0;
……等等
}
可想而知,每個由此繼承而來的子類將會負擔多麼大的虛擬函式表,光是自帶的就有數十個之多。當然不可取。
可是除此之外,似乎有一種觀點是如果機器夠快的話就可以採用虛擬函式的方法了,哪隻不不過是ms在當年的無奈之舉。嗬嗬,真的是這樣嗎?非也!
其一、如果有自定義的訊息怎麼辦?修改基類?
其二、其實在視窗間互相傳遞訊息可以看成是互相的請求服務,此服務被請求窗體可以響應,也可以不響應。這種靈活性是虛擬函式方法所無法取得的——如果不支援的話,嗬嗬,對不起,編譯時便會報錯了。請求方對於被請求方的所有要求僅僅是其是CCmdTarget的子類即可。怎麼樣,正所謂便宜實惠量又足啊。可就是不太好理解,所以ms提供了許多宏來做這件事情。
下面看一個具體的例子。這是一個關於treectrl操作的例子。這是一棵表示公司組織的樹,上面的節點有
公司
----人事科
-----張三
-----李四
----採購
-----王二
-----麻子
即三類節點,公司、科室、員工
當客戶右擊滑鼠時,對於不同的節點彈出的選單當然是不同的。
做法1、判斷三種節點的圖示,(假定用不同的圖示顯示不同節點)然後針對不同的情況彈出選單。這種方法對於顯然不妥,有點像經典的
if ( obj.typeid == ...)
do something
else if ( obj.typeid == .. )
do somthine else ...
結果就是在treectrl的程式碼中充滿了這樣的判斷程式碼
做法2、有class Company, class , class person,均從CCmdTarget繼承。當insert treeitem的時候,產生,將其指標和插入的item聯絡起來,方法可以採用SetItemData(物件的指標),這樣的話,處理彈出選單的方法就變為
treectrl::OnContextMenu(...)
{
CCmdTarget* p = GetItemData(hSelItem);
p->sendcommand(wm_contextmenu, point)
}
這樣就ok了。但是有一個缺點,佔用太多的記憶體了!每個item都有多出sizeof(CCmdTarget),有點過分。
再改進——做法3
class Company, office, person不變,
但增加他們的工廠類
class treeitemor
{
virtual CCmdTarget* CreateItem() = 0;
}
class Companyor
{
long m_ID;
virtual CmdTarget* CreateItem(); //產生Company類
}
class office和person同上
彈出選單變為
treectrl::OnContextMenu(...)
{
treeItemor* ItemCreator = GetItemData(hSelItem);
CCmdTarget *pCmd = ItemCreator->CreateItem();
pCmd->SendCommand(WM_CONTEXTMENU, POINT);
}
呼!總算完了。最後請大家多提意見!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-996715/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MFC DLL如何響應PreTranslateMessage訊息
- MFC訊息對映
- 用程式碼理解 ObjC 中的傳送訊息和訊息轉發OBJ
- 用於日期轉換的訊息轉換器
- MFC學習(四) 訊息機制
- Objective-C中的訊息轉發Object
- 訊息中介軟體的應用場景
- OCX 控制元件主動傳送訊息給 MFC 視窗訊息控制元件
- RabbitMq中的訊息應答與持久化MQ持久化
- 訊息佇列系列一:訊息佇列應用佇列
- MFC中獲取程式自身的版本資訊
- python 用traceback列印錯誤訊息(轉)Python
- 訊息佇列常見的 5 個應用場景佇列
- 訊息佇列常見的5個應用場景佇列
- 訊息佇列的七種經典應用場景佇列
- Java訊息佇列:RabbitMQ與Kafka的整合與應用Java佇列MQKafka
- Zalo成為越南最受歡迎的訊息應用程式
- redis訊息佇列簡單應用Redis佇列
- React應用裡Invalid hook call錯誤訊息的處理ReactHook
- 基於Redis訊息的訂閱釋出應用場景Redis
- 訊息中介軟體應用的常見問題與方案
- 計算儲存分離在訊息佇列上的應用佇列
- 基於tcp的應用層訊息邊界如何定義TCP
- 訊息佇列中的Oracle佇列Oracle
- Visaul Studio 2015 MFC 應用程式工程建立
- iOS 訊息轉發iOS
- Fuchsia最新訊息,確認支援Android應用Android
- Android應用程式訊息處理機制Android
- 使用Java客戶端傳送訊息和消費的應用Java客戶端
- MFC vc++ 中CTreeContrl如何自定義實現滑鼠單擊或雙擊響應事件 ,即重寫類似於控制元件的響應事件或訊息C++事件控制元件
- Socket.D 基於訊息的響應式應用層網路協議協議
- RocketMQ中Producer訊息的傳送MQ
- AI在視訊遊戲中的應用AI遊戲
- 好訊息!微軟已將Windows子系統轉為win11應用程式微軟Windows
- 主流的訊息佇列MQ比較,詳解MQ的4類應用場景佇列MQ
- [WPF]用HtmlTextBlock實現訊息對話方塊的內容高亮和跳轉HTMLBloC
- 使用 laravel-wechat-notification 傳送微信模板訊息、企業微信應用訊息Laravel
- 法國政府釋出它開發的端對端加密訊息應用加密
- Angular 伺服器端渲染應用的一個錯誤訊息 - localStorage is not definedAngular伺服器