模拟拼音输入法Dlg.cpp
上传用户:sztcmy
上传日期:2013-01-09
资源大小:154k
文件大小:11k
源码类别:

输入法编程

开发平台:

Visual C++

  1. // 模拟拼音输入法Dlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "模拟拼音输入法.h"
  5. #include "模拟拼音输入法Dlg.h"
  6. #include <fstream.h>
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CAboutDlg dialog used for App About
  14. class CAboutDlg : public CDialog
  15. {
  16. public:
  17. CAboutDlg();
  18. // Dialog Data
  19. //{{AFX_DATA(CAboutDlg)
  20. enum { IDD = IDD_ABOUTBOX };
  21. //}}AFX_DATA
  22. // ClassWizard generated virtual function overrides
  23. //{{AFX_VIRTUAL(CAboutDlg)
  24. protected:
  25. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  26. //}}AFX_VIRTUAL
  27. // Implementation
  28. protected:
  29. //{{AFX_MSG(CAboutDlg)
  30. //}}AFX_MSG
  31. DECLARE_MESSAGE_MAP()
  32. };
  33. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  34. {
  35. //{{AFX_DATA_INIT(CAboutDlg)
  36. //}}AFX_DATA_INIT
  37. }
  38. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  39. {
  40. CDialog::DoDataExchange(pDX);
  41. //{{AFX_DATA_MAP(CAboutDlg)
  42. //}}AFX_DATA_MAP
  43. }
  44. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  45. //{{AFX_MSG_MAP(CAboutDlg)
  46. // No message handlers
  47. //}}AFX_MSG_MAP
  48. END_MESSAGE_MAP()
  49. /////////////////////////////////////////////////////////////////////////////
  50. // CMyDlg dialog
  51. CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
  52. : CDialog(CMyDlg::IDD, pParent)
  53. {
  54. //{{AFX_DATA_INIT(CMyDlg)
  55. // NOTE: the ClassWizard will add member initialization here
  56. flag=0;
  57. page=0;
  58. length=0;
  59. Num=0;
  60. strstr1="";
  61. strstr2="";
  62. m_text  = _T("");
  63. m_hanzi = _T("");
  64. m_pinyin= _T("");
  65.     //}}AFX_DATA_INIT
  66. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  67. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  68. }
  69. void CMyDlg::DoDataExchange(CDataExchange* pDX)
  70. {
  71. CDialog::DoDataExchange(pDX);
  72. //{{AFX_DATA_MAP(CMyDlg)
  73. // NOTE: the ClassWizard will add DDX and DDV calls here
  74. DDX_Text(pDX, IDC_EDITTEXT, m_text);
  75. DDX_Text(pDX, IDC_DISPLAYHZ, m_hanzi);
  76. DDX_Text(pDX, IDC_INPUTPY, m_pinyin);
  77. //}}AFX_DATA_MAP
  78. }
  79. BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
  80. //{{AFX_MSG_MAP(CMyDlg)
  81. ON_WM_SYSCOMMAND()
  82. ON_WM_PAINT()
  83. ON_WM_QUERYDRAGICON()
  84. ON_EN_CHANGE(IDC_INPUTPY, OnChangeInputpy)
  85. ON_WM_KEYDOWN()
  86. ON_BN_CLICKED(IDEXIT, OnExit)
  87. ON_BN_CLICKED(IDC_ABOUT, OnAbout)
  88. //}}AFX_MSG_MAP
  89. END_MESSAGE_MAP()
  90. /////////////////////////////////////////////////////////////////////////////
  91. // CMyDlg message handlers
  92. BOOL CMyDlg::OnInitDialog()
  93. {
  94. CDialog::OnInitDialog();
  95. // Add "About..." menu item to system menu.
  96. // IDM_ABOUTBOX must be in the system command range.
  97. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  98. ASSERT(IDM_ABOUTBOX < 0xF000);
  99. CMenu* pSysMenu = GetSystemMenu(FALSE);
  100. if (pSysMenu != NULL)
  101. {
  102. CString strAboutMenu;
  103. strAboutMenu.LoadString(IDS_ABOUTBOX);
  104. if (!strAboutMenu.IsEmpty())
  105. {
  106. pSysMenu->AppendMenu(MF_SEPARATOR);
  107. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  108. }
  109. }
  110. // Set the icon for this dialog.  The framework does this automatically
  111. //  when the application's main window is not a dialog
  112. SetIcon(m_hIcon, TRUE); // Set big icon
  113. SetIcon(m_hIcon, FALSE); // Set small icon
  114. // TODO: Add extra initialization here
  115. return TRUE;  // return TRUE  unless you set the focus to a control
  116. }
  117. void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam)
  118. {
  119. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  120. {
  121. CAboutDlg dlgAbout;
  122. dlgAbout.DoModal();
  123. }
  124. else
  125. {
  126. CDialog::OnSysCommand(nID, lParam);
  127. }
  128. }
  129. // If you add a minimize button to your dialog, you will need the code below
  130. //  to draw the icon.  For MFC applications using the document/view model,
  131. //  this is automatically done for you by the framework.
  132. void CMyDlg::OnPaint() 
  133. {
  134. if (IsIconic())
  135. {
  136. CPaintDC dc(this); // device context for painting
  137. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  138. // Center icon in client rectangle
  139. int cxIcon = GetSystemMetrics(SM_CXICON);
  140. int cyIcon = GetSystemMetrics(SM_CYICON);
  141. CRect rect;
  142. GetClientRect(&rect);
  143. int x = (rect.Width() - cxIcon + 1) / 2;
  144. int y = (rect.Height() - cyIcon + 1) / 2;
  145. // Draw the icon
  146. dc.DrawIcon(x, y, m_hIcon);
  147. }
  148. else
  149. {
  150. CDialog::OnPaint();
  151. ReadFile();
  152. }
  153. }
  154. // The system calls this to obtain the cursor to display while the user drags
  155. //  the minimized window.
  156. HCURSOR CMyDlg::OnQueryDragIcon()
  157. {
  158. return (HCURSOR) m_hIcon;
  159. }
  160. /*****************把汉字内码表读入内存中************************/
  161. void CMyDlg::ReadFile()             
  162. {
  163. ifstream inf("汉字内码表.txt",ios::in);    //打开汉字内码表
  164. if(!inf)
  165. {
  166. AfxMessageBox("Can not open the file 汉字内码表.txt ");
  167. return;
  168. }
  169. CString str1,str2,str;
  170.     char ch[3002];
  171. inf.getline(ch,3000,'#');                  //一行一行地读取文件
  172. while(!inf.eof())                          //文件未读完
  173. {
  174. str="";
  175. str=ch;                               //把读取的内容赋值给str
  176. str+='#';                             //以分号“#”表示结束
  177. int i=0;
  178. str1="";
  179. str2="";
  180. while((str[i]==' ')||(str[i]=='n')||(str[i]=='r'))  //抛弃空格符以及回车符
  181. i++;
  182. while(str[i]>='a'&&str[i]<='z')       //接收拼音,存入变量str1中
  183. {
  184. str1+=str[i];
  185. i++;
  186. }
  187. while(str[i]!='#')                    //接收汉字,存入变量str2中
  188. {
  189. while((str[i]==' ')||(str[i]=='n')||(str[i]=='r'))  //抛弃空格符以及回车符
  190. i++;
  191. if(str[i]=='#')
  192. break;
  193. else
  194. {
  195. str2+=str[i];
  196. i++;
  197. }
  198. }
  199. m_Map[str1]=str2;                     //把所接收的拼音跟汉字通过映射类的函数
  200.                                       //建立一一对应的映射关系                                              
  201. inf.getline(ch,3000,'#');             //读取下一行字符
  202. }
  203. }
  204. /*********************响应输入拼音******************************/
  205. void CMyDlg::OnChangeInputpy() 
  206. {
  207. // TODO: If this is a RICHEDIT control, the control will not
  208. // send this notification unless you override the CDialog::OnInitDialog()
  209. // function and call CRichEditCtrl().SetEventMask()
  210. // with the ENM_CHANGE flag ORed into the mask.
  211. // TODO: Add your control notification handler code here
  212. UpdateData(TRUE);                   //接收用户输入
  213. CString str1;
  214. strstr2="";
  215. flag=0;
  216. m_hanzi=""; 
  217.     if(m_Map.Lookup(m_pinyin,strstr2))   //输入拼音找到匹配的汉字时的处理
  218. {                                 //调用Lookup()函数进行散列查找,
  219.                                         //m_Input中存放匹配的拼音,找到的对应的汉字存放在str中
  220. strstr1=m_pinyin;                
  221. int k=0;
  222. page=0;                         //翻页数初始化为0
  223. flag=1;                         //标记找到对应的汉字
  224. m_hanzi="";                      //清空以前的内容
  225. length=strstr2.GetLength();     //得到串的长度 
  226. for(int i=0;i<length;i++)       //把找到的汉字存放到一个数组中
  227. {
  228. MyArray[k].ch[0]=strstr2[i];
  229. MyArray[k].ch[1]=strstr2[++i];
  230. k++;
  231. }
  232. DisplayHanzi();                       //显示第一页的汉字
  233. }
  234. else                                //输入的拼音找不到匹配的汉字时的处理
  235. {
  236. strstr1=strstr2="";             //赋空
  237. m_hanzi="";
  238. flag=0;                         //标记找不到对应的汉字
  239. }
  240. UpdateData(FALSE);
  241. }
  242. /*************显示输入的拼音对应的汉字**************/
  243. void CMyDlg::DisplayHanzi()            
  244. {
  245. int k=1;
  246. CString str1;
  247. m_hanzi="";                               //清空以前的内容
  248. for(int i=page*10;i<page*10+10;i++)      //将数组中的汉字保存到字符串m_hanzi中
  249. {
  250. k=k%10;
  251. str1.Format("%d",k);                 //为汉字前面加上编号
  252. m_hanzi+=str1;
  253. m_hanzi+=MyArray[i].ch[0];            //接收汉字
  254. m_hanzi+=MyArray[i].ch[1];
  255. m_hanzi+="  ";                         //汉字之间用空格隔开
  256. k++;
  257. if((i+1)==(length/2))
  258. break;
  259. }
  260. UpdateData(FALSE);
  261. }
  262. /*********************显示结果**************************/
  263. void CMyDlg::ShowText()     
  264. {
  265. if(page*10+Num+1>length/2)            //如果所选的编号没有字,则返回
  266. return;
  267. m_text+=MyArray[page*10+Num].ch[0];
  268. m_text+=MyArray[page*10+Num].ch[1]; //接收汉字
  269. m_pinyin="";                           //清空提示
  270. m_hanzi="";
  271. UpdateData(FALSE);
  272. ChangeOrder();                        //改变汉字的先后顺序
  273. }
  274. BOOL CMyDlg::PreTranslateMessage(MSG* pMsg) 
  275. {
  276. // TODO: Add your specialized code here and/or call the base class
  277. if(pMsg->message == WM_KEYDOWN) 
  278.      { 
  279. if(pMsg->wParam == VK_RETURN)                 //截取键盘中的回车键
  280. UINT nID = GetFocus()->GetDlgCtrlID(); 
  281. switch(nID) 
  282. case IDC_INPUTPY: 
  283. m_text+=m_pinyin;                    //按回车键时则输入拼音
  284. m_pinyin="";                           //并清提示符
  285. m_hanzi="";
  286. UpdateData(FALSE);
  287. return TRUE; 
  288. default: 
  289. return FALSE; 
  290. if(pMsg->wParam==VK_NEXT||pMsg->wParam==VK_ADD) //按PageDown或'+',向后翻页
  291. {
  292. UINT nID2 = GetFocus()->GetDlgCtrlID();
  293. switch(nID2)
  294. {
  295. case IDC_INPUTPY:
  296. if((flag==1)&&(m_pinyin!=""))
  297. {
  298. if((page+1)*10>length/2) //不能再翻页
  299. return TRUE;
  300. else
  301. {
  302. page++;              //翻页变量加一
  303. DisplayHanzi();
  304. }
  305. }
  306. return TRUE;
  307. default:
  308. return FALSE;
  309. }
  310. }
  311. if(pMsg->wParam==VK_PRIOR||pMsg->wParam==VK_SUBTRACT) //按PageUp或'-',向前翻页
  312. {
  313. UINT nID2 = GetFocus()->GetDlgCtrlID();
  314. switch(nID2)
  315. {
  316. case IDC_INPUTPY:
  317. if((flag==1)&&(m_pinyin!=""))
  318. {
  319. if(page==0)       //不能再翻页
  320. return TRUE;
  321. else
  322. {
  323. page--;       //翻页变量减一
  324. DisplayHanzi();
  325. }
  326. }
  327. return TRUE;
  328. default:
  329. return FALSE;
  330. }
  331. }
  332. if( ((pMsg->wParam >= VK_NUMPAD0)&&(pMsg->wParam <= VK_NUMPAD9))  //选字的处理
  333. ||((pMsg->wParam >= _T('0'))&&(pMsg->wParam <= _T('9')))||(pMsg->wParam==_T(' ')))
  334. {
  335. UINT nID2 = GetFocus()->GetDlgCtrlID();
  336. switch(nID2)
  337. {
  338. case IDC_INPUTPY:
  339. UpdateData(FALSE);
  340. if((flag==1)&&(m_pinyin!=""))
  341. {
  342. if((pMsg->wParam>=VK_NUMPAD1)&&(pMsg->wParam<=VK_NUMPAD9))
  343. Num=pMsg->wParam-VK_NUMPAD1;   //输入数字键时
  344. else if(pMsg->wParam==_T(' '))     //输入空格时
  345. Num=0;
  346. else if(pMsg->wParam==_T('0')||pMsg->wParam>=VK_NUMPAD0)   //输入0时
  347. Num=9;
  348. else
  349. Num=pMsg->wParam-_T('1');      //输入1~9时
  350. ShowText();                      //显示所选的字
  351. UpdateData(FALSE);
  352. }
  353. return TRUE;
  354. default:
  355. return FALSE;
  356. }
  357. }
  358. return CDialog::PreTranslateMessage(pMsg);
  359. }
  360. void CMyDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  361. {
  362. // TODO: Add your message handler code here and/or call default
  363. CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
  364. }
  365. /*****改变汉字次序的函数,将上次所选的汉字在下次显示中排在前面*****/
  366. void CMyDlg::ChangeOrder() 
  367. {
  368. CString str1="";
  369. str1+=MyArray[page*10+Num].ch[0];
  370.     str1+=MyArray[page*10+Num].ch[1];      //保存用户刚输入的汉字
  371. strstr2.Delete((page*10+Num)*2,2);     //在原字符串中删除用户刚输入的汉字
  372. strstr2.Insert(0,str1);                //把用户刚输入的汉字放在前面
  373. m_Map.SetAt(strstr1,strstr2);          //重新修改映射中关键字对应的元素
  374. }
  375. /********************响应关于按钮***************************/
  376. void CMyDlg::OnAbout()
  377. {
  378. CAboutDlg  Dlg;
  379. Dlg.DoModal();;
  380. }
  381. /*********************退出程序******************************/
  382. void CMyDlg::OnExit() 
  383. {
  384. // TODO: Add your control notification handler code here
  385. CDialog::OnOK();
  386. }