Chcand.pas
上传用户:wen198501
上传日期:2013-04-01
资源大小:335k
文件大小:6k
源码类别:

输入法编程

开发平台:

Delphi

  1.  {******************************************************}
  2.  {                                                      }
  3.  {    Copyright (c) 1990-1999 Microsoft Corporation     }
  4.  {                                                      }
  5.  {    Module Name:  Chcand.c ->>  Chcand.pas            }
  6.  {                                                      }
  7.  {    Translator:  Liu_mazi@126.com, 2005-11-14         }
  8.  {                                                      }
  9.  {******************************************************}
  10. unit Chcand;
  11. {$I Define.Inc}
  12. interface
  13. uses Windows, ImmDev, ImeDefs;
  14. procedure SelectOneCand(lpIMC: PInputContext; lpCompStr: PCompositionString;
  15.   lpImcP: PPrivContext; lpCandList: PCandidateList); // 选中一个Candidate
  16. procedure CandEscapeKey(lpIMC: PInputContext; lpImcP: PPrivContext);  // Candidate取消处理
  17. procedure ChooseCand(wCharCode: Word; lpIMC: PInputContext;
  18.   lpCandInfo: PCandidateInfo; lpImcP: PPrivContext); // Candidate按键处理
  19. implementation
  20. uses DDIS, Compose;
  21.   // 选中一个Candidate
  22. procedure SelectOneCand(lpIMC: PInputContext; lpCompStr: PCompositionString; lpImcP: PPrivContext; lpCandList: PCandidateList);
  23. begin
  24.   if (lpCompStr = nil) or (lpImcP = nil) then begin MessageBeep($FFFFFFFF); Exit; end;
  25.   InitCompStr(lpCompStr);
  26.   // calculate result string length
  27.   lpCompStr.dwResultStrLen := lStrLen(PChar(DWord(lpCandList) + lpCandList.dwOffset[lpCandList.dwSelection]));
  28.   // the result string = the selected candidate
  29.   lStrCpy(
  30.     PChar(DWord(lpCompStr) + lpCompStr.dwResultStrOffset),
  31.     PChar(DWord(lpCandList) + lpCandList.dwOffset[lpCandList.dwSelection])
  32.          );
  33.   // tell application, there is a reslut string
  34.   lpImcP.fdwImeMsg := lpImcP.fdwImeMsg or MSG_COMPOSITION;
  35.   lpImcP.dwCompChar := 0;
  36.   lpImcP.fdwGcsFlag := lpImcP.fdwGcsFlag or (GCS_COMPREAD or GCS_COMP or GCS_CURSORPOS or GCS_DELTASTART or GCS_RESULTREAD or GCS_RESULT);
  37.   if ((lpImcP.fdwImeMsg and MSG_ALREADY_OPEN) <> 0) then
  38.     lpImcP.fdwImeMsg := (lpImcP.fdwImeMsg or MSG_CLOSE_CANDIDATE) and (not MSG_OPEN_CANDIDATE);
  39.   // no candidate now, the right candidate string already be finalized
  40.   lpCandList.dwCount := 0;
  41.   lpImcP.iImeState := CST_INIT;
  42.   // init Engine private data, **
  43.   PDWord(@lpImcP.bSeq)^ := 0;
  44. end;
  45.   // Candidate取消处理
  46. procedure CandEscapeKey(lpIMC: PInputContext; lpImcP: PPrivContext);
  47. var
  48.   lpCompStr: PCompositionString;
  49.   lpGuideLine: PGuideLine;
  50. begin
  51.   // clean all candidate information
  52.   if ((lpImcP.fdwImeMsg and MSG_ALREADY_OPEN) <> 0) then
  53.   begin
  54.     ClearCand(lpIMC);
  55.     lpImcP.fdwImeMsg := (lpImcP.fdwImeMsg or MSG_CLOSE_CANDIDATE) and (not MSG_OPEN_CANDIDATE);
  56.   end;
  57.   // if it start composition, we need to clean composition
  58.   if ((lpImcP.fdwImeMsg and MSG_ALREADY_START) = 0) then Exit;
  59.   lpCompStr := ImmLockIMCC(lpIMC.hCompStr);
  60.   if (lpCompStr = nil) then Exit;
  61.   lpGuideLine := ImmLockIMCC(lpIMC.hGuideLine); // **
  62.   if (lpGuideLine = nil) then Exit;
  63.   CompEscapeKey(lpIMC, lpCompStr, lpGuideLine, lpImcP);
  64.   ImmUnlockIMCC(lpIMC.hGuideLine);
  65.   ImmUnlockIMCC(lpIMC.hCompStr);
  66. end;
  67.   // Candidate按键处理
  68. procedure ChooseCand(wCharCode: Word; lpIMC: PInputContext; lpCandInfo: PCandidateInfo; lpImcP: PPrivContext);
  69. var
  70.   lpCandList: PCandidateList;
  71.   lpCompStr: PCompositionString;
  72.   dwSelCand: DWord;
  73. begin
  74.   if (wCharCode = VK_ESCAPE) then // 取消
  75.   begin
  76.     CandEscapeKey(lpIMC, lpImcP);
  77.     Exit;
  78.   end;
  79.   if (lpCandInfo = nil) then
  80.   begin
  81.     MessageBeep($FFFFFFFF);
  82.     Exit;
  83.   end;
  84.   lpCandList := PCandidateList(DWord(lpCandInfo) + lpCandInfo.dwOffset[0]);
  85.   if (wCharCode = Ord(' ')) then       // 循环翻页
  86.   begin
  87.     Inc(lpCandList.dwSelection, lpCandList.dwPageSize);
  88.     if (lpCandList.dwSelection >= lpCandList.dwCount) then
  89.     begin
  90.       lpCandList.dwSelection := 0;
  91.       MessageBeep($FFFFFFFF);
  92.     end;
  93.     lpImcP.fdwImeMsg := lpImcP.fdwImeMsg or MSG_CHANGE_CANDIDATE;
  94.     Exit;
  95.   end;
  96.   if (wCharCode = Ord('=')) then       // 向下翻页
  97.   begin
  98.     if (lpCandList.dwSelection >= ((IME_MAXCAND - 1) div CANDPERPAGE) * lpCandList.dwPageSize) then
  99.     begin
  100.       MessageBeep($FFFFFFFF);
  101.       Exit;
  102.     end;
  103.     Inc(lpCandList.dwSelection, lpCandList.dwPageSize);
  104.     lpImcP.fdwImeMsg := lpImcP.fdwImeMsg or MSG_CHANGE_CANDIDATE;
  105.     Exit;
  106.   end;
  107.   if (wCharCode = Ord('-')) then       // 向上翻页
  108.   begin
  109.     if (lpCandList.dwSelection < lpCandList.dwPageSize) then
  110.     begin
  111.       MessageBeep($FFFFFFFF);
  112.       Exit;
  113.     end;
  114.     Dec(lpCandList.dwSelection, lpCandList.dwPageSize);
  115.     lpImcP.fdwImeMsg := lpImcP.fdwImeMsg or MSG_CHANGE_CANDIDATE;
  116.     Exit;
  117.   end;
  118.   if (wCharCode = $23) then      // 翻至尾页
  119.   begin
  120.     if (lpCandList.dwSelection >= ((IME_MAXCAND - 1) div CANDPERPAGE) * lpCandList.dwPageSize) then
  121.     begin
  122.       MessageBeep($FFFFFFFF);
  123.       Exit;
  124.     end;
  125.     lpCandList.dwSelection := ((IME_MAXCAND - 1) div CANDPERPAGE) * lpCandList.dwPageSize;
  126.     lpImcP.fdwImeMsg := lpImcP.fdwImeMsg or MSG_CHANGE_CANDIDATE;
  127.     Exit;
  128.   end;
  129.   if (wCharCode = $24) then      // 翻至首页
  130.   begin
  131.     if (lpCandList.dwSelection < lpCandList.dwPageSize) then
  132.     begin
  133.       MessageBeep($FFFFFFFF);
  134.       Exit;
  135.     end;
  136.     lpCandList.dwSelection := 0;
  137.     lpImcP.fdwImeMsg := lpImcP.fdwImeMsg or MSG_CHANGE_CANDIDATE;
  138.     Exit;
  139.   end;
  140.   if (wCharCode = Ord('?')) then       // 翻至home
  141.   begin
  142.     if (lpCandList.dwSelection = 0) then
  143.     begin
  144.       MessageBeep($FFFFFFFF);
  145.       Exit;
  146.     end;
  147.     lpCandList.dwSelection := 0;
  148.     lpImcP.fdwImeMsg := lpImcP.fdwImeMsg or MSG_CHANGE_CANDIDATE;
  149.     Exit;
  150.   end;
  151.   if (wCharCode >= Ord('0')) and (wCharCode <= Ord('9')) then // 选择
  152.   begin
  153.     if (wCharCode = Ord('0')) then dwSelCand := 9 else dwSelCand := wCharCode - Ord('0') - CAND_START;
  154.     if (dwSelCand >= CANDPERPAGE) then  // out of candidate page range
  155.     begin
  156.       MessageBeep($FFFFFFFF);
  157.       Exit;
  158.     end;
  159.     if (lpCandList.dwSelection + dwSelCand >= lpCandList.dwCount) then  // out of range
  160.     begin
  161.       MessageBeep($FFFFFFFF);
  162.       Exit;
  163.     end;
  164.     lpCandList.dwSelection := lpCandList.dwSelection + dwSelCand;
  165.     lpCompStr := ImmLockIMCC(lpIMC.hCompStr);
  166.     if (lpCompStr = nil) then Exit;
  167.     SelectOneCand(lpIMC, lpCompStr, lpImcP, lpCandList); // translate into translate buffer
  168.     ImmUnlockIMCC(lpIMC.hCompStr);
  169.   end;
  170. end;
  171. end.