我有一个组合框,我想在Combo中选择一个项目时显示不同的字符串.
我的组合框是一个下拉组合框.
例如:我在我的组合框中有以下内容.
亚历克斯 - 经理
雨 - 项目负责人
Shiney - 工程师
Meera - 高级工程师
On在Combobox中选择一个项目我想只是名字,即Alex.
我试过下面的代码
struct details{
CString name;
CString des;
};
BOOL CComboTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
details d1;
d1.name = _T("alex");
d1.des =_T("manager");
m_vec.push_back(d1);
details d2;
d2.name = _T("Rain");
d2.des =_T("Engineer");
m_vec.push_back(d2);
// TODO: Add extra initialization here
for(int i=0;i<m_vec.size();i++)
{
m_ctrlCombo.AddString(m_vec[i].name+m_vec[i].des);
m_ctrlCombo.SetItemData(i,(DWORD_PTR)&m_vec[i]);
}
m_ctrlCombo.SelectString(-1,m_vec[0].name);
m_ctrlCombo.SetWindowText(m_vec[0].name);
return TRUE; // return TRUE unless you set the focus to a control
}
void CComboTestDlg::OnCbnSelchangeCombo1()
{
int nItem = m_ctrlCombo.GetCurSel();
details* det = (details*)m_ctrlCombo.GetItemData(nItem);
PostMessage(SETCOMBOTEXT,IDC_COMBO1,(LPARAM)(LPCTSTR)det->name);
}
BOOL CComboTestDlg::PreTranslateMessage(MSG* pMsg)
{
MSG msg1=*pMsg;//I am loosing the value after checking ..so storing temp.
MSG msg;
CopyMemory(&msg, pMsg, sizeof(MSG));
HWND hWndParent = ::GetParent(msg.hwnd);
while (hWndParent && hWndParent != this->m_hWnd)
{
msg.hwnd = hWndParent;
hWndParent = ::GetParent(hWndParent);
}
if (pMsg->message==SETCOMBOTEXT && (pMsg->wParam == IDC_COMBO1))
SetDlgItemText(IDC_COMBO1, (LPCTSTR)pMsg->lParam);
if(pMsg->message==WM_KEYDOWN)
{
if(pMsg->wParam==VK_RETURN && msg.hwnd ==m_ctrlCombo.m_hWnd )
{
OnCbnSelchangeCombo1();
}
}
return CDialog::PreTranslateMessage(pMsg);
}
Run Code Online (Sandbox Code Playgroud)
我能够实现我的要求OnComboSelChange()和箭头键事件,但在组合框中使用箭头键后按Enter键,它没有在组合框中显示格式化文本.
我认为最可靠和易于实现的解决方案是将组合框的编辑控件子类化.拦截WM_SETTEXT消息并根据需要更改文本,然后将其转发到链的其余部分(最后是原始窗口proc).
在以下位置安装子类proc OnInitDialog():
COMBOBOXINFO cbi{ sizeof(cbi) };
if( m_ctrlCombo.GetComboBoxInfo( &cbi ) )
{
SetWindowSubclass( cbi.hwndItem, ComboEditSubClassProc, 0, 0 );
}
Run Code Online (Sandbox Code Playgroud)
ComboEditSubClassProc() 可能看起来像这样:
LRESULT CALLBACK ComboEditSubClassProc( HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData )
{
switch( uMsg )
{
case WM_SETTEXT:
{
CString text = reinterpret_cast<LPCTSTR>( lParam );
// Extract the name (everything before "-").
CString name = text.SpanExcluding( _T("-") );
name.TrimRight();
// Forward the modified text to any other sub class procs, aswell
// as the original window proc at the end of the chain.
return DefSubclassProc( hWnd, uMsg, 0, reinterpret_cast<LPARAM>( name.GetString() ) );
}
case WM_NCDESTROY:
{
// We must remove our subclass before the subclassed window gets destroyed.
// This message is our last chance to do that.
RemoveWindowSubclass( hWnd, ComboEditSubClassProc, uIdSubclass );
break;
}
}
return DefSubclassProc( hWnd, uMsg, wParam, lParam );
}
Run Code Online (Sandbox Code Playgroud)
笔记:
与我原来的处理解决方案相反,CBN_SELCHANGE如果通过按下Return或关闭组合框下拉列表,当前解决方案也可以正常工作.
我认为它通常更可靠,因为我们不必依赖通知的顺序.组合框最终必须调用WM_SETTEXT以更改编辑控件的内容,以便始终接收此消息.
原始解决方案中也没有闪烁,其中文本首先由组合框更改,然后仅在事实之后由我们的代码修改.
| 归档时间: |
|
| 查看次数: |
406 次 |
| 最近记录: |