文章目录
前言
在开发过程中,使用XListCtrl来丰富列表的使用,从而发现对项ComboBox的改变响应没有好的方法入手,既有一下问题过程,现解决记录互相分享,下拉到底直接查看解决方法。
一、开发需求
如上图所示,当数据类型改变时需要改变内容中的显示方式(可选框或者输入框)。
二、寻找解决方法
1.用ComboBox的CBN_SELCHANGE消息进行尝试
代码如下(示例):
//CXListCtrl列表的变量 CXListCtrl m_list;
DDX_Control(pDX, IDC_LIST2, m_list);
//消息绑定函数 尝试绑定在列表上
ON_CBN_SELCHANGE(IDC_LIST2, &CModelConfigDlg::OnSelchangeComboStyle)
//Combox控件的生成方式如下,所以没有对象可以直接绑定
m_list.SetComboBox(nItem, 4,
TRUE, // enable combobox
&(CStringArray), // pointer to persistent CStringArray
5, // size of dropdown
0, // initial combo selection
FALSE); // sort CStringArray
结果:此方法没有响应
2.考虑XListCtrl是否有自带的响应消息
A.获得WM_XLISTCTRL_COMBO_SELECTION消息
百度查找到以下内容:
XListCtrl中自定义了消息WM_XLISTCTRL_COMBO_SELECTION,写个该消息的响应函数就可以了。
来自此CSDN问答:如何获取CXListCtrl中ComboBox的下拉事件
B.尝试进行消息绑定和获取
//响应接口声明
afx_msg LRESULT OnXlistCombo(WPARAM wParam, LPARAM lParam);
//消息绑定
ON_MESSAGE(WM_XLISTCTRL_COMBO_SELECTION, &CModelConfigDlg::OnXlistCombo)
结果:此方法没有响应
C.对CXListCtrl源码分析
上述步骤不能实现,考虑是否CListCtrl对此消息有特殊处理,以下贴出部分源码追踪过程
//在XListCtrl.cpp注册了此消息
XLISTCTRLLIBDLLEXPORT UINT WM_XLISTCTRL_COMBO_SELECTION = ::RegisterWindowMessage(_T("WM_XLISTCTRL_COMBO_SELECTION"));
//查找此消息的发送位置
void CXListCtrl::OnTimer(UINT nIDEvent)
{
//忽略部分源码.......
else if (nIDEvent == 3) // get combo listbox selection, then close combo listbox
{
//忽略部分源码.......
CWnd *pWnd = GetParent();
if (!pWnd)
pWnd = GetOwner();
if (pWnd && ::IsWindow(pWnd->m_hWnd))
pWnd->SendMessage(WM_XLISTCTRL_COMBO_SELECTION,
m_nComboItem, m_nComboSubItem);
//忽略部分源码.......
}
//可知在定时器中 去当接收到3的触发条件进行发送消息 接着查看定时器启动位置
// OnComboReturn
LRESULT CXListCtrl::OnComboComplete(WPARAM, LPARAM)
{
XLISTCTRL_TRACE(_T("in CXListCtrl::OnComboComplete\n"));
SetTimer(3, 50, NULL);
return 0;
}
//查到一个信号相应函数 绑定接口如下
ON_REGISTERED_MESSAGE(WM_XCOMBOLIST_COMPLETE, OnComboComplete)
//去查找信号WM_XCOMBOLIST_COMPLETE未有发现从而对ON_REGISTERED_MESSAGE这个不常见的绑定方法进行分析
D.ON_REGISTERED_MESSAGE自定义消息绑定接口
通过百度查找得到如下
注意事项:
发送消息的-MyMessageDlg.cpp前也要定义
static UINT WM_MY_MESSAGE=RegisterWindowMessage(“Message”);
接受消息的-MessageTestView.cpp前也要定义
static UINT WM_MY_MESSAGE=RegisterWindowMessage(“Message”);
RegisterWindowMessage(“Message”)中""的内容是什么不重要,写什么都可以,单必须
发送者与接受者是一样的内容,例如:“Message”
来自此博客 发送自定义消息:ON_MESSAGE和ON_REGISTERED_MESSAGE的差别(转)
解决方法
涉及代码如下
//先在接收消息所在的CPP进行消息注册
static UINT WM_MY_MESSAGE = RegisterWindowMessage(_T("WM_XLISTCTRL_COMBO_SELECTION"));
//绑定消息
ON_REGISTERED_MESSAGE(WM_MY_MESSAGE, OnXlistCombo)
//消息响应函数
afx_msg LRESULT CModelConfigDlg::OnXlistCombo(WPARAM wParam, LPARAM lParam)
{
CString strTittle;
strTittle.Format(_T("自定义消息参数:x=%d,y=%d"), wParam, lParam);
SetWindowText(strTittle);
return LRESULT();
}
至此,每次ComboBox的改变,都可以在响应函数中得到在XListCtrl上对应的行列位置,即可在响应函数中实现对应功能要求