2017-09-14 13 views
1

コンボでアイテムを選択する際に別の文字列を表示したいというコンボボックスがあります。コンボボックスの項目を選択する際の書式付きテキストを表示

私のコンボボックスはドロップダウンコンボボックスです。

たとえば:私は私のコンボボックスで次のようにしています。


アレックス - Managerの

雨 - エンジニア

ミーラ - - 私はdiaplyしたいコンボボックス内の項目をOnSelectingシニアエンジニア


プロジェクトは

Shiney鉛名前、すなわちアレックス。

私は私の要件OnComboSelChange()と矢印キーイベントを達成することができていますが、コンボボックスの矢印キーを使用した後エンターキーを押すことで、それはコンボでフォーマットされたテキストが表示されないコード

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); 
} 

下回ってみましたボックス。

+3

PreTranslateMessageの使用を避け、希望するイベントをそこに捕らえてはいけませんが、SELEND_OK:詳細はこちら:https://msdn.microsoft.com/en-us/library/12h9x0ch(VS.80).aspx – flaviu2

+3

" ON_CBN_SELCHANGEコンボボックスのリストボックス内の選択は、ユーザがリストボックスをクリックするか、矢印キーを使用して選択を変更した結果、変更されようとしています。コンボボックスは、GetLBTextまたは他の同様の関数を使用してのみ取得できます。GetWindowTextは使用できません。 – flaviu2

+0

おかげさまでflaviu2。しかし、ユーザーがリストボックスをクリックするか、矢印キーを使用して選択を変更すると、書式付きテキストのみを表示する必要があります。 – user566

答えて

5

私は最も信頼性が高く、ソリューションを実装するのが簡単だと思うのは、subclassのコンボボックスの編集コントロールです。 WM_SETTEXTメッセージを傍受し、残りのチェーン(最終的に元のウィンドウproc)に転送する前に、好きなようにテキストを変更します。

OnInitDialog()におけるサブクラスprocをインストールします:処理CBN_SELCHANGEの私のoriginal solution、現在に

反し:

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); 
} 

注:

COMBOBOXINFO cbi{ sizeof(cbi) }; 
if(m_ctrlCombo.GetComboBoxInfo(&cbi)) 
{ 
    SetWindowSubclass(cbi.hwndItem, ComboEditSubClassProc, 0, 0); 
} 

ComboEditSubClassProc()はこのようになります。ソリューションはまた、コンボボックスのドロップダウンリストはReturnを押して閉じるか、終了します。

通知の順序に頼る必要がないので、一般的には信頼性が高いと思います。コンボボックスは最後にWM_SETTEXTを呼び出して、このメッセージが常に受信されるように編集コントロールの内容を変更する必要があります。

テキストは最初にコンボボックスによって変更され、その後、事実の後でしかコードによって変更されなかった元のソリューションと同じようにちらつきがありません。

関連する問題