boost庫實在是乙個博大精深的庫。經過實驗,我發現巧用boost::bind和boost::function可以實現一些巧妙的設計。
編寫過mfc程式的朋友都知道,通過資源編輯器編輯選單項,設定選單項id,然後mfc內部通過該id來對映選單命令處理函式和選單介面更新函式。我設想撇開mfc的資源編輯,在mfc程式中通過xml檔案來進行介面配置,然後利用字串來對映訊息處理函式。借助boost庫,我實現了這一設想。具體就是在xml檔案指定乙個字串,然後通過這個字串就能找到它的命令訊息處理函式和介面更新命令訊息處理函式。
下面具體談談怎麼實現這一設想。我需要解決的是兩大問題:一是通過xml檔案來動態建立介面;二是根據xml檔案裡指定的選單項字串找到它的命令訊息處理函式。
第乙個問題相對簡單。首先我談談我的系統介面配置xml檔案的設計。我的系統介面配置xml檔案比較簡單,具體如下:
view plaincopy to clipboardprint?
<?xml version="1.0" encoding="gb2312" standalone="no" ?>
<?xml version="1.0" encoding="gb2312" standalone="no" ?>
對應這個系統配置xml檔案,我們需要在程式中定義相應的結構體,具體如下:
view plaincopy to clipboardprint?
#include
using std::string;
#include
using std::vector;
* \brief 程式資訊結構體.
* * 包含了程式名、公司名和公司**
*/
/**
* \brief 應用程式名。
*/
/**
* \brief 公司名。
*/
string m_strcompanyname;
/**
* \brief 公司**。
*/
string m_strurl;
};
/*! \struct menuitem basestruct.h
* \brief 選單項資訊結構體.
* * 包含了選單是否有效,選單識別符號和選單名
*/
struct menuitem
/**
* \brief 選單項是否有效,1為有效,0為無效。
*/
string m_strvalid;
/**
* \brief 選單標識,用於對映訊息處理函式。
*/
string m_strid;
/**
* \brief 選單項名。
*/
string m_strcaption;
};
* \brief 選單欄資訊結構體.
* * 包含了選單欄是否有效、選單欄名和選單項陣列
*/
/**
* \brief 選單欄是否有效,1為有效,0為無效。
*/
string m_valid;
/**
* \brief 選單欄名。
*/
string m_strcaption;
/**
* \brief 對應的選單項陣列。
*/
vectorm_menuitemvec;
};
#include
using std::string;
#include
using std::vector;
* \brief 程式資訊結構體. *
* 包含了程式名、公司名和公司** */
; /*! \struct menuitem basestruct.h
* \brief 選單項資訊結構體. *
* 包含了選單是否有效,選單識別符號和選單名 */
struct menuitem ;
* \brief 選單欄資訊結構體. *
* 包含了選單欄是否有效、選單欄名和選單項陣列 */
; tinyxml快速入門(一)
tinyxml快速入門(二)
tinyxml快速入門(三)
就tinyxml使用答覆一位網友
將tinyxml快速入門的介面物件導向化
具體做法是在應用程式類裡定義兩個變數:
view plaincopy to clipboardprint?
/**
* \brief 用於儲存程式資訊的變數。
* */
/**
* \brief 用於儲存程式資訊的變數。
* */
cxmlparse *m_psyssetting;
在程式初始化例項函式initinstance()裡呼叫cxmlparse類的介面來解析系統配置檔案。根據解析系統xml檔案來動態建立選單欄的**也比較簡單,集中在getallmenubar和mainmenubarcreate兩個函式,具體見上傳的**,這裡不作贅述。
下面我具體談談如何通過xml檔案中指定的選單id字串來對映它的訊息處理函式,概括來說是通過乙個函式來實現的。
view plaincopy to clipboardprint?
/**
* \brief 選單命令訊息處理函式指標。
* */
typedef boost::functioncmdfunction;
/**
* \brief 選單介面更新命令訊息處理函式指標。
* */
typedef boost::functionupdatecmduifunction;
/*** \brief 選單命令訊息處理函式指標。 *
*/typedef boost::functioncmdfunction;
/*** \brief 選單介面更新命令訊息處理函式指標。 *
*/typedef boost::functionupdatecmduifunction;
在框架類裡定義乙個map,選單id作為鍵,訊息處理函式指標作為鍵值:
view plaincopy to clipboardprint?
/**
* \brief 儲存所有命令訊息處理函式指標的map。
*/
然後在建立選單的時候將訊息處理函式指標新增進這個map:
view plaincopy to clipboardprint?
void cmainframe::addtomessagemap(uint umenuid,cmdfunction cmd, updatecmduifunction updateuicmd)
void cmainframe::mainmenubarcreate()
m_menu.createmenu();
// 給cmdid賦值為系統起始選單id值
int cmdid = sys_command_begin;
int menubarsize = m_menubarvec.size();
for (int i=0;i
if (string(_t("file_open"))==m_menubarvec[i].m_menuitemvec[j].m_strid)
if (string(_t("edit_copy"))==m_menubarvec[i].m_menuitemvec[j].m_strid)
if (string(_t("edit_paste"))==m_menubarvec[i].m_menuitemvec[j].m_strid)
cmdid++;
}
// 將彈出選單欄插入到主選單
popmenu.detach();
}
// 設定為系統主選單
setmenu(&m_menu);
} void cmainframe::addtomessagemap(uint umenuid,cmdfunction cmd, updatecmduifunction updateuicmd)
void cmainframe::mainmenubarcreate()
int cmdid = sys_command_begin;
// 將彈出選單欄插入到主選單
popmenu.detach();
setmenu(&m_menu); }
最後過載框架類的oncmdmsg函式,根據選單id值呼叫map裡的函式:
view plaincopy to clipboardprint?
bool cmainframe::oncmdmsg(uint nid, int ncode, void* pextra, afx_cmdhandlerinfo* phandlerinfo)
bool cmainframe::oncmdmsg(uint nid, int ncode, void* pextra, afx_cmdhandlerinfo* phandlerinfo)
巧用boost庫實現字串對映訊息處理函式
boost庫實在是乙個博大精深的庫。經過實驗,我發現巧用boost bind和boost function可以實現一些巧妙的設計。編寫過mfc程式的朋友都知道,通過資源編輯器編輯選單項,設定選單項id,然後mfc內部通過該id來對映選單命令處理函式和選單介面更新函式。我設想撇開mfc的資源編輯,在m...
巧用boost庫實現字串對映訊息處理函式
boost庫實在是乙個博大精深的庫。經過實驗,我發現巧用boost bind和boost function可以實現一些巧妙的設計。編寫過mfc程式的朋友都知道,通過資源編輯器編輯選單項,設定選單項id,然後mfc內部通過該id來對映選單命令處理函式和選單介面更新函式。我設想撇開mfc的資源編輯,在m...
巧用boost庫實現字串對映訊息處理函式
boost 庫實在是乙個博大精深的庫。經過實驗,我發現巧用boost bind和boost function可以實現一些巧妙的設計。編寫過mfc程式的朋友都知道,通過資源編輯器編輯選單項,設定選單項id,然後mfc內部通過該id來對映選單命令處理函式和選單介面更新函式。我設想撇開mfc的資源編輯,在...