在注册表里改了输入法的顺序了,怎样让新的顺序立即生效?(200分)

  • 主题发起人 主题发起人 悲酥清风
  • 开始时间 开始时间

悲酥清风

Unregistered / Unconfirmed
GUEST, unregistred user!
像用添加/删除输入法那样,完成后立即就能显示出来。
 
SystemParametersInfo
 
关注,我也想知道.谁有更详细一点代码.
 
procedure TForm1.Button5Click(Sender: TObject);
begin
SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, nil, 0);
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
;SystemParametersInfo(SPI_SCREENSAVERRUNNING, 0, nil, 0);
end;
 
查了半天SystemParametersInfo函数的参数取值,
好像没有跟输入法顺序有关的。
 
既然该了注册表,就让window知道注册表改啦!
SystemParametersInfo里有个参数是通知系统注册表跟改的!
fWinIni

If a system parameter is being set, specifies whether the user profile is to be updated, and if so,
whether the WM_SETTINGCHANGE message is to be broadcast to all top-level windows to notify them of the change.
This parameter can be zero or can be one of the following values:

Value Action
SPIF_UPDATEINIFILE Writes the new system-wide parameter setting to the user profile.
SPIF_SENDCHANGE Broadcasts the WM_SETTINGCHANGE message after updating the user profile.
SPIF_SENDWININICHANGE Same as SPIF_SENDCHANGE.
 
