【MFC】如何自定義發送Control消息 COMMAND消息

  爲了自制一個搜索框,但是又不想自己寫太多東西,這裏我通過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日

  1. 創建本文檔,添加ON_CONTROL  ON_COMMAND 兩個消息觸發的原型
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章