原文:
发现原程序有一个问题,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: //
12: // yinxf 2010/07/13 Build
13: //
14: //*************************************************************************
15: #pragma once
16:
17: class CAutoComboBox
18: : public CWindowImpl
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: CContainedWindowTm_Edit; // CContainedWindow包容器窗口, 在控件的父窗口中处理控件的消息
104: };