类似股软(大智慧)之键盘精灵的 vc2008--UNICODE 环境实现

键盘精灵是指,当按下键盘上任意一个数字、字母或符号的时候,都会弹出“键盘精灵”,其类似于股票软件(如大智慧)中的。可以在这里面输入中英文和数字搜索您想要的东西。可以通过输入代码、名称或名称的汉语拼音首字母来搜索对应的商品(股票、基金、债券、指数等),按enter键进入相关页面。

个人理解,实现键盘精灵的几个关键点是CEdit和CListBox两个控件的关联,CEdit接收键盘输入,两者对enter键和上下方向键的 响应并显示相关页面,ClistBox对双击鼠标左键的响应并显示相关页面,以及何时显示和隐藏这两个控件。 

下边是一些相关代码,是在SDI中手动添加这两个控件的,如果是基于CDialog的话,在消息响应函数和设置控件属性时操作就比较简单了。

1. 在view类.h文件中添加下面代码:

  1.     CEdit         m_wndEditStock;    //EDIT控件 键盘精灵的东东  
  2.     CListBox      m_wndListBoxStock; //LIST控件  键盘精灵的东东  
  3.   
  4. afx_msg void OnChangeEditStockcode(); // 响应CEdit内容改变  
  5. afx_msg void OnDblclkListStockcode(); // 响应CListBox 双击  

2. 在view类.cpp文件的消息映射里添加下面的代码:

  1. ON_EN_CHANGE(IDE_EDIT_CODE, OnChangeEditStockcode)  
  2. ON_LBN_DBLCLK(IDL_LIST_CODE_NAME, OnDblclkListStockcode)  

3. 在view重载的OnInitialUpdate()函数中初始化控件,其中的rc和rc1是两个CRect,其位置自己可以随意定:

  1. m_wndEditStock.Create(  
  2.         WS_CHILD  
  3.         |WS_VISIBLE  
  4.         |WS_BORDER  
  5.         |WS_THICKFRAME  
  6.         |WS_TABSTOP  
  7.         |WS_CLIPCHILDREN  
  8.         |ES_UPPERCASE,  
  9.         rc, this, IDE_EDIT_CODE)  
  10.     m_wndListBoxStock.Create(  
  11.         WS_CHILD  
  12.         |WS_VISIBLE  
  13.         |LBS_HASSTRINGS   
  14.         |LBS_STANDARD  
  15.         |WS_THICKFRAME  
  16.         |LBS_NOINTEGRALHEIGHT  
  17.         |LBS_NOTIFY,   
  18.         rc1,  this, IDL_LIST_CODE_NAME)  
  19.     m_wndEditStock.ShowWindow(SW_HIDE);  
  20.     m_wndListBoxStock.BringWindowToTop();   
  21.     m_wndListBoxStock.ShowWindow(SW_HIDE);  

