爲了自制一個搜索框,但是又不想自己寫太多東西,這裏我通過MFC自帶的文本編(CMFCEditBrowseCtrl)實現搜索框功能
搜索框組成結構:文本編輯框 點擊按鈕
效果如下圖所示,可以很好的滿足我的需求,但是在使用此類時發現按鈕功能並沒有給我作爲消息發送出來,如果繼承之後重寫OnBrowse()在其內部進行搜索操作顯然過於麻煩,因此我通過多方查找,在源碼中找到內部ON_CONTROL 消息的發送機制,這裏寫下筆記以備用。
發送ON_CONTROL消息
想要實現的功能,在點擊右側的按鈕後,父窗口能夠獲取一個搜索消息的觸發,爲實現此功能,首先繼承CMFCEditBrowseCtrl,然後重寫OnBrowse(),在內部添加消息發送函數
GetOwner()->PostMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), ID_Search_Button), (LPARAM)m_hWnd);
接收方使用下面結構進行接收
ON_CONTROL(ID_Search_Button, ID_Search_Edit, &CHuProListView::OnSearchButton)
以此爲結構原型,如果需要更多複雜的消息響應,則只需更改ID_Search_Button爲需要ID即可,方便消息的調用
如發送內置已有的消息(BN_CLICKED)給父窗口,MFC結構中默認的接收方式如下,
ON_CONTROL(BN_CLICKED, id, memberFxn)
ON_BN_CLICKED(IDOK, &CAboutDlg::OnBnClickedOk)
子窗口發送格式使用 GetOwner()->PostMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);即可。
發送ON_COMMAND消息
發送ON_COMMAND消息其實比上文的ON_CONTROL消息更加簡略
GetOwner()->SendMessage(WM_COMMAND, (WPARAM)GetDlgCtrlID(), NULL);//發送方式
ON_COMMAND(ID_Search_Edit, &CHuProListView::OnSearchEdit)//接收方式
可以看到,發送方式幾乎相同都是要向接收的窗口發送,發送命令第一個仍然爲WM_COMMAND,但是第二個參數就變的簡單,只需填寫ID就可以,而接收窗口內部 參數也變的簡單,只需命令ID既可以正常的處理這條消息。
下面展示部分源碼
環境現狀 停靠窗口裏添加 edit編輯框做爲搜索框
停靠窗口內定義
class CHuProListView : public CDockablePane
{
//其他無關內容省略…………
// 特性
protected:
CSearchEdit m_EditBrowse;//演示的成員變量 其ID爲ID_Search_Edit
public:
afx_msg void OnSearchEditChange();
afx_msg void OnSearchButton();
afx_msg void OnSearchEdit();
};
BEGIN_MESSAGE_MAP(CHuProListView, CDockablePane)
ON_EN_CHANGE(ID_Search_Edit, &CHuProListView::OnSearchEditChange) //內置消息
ON_CONTROL(ID_Search_Button, ID_Search_Edit, &CHuProListView::OnSearchButton)///手動增加Control消息
ON_COMMAND(ID_Search_Edit, &CHuProListView::OnSearchEdit) //增加控制消息
END_MESSAGE_MAP()
// 初始化搜索框
void CHuProListView::InitsearchToolBar()
{
// TODO: 在此處添加實現代碼.
RECT rect;//關於顯示的位置自適應調整這裏未寫出實際放置位置
m_EditBrowse.Create(WS_CHILD | WS_VISIBLE, rect, this, ID_Search_Edit);
m_EditBrowse.EnableBrowseButton();
m_EditBrowse.SetOwner(this);
}
Edit搜索框繼承和重載實例
// CSearchEdit
class CSearchEdit : public CMFCEditBrowseCtrl
{
DECLARE_DYNAMIC(CSearchEdit)
public:
CSearchEdit();
virtual ~CSearchEdit();
virtual void OnBrowse();//重寫此方法
protected:
DECLARE_MESSAGE_MAP()
afx_msg void OnSearchButton();
};
void CSearchEdit::OnBrowse()
{
ASSERT_VALID(this);
ENSURE(GetSafeHwnd() != NULL);
switch (m_Mode)
{
case BrowseMode_Default://這裏的模式是創建的時候設定的
/*功能解釋 GetOwner()是獲取所有者的指針,一般爲父窗口指針,Get->SendMessage()意爲向父窗口發送這條信息
信息內容如下 信息命令是WM_COMMAND 觸發消息是ID_Search_Button 此窗口發送的
接收方的消息格式是On_CONTROL(ID_Search_Button,ID_Search_Edit,void *fun())*/
GetOwner()->PostMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), ID_Search_Button), (LPARAM)m_hWnd);
break;
}
SetFocus();
}
熟悉瞭解MFC內部消息機制能夠讓我們更好的規範的使用庫,這裏的一些總結如有不足之處歡迎指正。
補充部分:
部分朋友已經看到了 ON_EN_CHANGE(id, memberFxn) 這個消息,其功能是每當CEdit文本編輯框有數值變動的時候便觸發一次這個消息,而這個消息是什麼樣子的呢 ,通過轉到宏定義 發現其結構
#define ON_EN_CHANGE(id, memberFxn) \
ON_CONTROL(EN_CHANGE, id, memberFxn)
可以猜測這個消息內部也是通過上面的類似結構進行功能觸發的.
但是爲什麼要用這個結構來發送消息,只能去分析源碼對消息的處理形式了,本人能力有限,暫時無法去分析源碼,只好做筆記記錄用法.
日誌:
2019年9月6日
- 創建本文檔,添加ON_CONTROL ON_COMMAND 兩個消息觸發的原型