DDIS.pas
资源名称:Wingb_Mz.rar [点击查看]
上传用户:wen198501
上传日期:2013-04-01
资源大小:335k
文件大小:25k
源码类别:
输入法编程
开发平台:
Delphi
- {******************************************************}
- { }
- { Copyright (c) 1990-1999 Microsoft Corporation }
- { }
- { Module Name: DDIS.c ->> DDIS.pas }
- { }
- { Translator: Liu_mazi@126.com, 2005-11-15 }
- { }
- {******************************************************}
- unit DDIS;
- {$I Define.Inc}
- interface
- uses Windows, ImmDev;
- var hCrtDlg: hWnd = 0;
- function OpenReg_PathSetup(_phKey: PHKey): DWord; // 打开注册表
- function OpenReg_User(_hKey: HKey; lpszSubKey: PChar; phkResult: PHKey): DWord; // 打开注册表
- function ClearCand(lpIMC: PInputContext): Bool; // 清除Candidate, **
- procedure InitCompStr(lpCompStr: PCompositionString); // 初始化编码串
- // Ime回调 ..
- function ImeConfigure(_hKL: hKL; hAppWnd: hWnd; dwMode: DWord; lpData: Pointer): Bool; stdcall;
- function ImeConversionList(_hIMC: hIMC; lpszSrc: PChar; lpCandList: PCandiDateList; uBufLen, uFlag: uInt): DWord; stdcall;
- function ImeDestroy(uReserved: uInt): Bool; stdcall;
- function ImeEscape(_hIMC: hIMC; uSubFunc: uInt; lpData: PChar): LResult; stdcall;
- function ImeInquire(lpImeInfo: PImeInfo; lpszWndCls: PChar; lpszOptions: DWord): Bool; stdcall;
- function ImeSelect(_hIMC: hIMC; fSelect: Bool): Bool; stdcall;
- function ImeSetActiveContext(_hIMC: hIMC; fOn: Bool): Bool; stdcall;
- implementation
- uses Messages, ImeDefs, Data, ToAscii, Ui, Compose, LogText;
- // Ime回调, initialized data structure of IME
- function ImeInquire(lpImeInfo: PImeInfo; lpszWndCls: PChar; lpszOptions: DWord): Bool; stdcall;
- begin
- Result := False;
- if (lpImeInfo = nil) then Exit;
- lpImeInfo.dwPrivateDataSize := SizeOf(TPrivContext);
- lpImeInfo.fdwProperty := IME_PROP_KBD_CHAR_FIRST or IME_PROP_CANDLIST_START_FROM_1 or IME_PROP_IGNORE_UPKEYS;
- lpImeInfo.fdwConversionCaps := IME_CMODE_NATIVE or IME_CMODE_FULLSHAPE or IME_CMODE_CHARCODE or IME_CMODE_SOFTKBD or IME_CMODE_NOCONVERSION;
- lpImeInfo.fdwSentenceCaps := 0;
- // IME will have different distance base multiple of 900 escapement
- lpImeInfo.fdwUICaps := UI_CAP_ROT90 or UI_CAP_SOFTKBD;
- // composition string is the reading string for simple IME
- lpImeInfo.fdwSCSCaps := SCS_CAP_COMPSTR or SCS_CAP_MAKEREAD;
- // IME want to decide conversion mode on ImeSelect
- lpImeInfo.fdwSelectCaps := 0;
- lStrCpy(lpszWndCls, szUIClassName);
- Result := True;
- end;
- // Ime配置对话框回调
- function ImeSetDlgProc(hDlg: hWnd; uMessage: uInt; wParam: WParam; lParam: LParam): Bool; stdcall;
- const {$J+}
- TempParam: DWord = $FFFFFFFF; {$J-}
- var
- rc: TRect;
- DlgWidth, DlgHeight: Integer;
- hKeyCurrVersion, hKeyGB: hKey;
- retCode: DWord;
- begin
- Result := False;
- case (uMessage) of
- WM_INITDIALOG:
- begin
- hCrtDlg := hDlg;
- // reset position
- GetWindowRect(hDlg, rc);
- DlgWidth := rc.Right - rc.Left;
- DlgHeight := rc.Bottom - rc.Top;
- SetWindowPos(hDlg, HWND_TOP, (sImeG.rcWorkArea.Right - DlgWidth) div 2,
- (sImeG.rcWorkArea.Bottom - DlgHeight) div 2, 0, 0, SWP_NOSIZE);
- TempParam := sImeG.IC_Trace;
- CheckDlgButton(hDlg, IDC_TRACE, sImeG.IC_Trace);
- // don't want to set focus to special control
- Result := True;
- end;
- WM_COMMAND:
- case (wParam) of
- IDOK:
- begin
- sImeG.IC_Trace := TempParam;
- retCode := OpenReg_PathSetup(@hKeyCurrVersion);
- if (retCode <> ERROR_SUCCESS) then RegCreateKey(HKEY_CURRENT_USER, REGSTR_PATH_SETUP, hKeyCurrVersion);
- retCode := RegCreateKeyEx(hKeyCurrVersion, szImeRegName, 0, nil,
- REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, nil, hKeyGB, nil);
- if (retCode <> ERROR_SUCCESS) then RegCreateKey(HKEY_CURRENT_USER, REGSTR_PATH_SETUP, hKeyCurrVersion);
- RegSetValueEx(hKeyGB, szTrace, 0, REG_DWORD, @sImeG.IC_Trace, SizeOf(DWord));
- RegCloseKey(hKeyGB);
- RegCloseKey(hKeyCurrVersion);
- EndDialog(hDlg, 0);
- Result := True;
- end;
- IDCANCEL:
- begin
- EndDialog(hDlg, 0);
- Result := True;
- end;
- IDC_TRACE: // Set Current InputMode Param(temp)
- begin
- if (TempParam = $FFFFFFFF) then TempParam := sImeG.IC_Trace; // 初始化, ++
- TempParam := (TempParam xor $00000001) and $00000001;
- Result := True;
- end;
- end;
- WM_PAINT:
- begin
- GetClientRect(hDlg, rc);
- DrawConvexRect(GetDC(hDlg), rc.Left + 7, rc.Top + 7, rc.Right - 7 - 1, rc.Bottom - 40 - 1);
- DrawConvexRectP(GetDC(hDlg), rc.Left + 7, rc.Top + 7, rc.Right - 7, rc.Bottom - 40);
- end;
- WM_CLOSE:
- begin
- EndDialog(hDlg, 0);
- Result := True;
- end;
- end;
- end;
- // Ime回调, configurate the IME setting
- function ImeConfigure(_hKL: hKL; hAppWnd: hWnd; dwMode: DWord; lpData: Pointer): Bool; stdcall;
- begin
- case (dwMode) of
- IME_CONFIG_GENERAL:
- begin
- DialogBox(HInstance, 'ImeSet', hAppWnd, @ImeSetDlgProc);
- Result := True;
- end;
- else
- Result := False;
- end;
- end;
- // GCL_CONVERSION处理
- function Conversion(lpszReading: PChar; lpCandList: PCandiDateList; uBufLen: uInt): DWord;
- var
- MAX_COMP, J, uMaxCand, iRet: uInt;
- wCode: Word;
- lpImcP: PPrivContext;
- hImcP: hGlobal;
- dwSize: DWord;
- begin
- Result := 0;
- if (lStrLen(lpszReading) <> 4) then Exit;
- hImcP := GlobalAlloc(GMEM_MOVEABLE, SizeOf(TPrivContext));
- if(hImcP = 0) then Exit;
- lpImcP := GlobalLock(hImcP);
- if (lpImcP = nil) then
- begin
- GlobalFree(hImcP);
- Exit;
- end;
- lStrCpy(lpImcP.bSeq, lpszReading);
- if (lpImcP.bSeq[3] = '?') then MAX_COMP := 94 else MAX_COMP := 1;
- dwSize := SizeOf(TCandiDateList) + SizeOf(DWord) * MAX_COMP + (SizeOf(Word) + SizeOf(Char)) * MAX_COMP;
- if (uBufLen = 0) then
- begin
- Result := dwSize;
- Exit;
- end;
- uMaxCand := uBufLen - SizeOf(TCandidateList);
- uMaxCand := uMaxCand div (SizeOf(DWord) + SizeOf(Word) + SizeOf(Char));
- if (uMaxCand = 0) then Exit; // can not even put one string
- lpCandList.dwSize := dwSize;
- lpCandList.dwStyle := IME_CAND_READ; // candidate having same reading
- lpCandList.dwCount := 0;
- lpCandList.dwSelection := 0;
- lpCandList.dwPageSize := CANDPERPAGE;
- lpCandList.dwOffset[0] := SizeOf(TCandiDateList) + SizeOf(DWord) * (uMaxCand - 1);
- lpImcP.bSeq[0] := #0;
- lpImcP.bSeq[1] := #0;
- lpImcP.bSeq[2] := #0;
- lpImcP.bSeq[3] := #0;
- for J := 0 to 3 do
- begin
- iRet := GBProcessKey(PByte(DWord(lpszReading) + J)^, lpImcP);
- if (iRet = CST_INPUT) then lpImcP.bSeq[J] := PChar(DWord(lpszReading) + J)^ else Exit; //return 0;
- end;
- wCode := GBEngine(lpImcP);
- wCode := HiByte(wCode) or (LoByte(wCode) shl 8);
- for J := 0 to MAX_COMP - 1 do
- begin
- AddCodeIntoCand(lpCandList, wCode);
- Inc(wCode);
- end;
- GlobalUnlock(hImcP);
- GlobalFree(hImcP);
- Result := dwSize;
- end;
- // 汉字内码转区位码串, **
- // function DBCSToGBCode(wCode: Word; AbSeq: array[0..4] of Char): Bool;
- function DBCSToGBCode(wCode: Word; AbSeq: PChar): Bool;
- var
- AreaCode: Word;
- begin
- Result := False;
- //check valid GB range code first
- if (LoByte(wCode) < $A1) or (LoByte(wCode) > $FE) or (HiByte(wCode) < $A1) or (HiByte(wCode) > $FE) then Exit;
- AbSeq[1] := Chr(((wCode - $A0) and $FF) mod 10);
- AbSeq[0] := Chr(((wCode - $A0) and $FF) div 10);
- AreaCode := wCode shr 8; // **
- AbSeq[3] := Chr(((AreaCode - $A0) and 256) mod 10);
- AbSeq[2] := Chr(((AreaCode - $A0) and 256) div 10);
- AbSeq[4] := #0;
- Result := True;
- end;
- // 区位码串转GB码串, **
- // function AreaToGB(AbSeq: array[0..4] of Char; GbSeq: array[0..4] of Char): Bool;
- function AreaToGB(AbSeq, GbSeq: PChar): Bool;
- var
- MbSeq: array[0..2] of Char; // Temp string
- vList: DWord;
- begin
- // Area turn
- vList := Ord(AbSeq[0]) * 10 + Ord(AbSeq[1]) + $A0;
- wvsprintf(MbSeq, '%lx', @vList);
- GbSeq[0] := MbSeq[0];
- GbSeq[1] := MbSeq[1];
- // position turn
- vList := Ord(AbSeq[2]) * 10 + Ord(AbSeq[3]) + $A0;
- wvsprintf(MbSeq, '%lx', @vList);
- GbSeq[2] := MbSeq[0];
- GbSeq[3] := MbSeq[1];
- GbSeq[4] := #0;
- Result := True;
- end;
- // GCL_REVERSECONVERSION处理
- function ReverseConversion(wCode: Word; lpCandList: PCandiDateList; uBufLen: uInt): DWord;
- const
- Max_Comp: uInt = 2; // **
- nMaxKey: uInt = 4;
- var
- AbSeq, GbSeq: array [0..4] of Char;
- uMaxCand: uInt;
- dwSize: DWord; // similar to ClearCand
- lpdwOffset: PDWord;
- begin
- Result := 0;
- dwSize := SizeOf(TCandidateList) + SizeOf(DWord) * Max_Comp + (SizeOf(Char) * nMaxKey + SizeOf(Char));
- if (uBufLen = 0) then
- begin
- Result := dwSize;
- Exit;
- end;
- uMaxCand := uBufLen - SizeOf(TCandidateList);
- uMaxCand := uMaxCand div (SizeOf(DWord) + SizeOf(Char) * nMaxKey + SizeOf(Char));
- if (uMaxCand = 0) then Exit;// can not put one string
- lpCandList.dwSize := SizeOf(TCandidateList) + SizeOf(DWord) * uMaxCand + (SizeOf(Char) * nMaxKey + SizeOf(Char));
- lpCandList.dwStyle := IME_CAND_READ;
- lpCandList.dwCount := 0;
- lpCandList.dwSelection := 0;
- lpCandList.dwOffset[0] := SizeOf(TCandidateList) + SizeOf(DWord);
- if (DBCSToGBCode(wCode, AbSeq) = False) then Exit;
- AreaToGB(AbSeq, GbSeq);
- Inc(AbSeq[1], Ord('0'));
- Inc(AbSeq[0], Ord('0'));
- Inc(AbSeq[3], Ord('0'));
- Inc(AbSeq[2], Ord('0'));
- lStrCpy(PChar(DWord(lpCandList) + lpCandList.dwOffset[0]), AbSeq);
- lpdwOffset := @lpCandList.dwOffset[0];
- Inc(lpdwOffset);
- lpdwOffset^ := lpCandList.dwOffset[0] + 4 * SizeOf(Char) + SizeOf(Char);
- lStrCpy(PChar(DWord(lpCandList) + lpdwOffset^), GbSeq);
- lpCandList.dwCount := 2; // string count ++
- Result := dwSize;
- end;
- // Ime回调
- function ImeConversionList(_hIMC: hIMC; lpszSrc: PChar; lpCandList: PCandiDateList; uBufLen, uFlag: uInt): DWord; stdcall;
- var
- wCode: Word;
- lpIMC: PInputContext;
- lpImcP: PPrivContext;
- begin
- Result := 0;
- if (uBufLen = 0) then
- begin
- end else
- if (lpszSrc = nil) or
- (lpszSrc^ = #0) or
- (lpCandList = nil) or
- (uBufLen <= SizeOf(TCandidateList))
- then Exit;
- case (uFlag) of
- GCL_CONVERSION:
- begin
- lpIMC := ImmLockIMC(_hIMC);
- if (lpIMC = nil) then Exit;
- lpImcP := ImmLockIMCC(lpIMC.hPrivate);
- if (lpImcP = nil) then
- begin
- ImmUnlockIMC(_hIMC);
- Exit;
- end;
- Result := Conversion(lpszSrc, lpCandList, uBufLen);
- end;
- GCL_REVERSECONVERSION:
- begin
- if (uBufLen = 0) then
- begin
- Result := 1;
- Exit;
- end;
- // only support one DBCS char reverse conversion
- if PChar(DWord(lpszSrc) + SizeOf(Word))^ <> #0 then Exit;
- wCode := PWord(lpszSrc)^;
- // swap lead byte & second byte, UNICODE don't need it
- // wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8); For Big5
- Result := ReverseConversion(wCode, lpCandList, uBufLen);
- end;
- end;
- end;
- // Ime回调, this dll is unloaded
- function ImeDestroy(uReserved: uInt): Bool; stdcall;
- begin
- Result := (uReserved = 0);
- end;
- // **
- const
- IME_INPUTKEYTOSEQUENCE = $22;
- // Ime回调, escape function of IMEs
- function ImeEscape(_hIMC: hIMC; uSubFunc: uInt; lpData: PChar): LResult; stdcall;
- var
- szIMEGUDHlpName: array[0..MAXSTRLEN] of Char;
- begin
- case (uSubFunc) of
- IME_ESC_QUERY_SUPPORT:
- begin
- if (lpData = nil) then
- begin
- Result := 0;
- Exit;
- end;
- case PUInt(lpData)^ of // **
- IME_ESC_QUERY_SUPPORT,
- IME_ESC_MAX_KEY,
- IME_ESC_IME_NAME,
- IME_ESC_GETHELPFILENAME:
- Result := 0;
- IME_ESC_SEQUENCE_TO_INTERNAL,
- IME_ESC_GET_EUDC_DICTIONARY,
- IME_ESC_SET_EUDC_DICTIONARY,
- IME_INPUTKEYTOSEQUENCE: // will not supported in next version
- Result := 0; // will not supported in GB IME
- else
- Result := 0;
- end;
- end;
- IME_ESC_SEQUENCE_TO_INTERNAL,
- IME_ESC_GET_EUDC_DICTIONARY,
- IME_ESC_SET_EUDC_DICTIONARY,
- IME_INPUTKEYTOSEQUENCE:
- Result := 0;
- IME_ESC_MAX_KEY:
- Result := 4;
- IME_ESC_IME_NAME:
- begin
- Result := 0;
- if (lpData = nil) then Exit;
- lStrCpy(lpData, szImeName);
- Result := 1;
- end;
- IME_ESC_GETHELPFILENAME:
- begin
- Result := 0;
- if (lpData = nil) then Exit;
- szIMEGUDHlpName[0] := #0;
- GetWindowsDirectory(szIMEGUDHlpName, MAXSTRLEN);
- lStrCat(szIMEGUDHlpName, 'HELPWINGB.CHM');
- lStrCpy(lpData, szIMEGUDHlpName);
- Result := 1;
- end;
- else
- Result := 1;
- end;
- end;
- // init setting for composing string
- procedure InitCompStr(lpCompStr: PCompositionString);
- begin
- if (lpCompStr = nil) then Exit;
- lpCompStr.dwCompReadAttrLen := 0;
- lpCompStr.dwCompReadClauseLen := 0;
- lpCompStr.dwCompReadStrLen := 0;
- lpCompStr.dwCompAttrLen := 0;
- lpCompStr.dwCompClauseLen := 0;
- lpCompStr.dwCompStrLen := 0;
- lpCompStr.dwCursorPos := 0;
- lpCompStr.dwDeltaStart := 0;
- lpCompStr.dwResultReadClauseLen := 0;
- lpCompStr.dwResultReadStrLen := 0;
- lpCompStr.dwResultClauseLen := 0;
- lpCompStr.dwResultStrLen := 0;
- end;
- // 清除编码串, **
- function ClearCompStr(lpIMC: PInputContext): Bool;
- var
- hMem: hIMCC;
- lpCompStr: PCompositionString;
- dwSize: DWord;
- begin
- Result := False;
- if (lpIMC = nil) then Exit;
- dwSize :=
- SizeOf(TCompositionString) +
- sImeL.nMaxKey * SizeOf(Byte) + SizeOf(Byte) +
- SizeOf(DWord) + SizeOf(DWord) +
- sImeL.nMaxKey * SizeOf(Word) + SizeOf(Word) +
- SizeOf(DWord) + SizeOf(DWord) +
- sImeL.nMaxKey * SizeOf(Word) + SizeOf(Word) +
- SizeOf(DWord) + SizeOf(DWord) +
- MAXSTRLEN * SizeOf(Word) + SizeOf(Word);
- if (lpIMC.hCompStr = 0) then
- begin
- lpIMC.hCompStr := ImmCreateIMCC(dwSize); // it maybe free by other IME, init it
- end else
- begin
- hMem := ImmReSizeIMCC(lpIMC.hCompStr, dwSize);
- if (hMem <> 0) then
- begin
- lpIMC.hCompStr := hMem;
- end else
- begin
- ImmDestroyIMCC(lpIMC.hCompStr);
- lpIMC.hCompStr := ImmCreateIMCC(dwSize);
- Exit;
- end;
- end;
- if (lpIMC.hCompStr = 0) then Exit; // return (FALSE)
- lpCompStr := ImmLockIMCC(lpIMC.hCompStr);
- if (lpCompStr = nil) then
- begin
- ImmDestroyIMCC(lpIMC.hCompStr);
- lpIMC.hCompStr := ImmCreateIMCC(dwSize);
- Exit;
- end;
- lpCompStr.dwSize := dwSize;
- // 1. composition (reading) string - simple IME
- // 2. result reading string
- // 3. result string
- lpCompStr.dwCompReadAttrLen := 0;
- lpCompStr.dwCompReadAttrOffset := SizeOf(TCompositionString);
- lpCompStr.dwCompReadClauseLen := 0;
- lpCompStr.dwCompReadClauseOffset := lpCompStr.dwCompReadAttrOffset + sImeL.nMaxKey * SizeOf(Char) + SizeOf(Char);
- lpCompStr.dwCompReadStrLen := 0;
- lpCompStr.dwCompReadStrOffset := lpCompStr.dwCompReadClauseOffset + Sizeof(DWord) + Sizeof(DWord);
- // composition string is the same with composition reading string for simple IMEs
- lpCompStr.dwCompAttrLen := 0;
- lpCompStr.dwCompAttrOffset := lpCompStr.dwCompReadAttrOffset;
- lpCompStr.dwCompClauseLen := 0;
- lpCompStr.dwCompClauseOffset := lpCompStr.dwCompReadClauseOffset;
- lpCompStr.dwCompStrLen := 0;
- lpCompStr.dwCompStrOffset := lpCompStr.dwCompReadStrOffset;
- lpCompStr.dwCursorPos := 0;
- lpCompStr.dwDeltaStart := 0;
- lpCompStr.dwResultReadClauseLen := 0;
- lpCompStr.dwResultReadClauseOffset := lpCompStr.dwCompStrOffset + sImeL.nMaxKey * SizeOf(Word) + SizeOf(Word);
- lpCompStr.dwResultReadStrLen := 0;
- lpCompStr.dwResultReadStrOffset := lpCompStr.dwResultReadClauseOffset + SizeOf(DWord) + SizeOf(DWord);
- lpCompStr.dwResultClauseLen := 0;
- lpCompStr.dwResultClauseOffset := lpCompStr.dwResultReadStrOffset + sImeL.nMaxKey * SizeOf(Word) + SizeOf(Word);
- lpCompStr.dwResultStrOffset := 0;
- lpCompStr.dwResultStrOffset := lpCompStr.dwResultClauseOffset + SizeOf(DWord) + SizeOf(DWord);
- GlobalUnlock(lpIMC.hCompStr);
- Result := True;
- end;
- // 清除Candidate, **
- function ClearCand(lpIMC: PInputContext): Bool;
- var
- hMem: hIMCC;
- lpCandInfo: PCandiDateInfo;
- lpCandList: PCandiDateList;
- dwSize: DWord;
- begin
- dwSize := SizeOf(TCandidateInfo) + SizeOf(TCandidateList) +
- SizeOf(DWord) * (MAXCAND + 1) + (SizeOf(Word) + SizeOf(Word)) * (MAXCAND + 1);
- Result := False;
- if (lpIMC = nil) then Exit;
- if (lpIMC.hCandInfo = 0) then
- begin
- lpIMC.hCandInfo := ImmCreateIMCC(dwSize); // it maybe free by other IME, init it
- end else
- begin
- hMem := ImmReSizeIMCC(lpIMC.hCandInfo, dwSize);
- if (hMem <> 0) then
- begin
- lpIMC.hCandInfo := hMem;
- end else
- begin
- ImmDestroyIMCC(lpIMC.hCandInfo);
- lpIMC.hCandInfo := ImmCreateIMCC(dwSize);
- Exit; // return (FALSE)
- end;
- end;
- if (lpIMC.hCandInfo = 0) then Exit; // return (FALSE)
- lpCandInfo := ImmLockIMCC(lpIMC.hCandInfo);
- if (lpCandInfo = nil) then
- begin
- ImmDestroyIMCC(lpIMC.hCandInfo);
- lpIMC.hCandInfo := ImmCreateIMCC(dwSize);
- Exit; // return (FALSE)
- end;
- // ordering of strings are buffer size
- lpCandInfo.dwSize := dwSize;
- lpCandInfo.dwCount := 0;
- lpCandInfo.dwOffset[0] := SizeOf(TCandidateInfo);
- lpCandList := PCandidateList(DWord(lpCandInfo) + lpCandInfo.dwOffset[0]);
- // whole candidate info size - header
- lpCandList.dwSize := lpCandInfo.dwSize - SizeOf(TCandidateInfo);
- lpCandList.dwStyle := IME_CAND_READ;
- lpCandList.dwCount := 0;
- lpCandList.dwSelection := 0;
- lpCandList.dwPageSize := CANDPERPAGE;
- lpCandList.dwOffset[0] := SizeOf(TCandidateList) + SizeOf(DWord) * (MAXCAND);
- ImmUnlockIMCC(lpIMC.hCandInfo);
- Result := True;
- end;
- // 清除GuideLine, **
- function ClearGuideLine(lpIMC: PInputContext): Bool;
- var
- hMem: hIMCC;
- lpGuideLine: PGuideLine;
- dwSize: DWord;
- begin
- dwSize := SizeOf(TGuideLine) + sImeG.cbStatusErr;
- Result := False;
- if (lpIMC.hGuideLine = 0) then
- begin
- lpIMC.hGuideLine := ImmCreateIMCC(dwSize); // it maybe free by IME
- end else
- begin
- hMem := ImmReSizeIMCC(lpIMC.hGuideLine, dwSize);
- if (hMem <> 0) then
- begin
- lpIMC.hGuideLine := hMem;
- end else
- begin
- ImmDestroyIMCC(lpIMC.hGuideLine);
- lpIMC.hGuideLine := ImmCreateIMCC(dwSize);
- end;
- end;
- lpGuideLine := ImmLockIMCC(lpIMC.hGuideLine);
- if (lpGuideLine = nil) then Exit; // return (FALSE)
- lpGuideLine.dwSize := dwSize;
- lpGuideLine.dwLevel := GL_LEVEL_NOGUIDELINE;
- lpGuideLine.dwIndex := GL_ID_UNKNOWN;
- lpGuideLine.dwStrLen := 0;
- lpGuideLine.dwStrOffset := SizeOf(TGuideLine);
- CopyMemory(Pointer(DWord(lpGuideLine) + lpGuideLine.dwStrOffset), @sImeG.szStatusErr, sImeG.cbStatusErr);
- ImmUnlockIMCC(lpIMC.hGuideLine);
- Result := True;
- end;
- // **
- procedure InitContext(lpIMC: PInputContext);
- var
- ptWnd: TPoint;
- begin
- if (lpIMC.fdwInit and INIT_STATUSWNDPOS) <> 0 then
- begin
- end else
- if (IsWindow(lpIMC.hWnd) = False) then
- begin
- end else
- begin
- ptWnd.x := 0;
- ptWnd.y := 0;
- ClientToScreen(lpIMC.hWnd, ptWnd);
- if (ptWnd.x < sImeG.rcWorkArea.Left) then
- begin
- lpIMC.ptStatusWndPos.x := sImeG.rcWorkArea.Left;
- end else
- if (ptWnd.x + sImeG.xStatusWi > sImeG.rcWorkArea.Right) then
- begin
- lpIMC.ptStatusWndPos.x := sImeG.rcWorkArea.Right - sImeG.xStatusWi;
- end else
- begin
- lpIMC.ptStatusWndPos.x := ptWnd.x;
- end;
- lpIMC.ptStatusWndPos.y := sImeG.rcWorkArea.Bottom - sImeG.yStatusHi;
- lpIMC.fdwInit := lpIMC.fdwInit or INIT_STATUSWNDPOS;
- end;
- if (lpIMC.fdwInit and INIT_COMPFORM) <> 0 then
- begin
- end else
- if (IsWindow(lpIMC.hWnd) = False) then
- begin
- end else
- begin
- ptWnd := sImeL.ptDefComp;
- ScreenToClient(lpIMC.hWnd, ptWnd);
- lpIMC.cfCompForm.dwStyle := CFS_DEFAULT;
- lpIMC.cfCompForm.ptCurrentPos := ptWnd;
- lpIMC.fdwInit := lpIMC.fdwInit or INIT_COMPFORM;
- end;
- end;
- // **
- function Select(_hIMC: hIMC; lpIMC: PInputContext; fSelect: Bool): Bool;
- var
- lpImcP: PPrivContext;
- // J: uInt;
- _hDC: hDC;
- hSysFont: hGdiObj;
- fdwConversion: DWord;
- begin
- Result := False;
- if (fSelect) then
- begin
- if (ClearCompStr(lpIMC) = False) then Exit; // return FALSE
- if (ClearCand(lpIMC) = False) then Exit; // return FALSE
- ClearGuideLine(lpIMC);
- end;
- if (lpIMC.cfCandForm[0].dwIndex <> 0) then lpIMC.cfCandForm[0].dwStyle := CFS_DEFAULT;
- // We add this hack for switching from other IMEs, this IME has a bug.
- // Before this bug fixed in this IME, it depends on this hack.
- if (lpIMC.cfCandForm[0].dwStyle = CFS_DEFAULT) then lpIMC.cfCandForm[0].dwIndex := $FFFFFFFF;
- if (lpIMC.hPrivate = 0) then Exit; // return FALSE
- lpImcP := ImmLockIMCC(lpIMC.hPrivate);
- if (lpImcP = nil) then Exit; // return FALSE
- if (fSelect) then
- begin
- //
- // init fields of hPrivate
- //
- lpImcP.iImeState := CST_INIT;
- lpImcP.fdwImeMsg := 0;
- lpImcP.dwCompChar := 0;
- lpImcP.fdwGcsFlag := 0;
- lpImcP.uSYHFlg := 0;
- lpImcP.uDYHFlg := 0;
- lpImcP.uDSMHCount := 0;
- lpImcP.uDSMHFlg := 0;
- //lpImcP->fdwSentence = (DWORD)NULL;
- //
- // reset SK State
- //
- PDWord(@lpImcP.bSeq)^ := 0;
- lpIMC.fOpen := True;
- if (lpIMC.fdwInit and INIT_CONVERSION) = 0 then
- begin
- lpIMC.fdwConversion := (lpIMC.fdwConversion and IME_CMODE_SOFTKBD) or IME_CMODE_NATIVE;
- lpIMC.fdwInit := lpIMC.fdwInit or INIT_CONVERSION;
- end;
- if (lpIMC.fdwInit and INIT_SENTENCE) <> 0 then
- begin
- end else
- if (sImeL.fModeConfig and MODE_CONFIG_PREDICT) <> 0 then
- begin
- lpIMC.fdwSentence := IME_SMODE_PHRASEPREDICT;
- lpIMC.fdwInit := lpIMC.fdwInit or INIT_SENTENCE;
- end;
- if (lpIMC.fdwInit and INIT_LOGFONT) = 0 then
- begin
- //hSysFont = GetStockObject(SYSTEM_FONT);
- _hDC := GetDC(0);
- hSysFont := GetCurrentObject(_hDC, OBJ_FONT);
- GetObject(hSysFont, SizeOf(TLogFont), @lpIMC.lfFont.A);
- ReleaseDC(0, _hDC);
- lpIMC.fdwInit := lpIMC.fdwInit or INIT_LOGFONT;
- end;
- InitContext(lpIMC);
- //
- // Set Caps status
- //
- if (GetKeyState(VK_CAPITAL) and $01) <> 0 then
- begin
- //
- // Change to alphanumeric mode.
- //
- fdwConversion := lpIMC.fdwConversion and not(IME_CMODE_NATIVE or IME_CMODE_CHARCODE or IME_CMODE_EUDC);
- end else
- begin
- //
- // Change to native mode
- //
- fdwConversion := (lpIMC.fdwConversion or IME_CMODE_NATIVE) and not(IME_CMODE_CHARCODE or IME_CMODE_EUDC );
- end;
- ImmSetConversionStatus(_hIMC, fdwConversion, lpIMC.fdwSentence);
- end else
- begin
- if (sImeL.hSKMenu <> 0) then
- begin
- DestroyMenu(sImeL.hSKMenu);
- sImeL.hSKMenu := 0;
- end;
- if (sImeL.hPropMenu <> 0) then
- begin
- DestroyMenu(sImeL.hPropMenu);
- sImeL.hPropMenu := 0;
- end;
- if IsWindow(hCrtDlg) then
- begin
- SendMessage(hCrtDlg, WM_CLOSE, 0, 0);
- hCrtDlg := 0;
- end;
- end;
- ImmUnlockIMCC(lpIMC.hPrivate);
- Result := True;
- end;
- // Ime回调, 初始化
- function ImeSelect(_hIMC: hIMC; fSelect: Bool): Bool; stdcall;
- var
- lpIMC: PInputContext;
- begin
- Result := False;
- if (_hIMC = 0) then Exit;
- lpIMC := ImmLockIMC(_hIMC);
- if (lpIMC = nil) then Exit;
- Result := Select(_hIMC, lpIMC, fSelect);
- ImmUnlockIMC(_hIMC);
- end;
- // Ime回调, 激活输入法
- function ImeSetActiveContext(_hIMC: hIMC; fOn: Bool): Bool; stdcall;
- var
- lpIMC: PInputContext;
- begin
- Result := False;
- if (fOn = False) then
- begin
- end else
- if (_hIMC = 0) then
- begin
- end else
- begin
- lpIMC := ImmLockIMC(_hIMC);
- if (lpIMC = nil) then Exit;
- InitContext(lpIMC);
- ImmUnlockIMC(_hIMC);
- end;
- Result := True;
- end;
- // 打开注册表, HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersion
- function OpenReg_PathSetup(_phKey: PHKey): DWord;
- begin
- Result := RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_SETUP, 0,
- KEY_ENUMERATE_SUB_KEYS or KEY_EXECUTE or KEY_QUERY_VALUE, _phKey^);
- end;
- // 打开注册表, _hKeylpszSubKey
- function OpenReg_User(_hKey: HKey; lpszSubKey: PChar; phkResult: PHKey): DWord;
- begin
- {$IfDef Debug}
- ImeLog('OpenReg_User, ' + lpszSubKey);
- {$EndIf}
- Result := RegOpenKeyEx(_hKey, lpszSubKey, 0, KEY_ALL_ACCESS, phkResult^);
- end;
- // 显示信息
- procedure InfoMessage(_hWnd: hWnd; wMsgID: Word);
- var
- szStr: array[0..256] of Char;
- begin
- LoadString(0, wMsgID, szStr, SizeOf(szStr) - 1);
- MessageBox(_hWnd, szStr, szWarnTitle, MB_ICONINFORMATION or MB_OK);
- end;
- // 显示错误
- procedure FatalMessage(_hWnd: hWnd; wMsgID: Word);
- var
- szStr: array[0..256] of Char;
- begin
- LoadString(0, wMsgID, szStr, SizeOf(szStr) - 1);
- MessageBox(_hWnd, szStr, szErrorTitle, MB_ICONSTOP or MB_OK);
- end;
- end.