4. view的cpp文件中添加消息响应函数 OnChangeEditStockcode和 OnDblclkListStockcode的实现部分。其中m_RelationArray是一个CArray<CString, CString&>派生类,这也是键盘精灵搜索的源资源 ,这个可以随意设计!  

  1. // OnChangeEditStockcode函数  
  2. {  
  3.     BOOL bFind = FALSE;  
  4.     CString szText;  
  5.     CString szCode;  
  6.     CString szName;  
  7.     CString szPyjc;  
  8.     CString szItem;  
  9.     long lCount = 0;  
  10.   
  11.     m_wndEditStock.GetWindowText(szText);  
  12.     m_wndListBoxStock.ResetContent();  
  13.   
  14.     int nSize = m_RelationArray.GetSize();  
  15.     if (szText == _T(""))  
  16.     {  
  17.         m_wndListBoxStock.ShowWindow(SW_HIDE); // Edit为空时,隐藏listbox  
  18.         return;  
  19.     }  
  20.     if (szText.GetLength() > 10)  
  21.     {  
  22.         szText = szText.Left(10);  
  23.         m_wndEditStock.SetWindowText(szText);  
  24.         m_wndListBoxStock.ShowWindow(SW_HIDE); // SW_HIDE  
  25.         return;  
  26.     }  
  27.   
  28.     TCHAR ch = szText.GetAt(0);  
  29.     if (ch <= '9' && ch >= '0')  
  30.     {  
  31.         for (long i = 0; i < nSize; i++)  
  32.         {  
  33.             szCode = (m_RelationArray.GetAt(i)).CODE;  
  34.             if (szStockCode.Find(szText) == 0)  
  35.             {  
  36.                 szName = (m_RelationArray.GetAt(i)).NAME;  
  37.                 szItem =  szCode + _T("  ") + szName;     
  38.                 m_wndListBoxStock.AddString(szItem);  
  39.             }  
  40.         }  
  41.     }  
  42.     else  
  43.     {  
  44.         m_wndListBoxStock.ShowWindow(SW_HIDE);  
  45.         return;  
  46.     }  
  47.   
  48.     lCount = m_wndListBoxStock.GetCount();  
  49.     if (lCount <= 0)  
  50.     {  
  51.         m_wndListBoxStock.ShowWindow(SW_HIDE);  
  52.     }  
  53.     else  
  54.     {  
  55.         m_wndListBoxStock.ShowWindow(SW_SHOW);  
  56.         m_wndListBoxStock.SetCurSel(0);  
  57.     }  
  58. }  
  59.   
  60. // OnDblclkListStockcode函数  
  61. {  
  62.     CString szText;  
  63.     CString szName;  
  64.     CString szCode;  
  65.     m_wndListBoxStock.ShowWindow( SW_HIDE );  
  66.     m_wndEditStock.ShowWindow( SW_HIDE );  
  67.     long lIndex = m_wndListBoxStock.GetCurSel();  
  68.     if ( lIndex >= 0 )  
  69.     {  
  70.         m_wndListBoxStock.GetText( lIndex, szText );  
  71.         // do something with szText  
  72.         ... ...  
  73.     }  
  74. }  

5. view重载Onchar消息函数,在里面添加下面的代码,用于在CEdit中显示键盘输入的字符,这里只是响应了数字键和退格键。

  1. if  (((nChar >= '0' && nChar <= '9')||(nChar == VK_BACK)))  
  2.     {  
  3.         CWnd* pwnd = GetDlgItem(IDE_EDIT_CODE);  
  4.         if (pwnd !=NULL)  
  5.         {  
  6.             pwnd->SetFocus(); // 否则会仅仅显示一个字符  
  7.             CString str,temp;  
  8.             temp.Format(_T("%c"),nChar);  
  9.             pwnd->BringWindowToTop();  
  10.             pwnd->ShowWindow(SW_SHOW);  
  11.             pwnd->SetWindowText(temp);  
  12.             pwnd->GetWindowText(str);  
  13.             int length = str.GetLength();  
  14.             m_wndEditStock.SetSel(length,length);   
  15.         }  
  16.     }  
  17.     else  
  18.         this->SetFocus();  

6. 在view重载的PreTranslateMessage中响应return键,其中在用上下方向键选择CListBox的item后响应return。

  1. if (pMsg->wParam == VK_RETURN)  
  2. {  
  3.     HWND hWnd = ::GetFocus();  
  4.     if (GetDlgItem(IDE_EDIT_CODE)->GetSafeHwnd() == hWnd)  
  5.     {  
  6.         CString str;  
  7.         GetDlgItem(IDE_EDIT_CODE)->GetWindowText(str);  
  8.         //... ... 用得到的str做些事情   
  9.         GetDlgItem(IDE_EDIT_CODE)->SetWindowText(_T("")); // 设置CEdit为空,为下次接收键盘输入  
  10.         GetDlgItem(IDE_EDIT_CODE)->ShowWindow(SW_HIDE);  
  11.         this->SetFocus();  
  12.     }  
  13.     // 响应用上下键滚动 并回车选择  
  14.     if (GetDlgItem(IDL_LIST_CODE_NAME)->GetSafeHwnd() == hWnd)  
  15.     {  
  16.         CString szText,szCode;  
  17.         long lIndex = m_wndListBoxStock.GetCurSel();  
  18.         if ( lIndex >= 0 )  
  19.         {  
  20.             m_wndListBoxStock.GetText( lIndex, szText );  
  21.             // 用得到的szText做些事情  
  22.         }  
  23.         m_wndListBoxStock.ShowWindow(SW_HIDE);  
  24.         m_wndEditStock.ShowWindow(SW_HIDE);  
  25.     }  
  26. }  

以上代码参考了http://www.pudn.com/downloads305/sourcecode/app/detail1357832.html中的代码,在此向作者致意!

原文地址:https://www.cnblogs.com/lxshanye/p/3216252.html