delphi取win10輸入法 (轉自qdac)


【問題原因】

該問題是由於微軟從 Windows 8  開始,GetKeyboadLayouts 函數不再有效,而 VCL 中仍然是通過該方法獲取輸入法列表造成的。希望下個版本的 Delphi/C++ Builder 能夠解決。

【解決辦法】

如果是 Win8+,則自己從注冊表讀,如果是Win 7 等以前的版本,則直接取 Screen.Imes。這個函數做了一個簡單的封裝。

procedure EnumImeNames(AList: TStrings);
var
AReg: TRegistry;
AKeyList: TStringList;
I: Integer;
ALayout: Cardinal;
function NameByLayout: String;
const
KbLayoutRegkeyFmt =
'System\CurrentControlSet\Control\Keyboard Layouts\%.8x';
KbLayoutRegSubkey = 'layout text';
var
AIMEReg: TRegistry;
begin
SetLength(Result, 0);
AIMEReg := TRegistry.Create;
try
AIMEReg.RootKey := HKEY_LOCAL_MACHINE;
if AIMEReg.OpenKeyReadOnly(Format(KbLayoutRegkeyFmt, [ALayout])) then
begin
if AIMEReg.ValueExists(KbLayoutRegSubkey) then
Result := AIMEReg.ReadString(KbLayoutRegSubkey)
end;
finally
FreeAndNil(AIMEReg);
end;
end;

function NameByClsId(AClsId: String): String;
var
AIMEReg: TRegistry;
begin
SetLength(Result, 0);
AIMEReg := TRegistry.Create;
try
AIMEReg.RootKey := HKEY_CLASSES_ROOT;
if AIMEReg.OpenKeyReadOnly('CLSID\' + AClsId) then
Result := AIMEReg.ReadString('');
finally
FreeAndNil(AIMEReg);
end;
end;

const
CnImeRoot =
'Software\Microsoft\CTF\SortOrder\AssemblyItem\0x00000804\{34745C63-B2F0-4784-8B67-5E12C8701A31}';
begin
if CheckWin32Version(6,2) then
begin
AKeyList := TStringList.Create;
AReg := TRegistry.Create;
AList.BeginUpdate;
try
AReg.RootKey := HKEY_CURRENT_USER;
if AReg.OpenKeyReadOnly(CnImeRoot) then
begin
AReg.GetKeyNames(AKeyList);
AReg.CloseKey;
for I := 0 to AKeyList.Count - 1 do
begin
if AReg.OpenKeyReadOnly(CnImeRoot+'\'+AKeyList[I]) then
begin
if AReg.ValueExists('KeyboardLayout') then
ALayout := AReg.ReadInteger('KeyboardLayout')
else
ALayout := 0;
if ALayout > 0 then
AList.Add(NameByLayout)
else if AReg.ValueExists('CLSID') then
AList.Add(NameByClsId(AReg.ReadString('CLSID')));
AReg.CloseKey;
end;
end;
end;
finally
FreeAndNil(AReg);
FreeAndNil(AKeyList);
AList.EndUpdate;
end;
end
else
AList.Assign(Screen.Imes);
end;

黑夜殺手提供的一個設置默認輸入法的函數,提供給需要的朋友:

procedure SetDefaultCNIME(AForm: TForm; IMEKeyStr: string = '五筆');
var
I, idx: Integer;
IMESList: TStringList;
begin
IMESList := TStringList.Create;
EnumImeNames(IMESList);
try
if IMESList.Count > 0 then
begin
{ 開始初始化默認中文輸入法 }
idx := -1;
for I := 0 to IMESList.Count - 1 do
begin
if IMESList[I].Contains(IMEKeyStr) then
begin
idx := I;
Break;
end;
end;
if idx = -1 then
begin
for I := 0 to IMESList.Count - 1 do
begin
if IMESList[I].Contains('拼音') then
// 如果找不到指定的輸入法,則設置為拼音
begin
idx := I;
Break;
end;
end;
end;
if idx = -1 then
begin
if IMESList.Count > 0 then
begin
idx := 0;
end
else
begin
exit;
end;
end;
for I := 0 to AForm.ComponentCount - 1 do
begin
if AForm.Components[I] is TMemo then
TMemo(AForm.Components[I]).ImeName := IMESList[idx];
if AForm.Components[I] is TEdit then
TEdit(AForm.Components[I]).ImeName := IMESList[idx];
if AForm.Components[I] is TLabeledEdit then
TEdit(AForm.Components[I]).ImeName := IMESList[idx];
end;
{ 結束初始化默認中文輸入法 }
end;
finally
IMESList.Free;
end;
end;

【注意】

在執行上述操作之前,請確認已經修改注冊表,允許每個應用獨立控制輸入法,黑夜殺手提供的參考代碼如下:

procedure SetDiffInputMethodInSeperateApp;
//http://superuser.com/questions/839993/find-registry-key-for-windows-8-per-application-input-method-setting
var
AReg: TRegistry;
MyValue: array [0 .. 7] of Byte;
// =[$9e,$1e,$07,$80,$92,$00,$00,$00]; on
// =[$9e,$1e,$07,$80,$12,$00,$00,$00]; off
const
ImeMethodSetRoot =
'Control Panel\Desktop';
begin
if CheckWin32Version(6, 2) then
begin
AReg := TRegistry.Create;
try
AReg.RootKey := HKEY_CURRENT_USER;
if AReg.OpenKey(ImeMethodSetRoot, False) then
begin
if AReg.ValueExists('UserPreferencesMask') then
begin
AReg.ReadBinaryData('UserPreferencesMask', MyValue, 8);
MyValue[4] := $92;
AReg.WriteBinaryData('UserPreferencesMask', MyValue, 8);
end;
AReg.CloseKey;
end;
finally
FreeAndNil(AReg);
end;
end;
end;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM