为了自制一个搜索框,但是又不想自己写太多东西,这里我通过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, MAKEWPARAM(GetDlgCtrlID(),CNCOMMAND), 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 两个消息触发的原型