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 once16: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: };