Keyboard Switching

{////////////////////////////////////////////////////////////
 LAYUNIT: Shows how to implement keyboard switching within a
          task and to determine current layout
  NOTE: Works only with two layouts - eg English/Russian
/////////////////////////////////////////////////////////////}
unit Lay_Unit;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;
type
  TMyForm = class(TForm)
  end;
  TForm1 = class(TMyForm)
    Edit1: TEdit;
    Memo1: TMemo;
    Label1: TLabel;
    GroupBox1: TGroupBox;
    RadioButton1: TRadioButton;
    RadioButton2: TRadioButton;
    procedure FormCreate(Sender: TObject);
    procedure ShowLayoutName;
    procedure LoadLayouts;
    procedure SwitchLayout(Layout : Bool);
    procedure RadioButton1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

{Common Layouts}
Const
 CyrLayout : String = '00000419'; {LANG_RUSSIAN}
 LatLayout : String = '00000409'; {LANG_ENGLISH}
var
  Form1    : TForm1;
  hCyr     : HKL;   {Handle to Cyr layout}
  hLat     : HKL;   {Handle to Lat layout}
implementation
{$R *.DFM}
procedure TForm1.ShowLayoutName;
Var
 LayoutName : Array [0..KL_NAMELENGTH] of Char;
 LangName   : Array [0..63] of Char;
begin
 GetKeyboardLayoutName(@LayoutName);
 GetLocaleInfo(StrToInt('$'+LayoutName), LOCALE_SENGLANGUAGE, @LangName, 64);
 Edit1.Text := LangName;
{To avoid error it the first call from TForm.Create, since Memo
 is no created when ShowLayoutName is called}
 ActiveControl := Memo1;
end;
{Initial procedure - get handles to Lat and Cyr layouts}
procedure TForm1.LoadLayouts;
begin
 hCyr := LoadKeyboardLayout(@CyrLayout, KLF_ACTIVATE);
 hLat := LoadKeyboardLayout(@LatLayout, KLF_ACTIVATE);
end;
procedure TForm1.SwitchLayout;
begin
 if Layout then ActivateKeyboardLayout(hCyr,0)
 else  ActivateKeyboardLayout(hLat,0);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
 LoadLayouts;
 SwitchLayout(RadioButton1.Checked);
 ShowLayoutName;
{Can't call SetFocus on Memo since it is not created yet!}
 ActiveControl := Memo1;
end;
{Works for both radiobuttons - simply switches the layout}
procedure TForm1.RadioButton1Click(Sender: TObject);
begin
 SwitchLayout((Sender as TRadioButton).Checked);
 ShowLayoutName;
end;
end.