哪个是 MFC C++ 中单选组合框的事件处理程序
Posted
技术标签:
【中文标题】哪个是 MFC C++ 中单选组合框的事件处理程序【英文标题】:Which is the event handler for Combobox for single select in MFC C++ 【发布时间】:2019-05-09 05:14:32 【问题描述】:在选择特定组合框时启用或禁用某些文本框时遇到问题。
我尝试过使用OnCbnSelChangeLvLayers()
和OnCbnDropdownLvLayers()
。
第一个事件处理程序的问题是我必须两次单击相同的值,并且组合框中的选择会冻结。第二个事件处理程序解决了冻结问题,但我必须单击组合框的下拉菜单才能发生事件。我还为组合框尝试了其他一些事件处理程序,但没有成功。 m_d_layers
是组合框选择的字符串变量 (1,2,3,4)
DDX:
void CThermalToolDlg::DoDataExchange(CDataExchange* pDX)
DDX_CBString(pDX, IDC_LV_LAYERS, m_d_lvlayers);
消息映射:
BEGIN_MESSAGE_MAP(CThermalToolDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_CBN_DROPDOWN(IDC_LV_LAYERS, &CThermalToolDlg::OnCbnDropdownLvLayers)
ON_CBN_DROPDOWN(IDC_HV_LAYERS, &CThermalToolDlg::OnCbnDropdownHvLayers)
ON_CBN_DROPDOWN(IDC_LVDUCTTYPE1, &CThermalToolDlg::OnCbnDropdownLvducttype1)
ON_CBN_DROPDOWN(IDC_LVDUCTTYPE2, &CThermalToolDlg::OnCbnDropdownLvducttype2)
ON_CBN_DROPDOWN(IDC_LVDUCTTYPE3, &CThermalToolDlg::OnCbnDropdownLvducttype3)
ON_CBN_DROPDOWN(IDC_HVDUCTTYPE1, &CThermalToolDlg::OnCbnDropdownHvducttype1)
ON_CBN_DROPDOWN(IDC_HVDUCTTYPE2, &CThermalToolDlg::OnCbnDropdownHvducttype2)
ON_CBN_DROPDOWN(IDC_HVDUCTTYPE3, &CThermalToolDlg::OnCbnDropdownHvducttype3)
ON_BN_CLICKED(IDCANCEL, &CThermalToolDlg::OnBnClickedCancel)
ON_BN_CLICKED(ID_CALCULATE, &CThermalToolDlg::OnCalculate)
//ON_CBN_EDITUPDATE(IDC_LV_LAYERS,&CThermalToolDlg::OnCbnEditupdateLvLayers)
//ON_CBN_SELENDOK(IDC_LV_LAYERS, &CThermalToolDlg::OnCbnSelendokLvLayers)
END_MESSAGE_MAP()
事件处理程序:
void CThermalToolDlg::OnCbnDropdownLvLayers()
// TODO: Add your control notification handler code here
UpdateData();
if (m_d_lvlayers == "1")
GetDlgItem(IDC_LV2_CU)->EnableWindow(0);
GetDlgItem(IDC_LV2_ICI)->EnableWindow(0);
//and so on
else if (m_d_lvlayers == "2")
GetDlgItem(IDC_LV2_CU)->EnableWindow(1);
GetDlgItem(IDC_LV2_ICI)->EnableWindow(1);
//and so on
else if (m_d_lvlayers == "3")
GetDlgItem(IDC_LV2_CU)->EnableWindow(1);
GetDlgItem(IDC_LV2_ICI)->EnableWindow(1);
//and so on
else
GetDlgItem(IDC_LV2_CU)->EnableWindow(1);
GetDlgItem(IDC_LV2_ICI)->EnableWindow(1);
//and so on
我想在不冻结组合框的情况下单击一下即可获得所需的启用/禁用。有没有其他方法或更快的方法?
【问题讨论】:
这个问题的第一个答案怎么样:***.com/questions/698910/…? @SamiSallinen 感谢您引导我解决这个问题。它与我的问题一致,但是两个事件处理程序(SELENDOK 和 EDITUPDATE)的解决方案不起作用,并且代码总是跳转到 else 循环。我不知道我做错了什么。 您的代码很糟糕:唯一与其他所有不同的情况是“1”。话虽这么说:您需要添加一张图片,显示 IDC_LV2_CU 和 IDC_LV2_ICI 是什么控件。 @Jabberwocky 情况不同我只是没有提到所有条件。 IDC_LV2_CU 和 IDC_LV2_ICI 是几个文本框(还有更多),需要根据 4 个选择启用或禁用。这里的问题是通过单击更新类文件中组合框的值。 显示您的消息映射 (BEGIN_MESSAGE_MAP...
) 以及 CThermalToolDlg::DoDataExchange
的定义。如果您有 OnCbnEditUpdate
和其他与组合框相关的处理程序,那么也显示它们的定义。通常你只需要处理ON_CBN_SELCHANGE
【参考方案1】:
这似乎是下拉列表组合框和简单组合框(不是下拉列表)的错误。 DDX_CBString
或 DDX_CBStringExact
未检索到正确的值以响应 ON_CBN_DROPDOWN
。
您可以使用自己的代码来检索正确的字符串:
void CThermalToolDlg::OnCbnDropdownLvLayers()
//UpdateData();
CComboBox *cb = (CComboBox*)GetDlgItem(IDC_LV_LAYERS);
if(cb)
int sel = cb->GetCurSel();
if(sel >= 0)
cb->GetLBText(sel, m_d_lvlayers);
TRACE(L"%s\n", m_d_lvlayers.GetString());
出于调试目的,注释掉除ON_CBN_DROPDOWN(IDC_LV_LAYERS...)
之外的其他消息。在继续之前,请确保您拥有正确的字符串。
不要像您在上一个问题中所做的那样致电UpdateData(FALSE)
。如果没有检索到正确的字符串,这可能会导致问题。
【讨论】:
这是检索正确字符串的正确方法,但仍然在选择组合框中的值调试到void CThermalToolDlg::OnCbnDropdownLvLayers()
中的 else 循环我应该为条件添加单独的事件处理程序吗?跨度>
我不确定根本问题。也许某处有空白。输入TRACE(_T("[%s]\n"), m_d_lvlayers.GetString())
。你看到了什么调试输出?
这里的根本问题是事件处理程序。 ON_CBN_DROPDOWN
事件处理程序在进行选择之前单击下拉菜单时启动。因此,我需要在进行选择后再次单击下拉列表,以便更新值。同样,ON_CBN_SELCHANGE
必须进行两次选择,但组合框在此处冻结。
使用ON_CBN_SELENDOK
而不是ON_CBN_DROPDOWN
,如果是下拉列表或简单的组合框,不要调用UpdateData
。【参考方案2】:
感谢@BarmakShemirani,我在ON_CBN_SELENDOK
事件处理程序中使用了他的代码来检索正确的字符串,而不是UpdateData()
,现在它就像一个魅力
DDX:
void CThermalToolDlg::DoDataExchange(CDataExchange* pDX)
DDX_CBString(pDX, IDC_LV_LAYERS, m_d_lvlayers);
消息映射:
BEGIN_MESSAGE_MAP(CThermalToolDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_CBN_SELENDOK(IDC_LV_LAYERS, &CThermalToolDlg::OnCbnSelendokLvLayers)
ON_BN_CLICKED(IDCANCEL, &CThermalToolDlg::OnBnClickedCancel)
ON_BN_CLICKED(ID_CALCULATE, &CThermalToolDlg::OnCalculate)
END_MESSAGE_MAP()
事件处理程序:
void CThermalToolDlg::OnCbnSelendokLvLayers()
// TODO: Add your control notification handler code here
CComboBox *cb = (CComboBox*)GetDlgItem(IDC_LV_LAYERS);
if (cb)
int sel = cb->GetCurSel();
if (sel >= 0)
cb->GetLBText(sel, m_d_lvlayers);
TRACE(_T("[%s]\n"), m_d_lvlayers.GetString());
/*UpdateData();*/
if (m_d_lvlayers == "1")
GetDlgItem(IDC_LV2_CU)->EnableWindow(0);
GetDlgItem(IDC_LV2_ICI)->EnableWindow(0);
GetDlgItem(IDC_LV2_PC)->EnableWindow(0);
GetDlgItem(IDC_LV2_RESIN)->EnableWindow(0);
GetDlgItem(IDC_LV2_RESO)->EnableWindow(0);
GetDlgItem(IDC_LV2_INST)->EnableWindow(0);
GetDlgItem(IDC_LV3_CU)->EnableWindow(0);
GetDlgItem(IDC_LV3_ICI)->EnableWindow(0);
GetDlgItem(IDC_LV3_PC)->EnableWindow(0);
GetDlgItem(IDC_LV3_RESIN)->EnableWindow(0);
GetDlgItem(IDC_LV3_RESO)->EnableWindow(0);
GetDlgItem(IDC_LV3_INST)->EnableWindow(0);
GetDlgItem(IDC_LV4_CU)->EnableWindow(0);
GetDlgItem(IDC_LV4_ICI)->EnableWindow(0);
GetDlgItem(IDC_LV4_PC)->EnableWindow(0);
GetDlgItem(IDC_LV4_RESIN)->EnableWindow(0);
GetDlgItem(IDC_LV4_RESO)->EnableWindow(0);
GetDlgItem(IDC_LV4_INST)->EnableWindow(0);
GetDlgItem(IDC_LVDUCTTYPE1)->EnableWindow(0);
GetDlgItem(IDC_LVDUCTTYPE2)->EnableWindow(0);
GetDlgItem(IDC_LVDUCTTYPE3)->EnableWindow(0);
GetDlgItem(IDC_LV_D_NO_12)->EnableWindow(0);
GetDlgItem(IDC_LV_D_NO_23)->EnableWindow(0);
GetDlgItem(IDC_LV_D_NO_34)->EnableWindow(0);
else if (m_d_lvlayers == "2")
GetDlgItem(IDC_LV2_CU)->EnableWindow(1);
GetDlgItem(IDC_LV2_ICI)->EnableWindow(1);
GetDlgItem(IDC_LV2_PC)->EnableWindow(1);
GetDlgItem(IDC_LV2_RESIN)->EnableWindow(1);
GetDlgItem(IDC_LV2_RESO)->EnableWindow(1);
GetDlgItem(IDC_LV2_INST)->EnableWindow(1);
GetDlgItem(IDC_LV3_CU)->EnableWindow(0);
GetDlgItem(IDC_LV3_ICI)->EnableWindow(0);
GetDlgItem(IDC_LV3_PC)->EnableWindow(0);
GetDlgItem(IDC_LV3_RESIN)->EnableWindow(0);
GetDlgItem(IDC_LV3_RESO)->EnableWindow(0);
GetDlgItem(IDC_LV3_INST)->EnableWindow(0);
GetDlgItem(IDC_LV4_CU)->EnableWindow(0);
GetDlgItem(IDC_LV4_ICI)->EnableWindow(0);
GetDlgItem(IDC_LV4_PC)->EnableWindow(0);
GetDlgItem(IDC_LV4_RESIN)->EnableWindow(0);
GetDlgItem(IDC_LV4_RESO)->EnableWindow(0);
GetDlgItem(IDC_LV4_INST)->EnableWindow(0);
GetDlgItem(IDC_LVDUCTTYPE1)->EnableWindow(1);
GetDlgItem(IDC_LVDUCTTYPE2)->EnableWindow(0);
GetDlgItem(IDC_LVDUCTTYPE3)->EnableWindow(0);
GetDlgItem(IDC_LV_D_NO_12)->EnableWindow(1);
GetDlgItem(IDC_LV_D_NO_23)->EnableWindow(0);
GetDlgItem(IDC_LV_D_NO_34)->EnableWindow(0);
else if (m_d_lvlayers == "3")
GetDlgItem(IDC_LV2_CU)->EnableWindow(1);
GetDlgItem(IDC_LV2_ICI)->EnableWindow(1);
GetDlgItem(IDC_LV2_PC)->EnableWindow(1);
GetDlgItem(IDC_LV2_RESIN)->EnableWindow(1);
GetDlgItem(IDC_LV2_RESO)->EnableWindow(1);
GetDlgItem(IDC_LV2_INST)->EnableWindow(1);
GetDlgItem(IDC_LV3_CU)->EnableWindow(1);
GetDlgItem(IDC_LV3_ICI)->EnableWindow(1);
GetDlgItem(IDC_LV3_PC)->EnableWindow(1);
GetDlgItem(IDC_LV3_RESIN)->EnableWindow(1);
GetDlgItem(IDC_LV3_RESO)->EnableWindow(1);
GetDlgItem(IDC_LV3_INST)->EnableWindow(1);
GetDlgItem(IDC_LV4_CU)->EnableWindow(0);
GetDlgItem(IDC_LV4_ICI)->EnableWindow(0);
GetDlgItem(IDC_LV4_PC)->EnableWindow(0);
GetDlgItem(IDC_LV4_RESIN)->EnableWindow(0);
GetDlgItem(IDC_LV4_RESO)->EnableWindow(0);
GetDlgItem(IDC_LV4_INST)->EnableWindow(0);
GetDlgItem(IDC_LVDUCTTYPE1)->EnableWindow(1);
GetDlgItem(IDC_LVDUCTTYPE2)->EnableWindow(1);
GetDlgItem(IDC_LVDUCTTYPE3)->EnableWindow(0);
GetDlgItem(IDC_LV_D_NO_12)->EnableWindow(1);
GetDlgItem(IDC_LV_D_NO_23)->EnableWindow(1);
GetDlgItem(IDC_LV_D_NO_34)->EnableWindow(0);
else
GetDlgItem(IDC_LV2_CU)->EnableWindow(1);
GetDlgItem(IDC_LV2_ICI)->EnableWindow(1);
GetDlgItem(IDC_LV2_PC)->EnableWindow(1);
GetDlgItem(IDC_LV2_RESIN)->EnableWindow(1);
GetDlgItem(IDC_LV2_RESO)->EnableWindow(1);
GetDlgItem(IDC_LV2_INST)->EnableWindow(1);
GetDlgItem(IDC_LV3_CU)->EnableWindow(1);
GetDlgItem(IDC_LV3_ICI)->EnableWindow(1);
GetDlgItem(IDC_LV3_PC)->EnableWindow(1);
GetDlgItem(IDC_LV3_RESIN)->EnableWindow(1);
GetDlgItem(IDC_LV3_RESO)->EnableWindow(1);
GetDlgItem(IDC_LV3_INST)->EnableWindow(1);
GetDlgItem(IDC_LV4_CU)->EnableWindow(1);
GetDlgItem(IDC_LV4_ICI)->EnableWindow(1);
GetDlgItem(IDC_LV4_PC)->EnableWindow(1);
GetDlgItem(IDC_LV4_RESIN)->EnableWindow(1);
GetDlgItem(IDC_LV4_RESO)->EnableWindow(1);
GetDlgItem(IDC_LV4_INST)->EnableWindow(1);
GetDlgItem(IDC_LVDUCTTYPE1)->EnableWindow(1);
GetDlgItem(IDC_LVDUCTTYPE2)->EnableWindow(1);
GetDlgItem(IDC_LVDUCTTYPE3)->EnableWindow(1);
GetDlgItem(IDC_LV_D_NO_12)->EnableWindow(1);
GetDlgItem(IDC_LV_D_NO_23)->EnableWindow(1);
GetDlgItem(IDC_LV_D_NO_34)->EnableWindow(1);
谢谢大家!
【讨论】:
以上是关于哪个是 MFC C++ 中单选组合框的事件处理程序的主要内容,如果未能解决你的问题,请参考以下文章