to SINGLBOY:
; 我试了三个参数,都没有用:(
 
关注 好像以前有过这方面资料的 现在找不到了[:(]
 
直接发个消息试试
An application can send WM_SETTINGCHANGE to all top-level windows when it makes changes to system parameters.
For example, you can send this message after a call to the WriteProfileString, WriteProfileSection, or SetLocaleInfo functions,
or after making changes to system parameters in the registry.

The WM_SETTINGCHANGE message is the same as the older WM_WININICHANGE message.

WM_SETTINGCHANGE ;
wParam = wFlag; ; ; ; ; ; ; ; ; ; ; ; ; // system-wide parameter flag
lParam = (LPARAM) (LPCTSTR) pszSection; // name of changed section or registry
 
To SingleBoy:
  主要问题SystemParametersInfo的第一个参数取什么?
  大概看了一下帮助,第一个参数没有什么合适的取值
 
用SendMessage发送WM_SETTINGCHANGE消息看看?把lParam传入注册表相应的Key!
 
先把你写注册表的代码贴上来?
我好拷下来作试验,看我的方法可不可以,免得我重写你写过的代码。
 
代码:
 ; TIme= Record
 ;  ; Code: string;  ; //保存输入法在注册表里对应的代码
 ;  ; Name: string;  //保存输入法显示的中文名
 ; end;
 ; TfrmMain = class(TForm)
......
 ; private
 ;  ; ime: array of TIme;  ;//保存所有可显示的输入法
......
procedure TfrmMain.SetReg(ListBox: TListBox; NewOrder,OldOrder: integer);
var
 ; Reg: TRegistry;
 ; i: integer;
 ; OldIME, NewIME: TIME;
 ; strList: TStringList;
begin
 ; Reg:= TRegistry.Create;
 ; strList:= TStringList.Create;
 ; try
 ;  ; //HKEY_CURRENT_USER/Keyboard Layout/Preload
 ;  ; Reg.RootKey:= HKEY_CURRENT_USER;
 ;  ; if Reg.OpenKey('/Keyboard Layout/Preload',true) then
 ;  ; begin
 ;  ;  ; for i:=0 to lsbIME.Count-1 do
 ;  ;  ; begin
 ;  ;  ;  ; if ime[i].Name= lsbIME.Items[OldOrder] then OldIME:= ime[i];
 ;  ;  ;  ; if ime[i].Name= lsbIME.Items[NewOrder] then NewIME:= ime[i];
 ;  ;  ; end;
 ;  ;  ; Reg.WriteString(IntToStr(NewOrder+1),OldIME.Code);
 ;  ;  ; Reg.WriteString(IntToStr(OldOrder+1),NewIME.Code);
 ;  ; end;
 ;  ; Reg.CloseKey;
 ; finally
 ;  ; strList.Free; 
 ;  ; Reg.Free;
 ; end;
end;
 
试试:
SendMessage(HWND_BROADCAST,WM_WININICHANGE,0,LongInt(PChar('WINDOWS')));
或是:
;SendMessage(HWND_BROADCAST,WM_WININICHANGE,0,LongInt(nil));
 
To 杜宝:
  还是不行呀,右下角的输入法顺序还是纹丝不动:(

To All:
  有没有办法得到正在运行的internat.exe的句柄?
 
啊,是要这种效果啊!不知道,
建议看看WM_IME_XXXXX和IMC_XXX的消息
 
我编写了一个实时调整输入法顺序的程序,如谁需要请给我来信?
sy.zhu@sohu.com
 
我还是把我的关于此问题的文章贴出来,供大家传阅.

不用重启实现输入法顺序调整
朱三元
在很多电脑报刊杂志上刊登过调整输入法顺序的方法,其原理是更改注册表中键盘设置的顺序,无论是手工还是编程来实现,作者在最后还得补充一句:重启后才有效。在当前流行的各种设置软件如:超级兔子魔法设置,优化大师等也都必须重启。难道就不能实现实时调整? 本人经过摸索,掌握了输入法设置的有关特性,实现了实时调整。
实现原理:在Windows系统中,输入法是与键盘布局(keyboard layout)相对应的。(详情请见有关文章)首先,用获取当前所装的键盘布局,放到数组中,将数组中的键盘布局的句柄按要求调整顺序,然后,卸载当前所有的输入法,最后,按调整后的顺序重新装载输入法。
要实现实时调整,须使用到下面的API函数:
1. BOOL UnloadKeyboardLayout( ; //卸载指定的键盘布局;该函数只是将其从键盘列表中删除,并不卸载与之对应的文件,;
; ; HKL hkl // 键盘布局的句柄;
; ;);
函数返回:如果成功,返回非0值
2. HKL LoadKeyboardLayout( ;//装载新的键盘布局;
; ; LPCTSTR pwszKLID, // 键盘布局的名称;
; ; UINT Flags // 装载键盘布局的选项;
; ;);
函数返回: ;如果成功,返回安装的键盘布局的句柄, 否则返回NULL。
(超级的下一版本应能有此功能,因我已告诉其作者)
下面的源程序在win9x/win2000下编译通过:
unit Unit1;
interface
uses
; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
; ComCtrls, StdCtrls, Buttons,shellapi,Imm,Registry, ExtCtrls;
CONST nHKL_LIST=20;

type
; LangDescription=record
; ; sID,sCode,sName:string;
; end;
; TLangDescription=array of LangDescription;
; TImeItem = record
; ; MainIndex:Integer;
; ; ImeDescription:string;
; ; KeyBoardLayout:HKL;
; end;
; TImeItemArray=array of TImeItem;
; TForm1 = class(TForm)
; ; ListView1: TListView;
; ; upBitBtn: TBitBtn;
; ; downBitBtn: TBitBtn;
; ; Button1: TButton;
; ; Panel1: TPanel;
; ; procedure FormCreate(Sender: TObject);
; ; procedure ButtonClick(Sender:TObject);
; ; procedure ApplyUpdate(Sender:Tobject);
; ; procedure ListView1SelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
private
; Function GetLangSet():Boolean;
; Function WriteRegistry():boolean;
; Procedure GetAndDislpayCurrentLangSet;
; procedure FillInListView;

; ; ;{ Private declarations }
public
; ; { Public declarations }
; end;
var
; Form1: TForm1;
; LangSet:TLangDescription;
; TImeItemList:TImeItemArray;
; ImeCounter,CurrentPos:integer;
; ListItem: TListItem;
implementation
{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
; if not GetLangSet() then begin
; ; ShowMessage('Error in accessing Registry.');
; ; Halt;
; end;
; GetAndDislpayCurrentLangSet;
; ListView1.Columns[0].Width := ColumnTextWidth;
; FillinListView;
end;

Function TForm1.GetLangSet():Boolean; //获取系统所支持所所有西文输入法
var
; Reg: TRegistry;
; Val:TStringList;
; i,j,iPos:Integer;
; str1: string;
begin
; Reg:=TRegistry.Create;
; try
; ; Val:=TStringList.Create;
; ; try
; ; ; Reg.RootKey:=HKey_Classes_Root;
; ; ; if not Reg.OpenKey('/MIME/DATABASE/RFC1766',False) then
; ; ; ; result:=false
; ; ; else ;begin
; ; ; ; Reg.GetValueNames(Val);
; ; ; ; SetLength(Langset,Val.Count);
; ; ; ; for i:=0 to Val.Count-1 do ;begin
; ; ; ; ; LangSet.sID:=val.strings;
; ; ; ; ; str1:=Reg.ReadString(Val.Strings);
; ; ; ; ; LangSet.sCode:=UpCase(str1[1])+LowerCase(str1[2]);
; ; ; ; ; iPos:=AnsiPos(';',str1);
; ; ; ; ; for j:=iPos+1 to length(str1) do LangSet.sName:=LangSet.sName+str1[j];
; ; ; ; end;
; ; ; ; Result:=True;
; ; ; end;
; ; finally
; ; ; Val.Free;
; ; end;
; finally
; ; Reg.Free;
; end;
end;

procedure TForm1.GetAndDislpayCurrentLangSet;
var ;i,j: integer;
; pList: array[0..nHKL_List] of HKL;
; buff: array[0..Max_Path] of char;
; s: string;
begin
; ImeCounter:= GetKeyboardLayoutList(nHKL_LIST, pList);
; Setlength(TImeItemList,ImeCounter);
; for i:=0 to ImeCounter-1 do begin
; ; if ;not ImmIsIME(plist) then ; begin //西文输入法
; ; ; ;Plist:=PList and $ffff;
; ; ; ;for j:=low(LangSet) to high(Langset) do ;if LangSet[j].sID=IntToHex(Plist mod $10000,4) then break;
; ; ; ;s:=LangSet[j].sName;
; ; ; ;end
; ; else begin ;//中文输入法
; ; ; ImmGetDescription(pList, Buff, MAX_PATH);
; ; ; s := string(buff);
; ; end;
; ; with TImeItemList do begin
; ; ; MainIndex:=i;
; ; ; ImeDescription:=s;
; ; ; KeyBoardLayout:=pList;
; ; end;
; end;
end;

procedure TForm1.FillInListView;
var i:integer;
begin
; with ListView1 do
; ; for i:=0 to ImeCounter-1 do begin
; ; ; ; ListItem := Items.Add;
; ; ; ; Listitem.Caption :=TImeItemList.ImeDescription;
; ; end;
end;

procedure TForm1.ButtonClick(Sender:TObject);
var i,step:integer;
begin
;if Sender=upBitBtn then step:=-1 else Step:=1; //代码重用
;If ((CurrentPos<ImeCounter-1) and (step=1)) or ((CurrentPos>0) and (Step=-1)) then begin
; ;for i:=0 to ImeCounter-1 do begin
; ; ; if (TimeItemList.MainIndex=CurrentPos) then
; ; ; ; ; TImeItemList.MainIndex :=TImeItemList.MainIndex +Step
; ; ; else ;if TimeItemList.MainIndex=CurrentPos+Step then
; ; ; ; ; TImeItemList.MainIndex :=TImeItemList.MainIndex -Step
; ; end;
; ; for i:=0 to ImeCounter-1 do begin
; ; ; if TimeItemList.MainIndex=CurrentPos then
; ; ; ; with ;ListView1 do begin
; ; ; ; ; ListItem:=Items.Item[CurrentPos];
; ; ; ; ; ListItem.Caption:=TImeItemList.ImeDescription;
; ; ; ; end
; ; ; else if TimeItemList.MainIndex=CurrentPos+Step then
; ; ; ; ;with ;ListView1 do begin
; ; ; ; ; ListItem:=Items.Item[CurrentPos+Step];
; ; ; ; ; ListItem.Caption:=TImeItemList.ImeDescription;
; ; ; ; ;end;
; ; end;
; ; CurrentPos:=CurrentPos+Step;
; end;
; ListView1.setfocus;
; with ;ListView1 do begin
; ; ; ListItem:=Items.Item[CurrentPos];
; ; ; listItem.selected:=true;
; ; ; ListItem.focused:=true;
; end;
end;

procedure TForm1.ApplyUpdate(Sender:Tobject);
var Kblayout: array [0..8] of char;
; ; i,k: integer;
; ; blModiReg:Boolean;
begin
; if Application.MessageBox('是否保留该配置,以便下次开机继续有效?','提醒:',
; ; ; ; MB_YESNO) = IDYES then blModiReg:=True else blModiReg:=False;
; for i := low(TImeItemList) to High(TImeItemList) do ;// 卸载输入法
; ; UnLoadKeyBoardLayout(TImeItemList.KeyBoardLayout);
; for i := high(TImeItemList) ;downto low(TImeItemList) do begin ;//重新装载输入法
; ; k:=0;
; ; while (TImeItemList[k].MainIndex<>i) and (k<=Imecounter-1)do inc(k);
; ; if k<> ImeCounter then begin
; ; ; strPCopy(Kblayout, inttohex(TImeItemList[k].KeyBoardLayout,8));
; ; ; LoadKeyBoardLayout(Kblayout,KLF_ACTIVATE+KLF_REPLACELANG+KLF_REORDER);
; ; end;
; end;
; if blModiReg then WriteRegistry;
end;

Function TForm1.writeRegistry():boolean;
var Reg: TRegistry;
; ; i,j:Integer;
begin
; Reg:=TRegistry.Create;
; try
; ; ; Reg.RootKey:=HKey_Current_User;
; ; ; i:=0;
; ; ; while ;Reg.OpenKey('/Keyboard Layout/Preload/'+inttostr(i+1),False) do begin
; ; ; ; j:=0;
; ; ; ; while (TImeItemList[j].MainIndex<>i) and (j<=Imecounter-1)do inc(j);
; ; ; ; Reg.writestring('',inttohex(TImeItemList[j].KeyBoardLayout,8));
; ; ; ; inc(i);
; ; ; ; reg.closekey;
; ; ; end;
; ; ; if i=ImeCounter then result:=true else result:=false;
; finally
; ; Reg.Free;
; end;
end;
procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
begin
; CurrentPos:=Item.index;
end;
end.
 
后退
顶部