Auto Completion ComboBox for WTL

原文:http://www.codeproject.com/Articles/4785/Auto-Completion-ComboBox-for-WTL

发现原程序有一个问题,ComboBox本身无法截获PreTranslateMessage。

 

为了要获取键盘按下的消息,可以从ComboBox里面的Edit下手,获取Edit的WM_KEYDOWN消息,再交给Edit的父窗口ComboBox处理。代码:

  1: //*************************************************************************
  2: //
  3: // Copyright (C), 2009-2010, Handy Information Co.,Ltd,All Rights Reserved
  4: //
  5: // FileName:      AutoComboBox.h  
  6: // Author:        yinxf
  7: // Date:          2012/2012/3
  8: // Description:   自动完成ComboBox
  9: // Function List:  
 10: // History:              
 11: //          <author>        <time>           <desc>        
 12: //            yinxf          2010/07/13        Build
 13: //
 14: //*************************************************************************
 15: #pragma once
 16: 
 17: class CAutoComboBox
 18:     : public CWindowImpl<CAutoComboBox, CComboBox>
 19: {
 20: public:
 21:     DECLARE_WND_SUPERCLASS(_T("AutoComboBox"), GetWndClassName())
 22: 
 23:     CAutoComboBox(void)
 24:         : m_Edit(this, 1)// 调用CContainedWindowT构造函数,告诉CEdit处理ALT_MSG_MAP的1小节
 25:         , m_bAutoComplete(TRUE)
 26:     {
 27:     }
 28:     ~CAutoComboBox(void){}
 29: 
 30: protected:
 31:     BEGIN_MSG_MAP(CAutoComboBox)
 32:         REFLECTED_COMMAND_CODE_HANDLER_EX(CBN_EDITUPDATE, OnEditUpdate) 
 33:         DEFAULT_REFLECTION_HANDLER()
 34:     ALT_MSG_MAP(1)      // 添加ALT_MSG_MAP消息处理
 35:         MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
 36:     END_MSG_MAP()
 37:     
 38:     BOOL SubclassWindow(HWND hWnd)
 39:     {
 40:         POINT pt;
 41:         pt.x = 3; 
 42:         pt.y = 3; 
 43:         HWND hwndEdit = ::ChildWindowFromPoint(hWnd , pt); 
 44:         m_Edit.SubclassWindow( hwndEdit );  // 将变量与CEdit控件关联
 45: 
 46:         BOOL bRet = __super::SubclassWindow(hWnd);
 47:         return bRet;
 48:     }
 49: 
 50:     // CBN_EDITUPDATE 输入框中内容被更新
 51:     LRESULT OnEditUpdate(UINT uNotifyCode, int nID, CWindow wndCtl)
 52:     {
 53:         if (!m_bAutoComplete) 
 54:             return 0;
 55: 
 56:         CString str;
 57:         GetWindowText(str);
 58:         int nLength = str.GetLength();
 59: 
 60:         // Currently selected range
 61:         DWORD dwCurSel = GetEditSel();
 62:         WORD dStart = LOWORD(dwCurSel); // 编辑控件中选中的字符串中起始位置
 63:         WORD dEnd   = HIWORD(dwCurSel); // 紧接着选中的字符串的第一个字符的位置
 64: 
 65:         // Search for, and select in, and string in the combo box that is prefixed
 66:         // by the text in the edit box
 67:         // 从列表开始查找并选中包含指定字符串的行
 68:         if ( SelectString(-1, str) == CB_ERR )
 69:         {
 70:             SetWindowText(str);        // No text selected, so restore what was there before
 71:             if (dwCurSel != CB_ERR)
 72:                 SetEditSel(dStart, dEnd);    //restore cursor postion
 73:         }
 74: 
 75:         // Set the text selection as the additional text that we have added
 76:         if ( dEnd < nLength && dwCurSel != CB_ERR )
 77:             SetEditSel(dStart, dEnd);
 78:         else
 79:             SetEditSel(nLength, -1);
 80: 
 81:         SetMsgHandled(FALSE);
 82:         return 0;
 83:     }
 84: 
 85:     // Need to check for backspace/delete. These will modify the text in
 86:     // the edit box, causing the auto complete to just add back the text
 87:     // the user has just tried to delete. 
 88:     LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
 89:     {
 90:         m_bAutoComplete = TRUE;
 91: 
 92:         if ( wParam == VK_DELETE || wParam == VK_BACK )
 93:         {
 94:             m_bAutoComplete = FALSE;
 95:         }
 96: 
 97:         bHandled = FALSE;
 98:         return 0;
 99:     }
100: 
101: protected:
102:     BOOL m_bAutoComplete;
103:     CContainedWindowT<CEdit> m_Edit;        // CContainedWindow包容器窗口, 在控件的父窗口中处理控件的消息
104: };
posted @ 2012-07-04 08:22  HoneyComb  阅读(873)  评论(0编辑  收藏  举报