Entwickler-Ecke

Windows API - Wie eines der installierten Keyboard-Layouts auswählen


Seven of Nine - So 10.10.10 07:56
Titel: Wie eines der installierten Keyboard-Layouts auswählen
Ziel:
1.) Liste der innerhalb Windows installierten Keyboards "laden" und im Klartext anzeigen ( Deustch (Deutschland) / English (USA) / usw...)
2.) auf ein beliebiges der in dieser Liste angegebenen (und damit instalierten) Keyboard-Layouts umschalten.

Irgendwo fehlt mir da noch etwas

zu 1.) Laden der Liste mache ich so


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
Var
  count : Integer;
  MyLang: PChar;

begin
  //Load all installed KeyboardLayouts
  GetMem(MyLang, Size);
  Count:=GetKeyboardLayoutList(16, Layouts); 

  Memo1.Clear;
  Memo2.Clear;
  for i:=0 to Count-1 do
  begin
    VerLanguageName(Layouts[i], MyLang, Size);
    Memo1.Lines.Add(StrPas(MyLang));    // The name of the installed Layouts
    Memo2.Lines.Add(IntToStr(Layouts[i])); //a "number" of the Layout but in which format??
  end;

end;


soweit so gut, aber mein Problem ist das "umschalten" auf eines der Layouts in der Liste.
Die zu verwendende Prozedur ist ist klar: LoadKeyboardLayout(pcKeyboard, KLF_ACTIVATE);

wobei pcKeayboard eine String-Konstante aus einer Liste ist
(zb '00000409' - english, ', '00000407' - german, ...)

ich möchte aber "nur genau die pcKeyboard's" verwenden die zu meiner oben erstellten Liste gehören
folgender Code funktioniert leider nicht


Delphi-Quelltext
1:
LoadKeyboardLayout(PChar(IntToStr(Layouts[0])), KLF_ACTIVATE);                    


lG Martin


jaenicke - So 10.10.10 08:05

IntToStr fügt keine führenden Nullen hinzu. Dementsprechend ist der entstehende String nicht die ID der gemeinten Sprache.

Belasse die IDs einfach als Strings wie du sie ausliest.


Seven of Nine - So 10.10.10 10:14

Danke zunächst mal für deine Antwort Sebastian.
Ich habe die Codezeile entsprechend abgeändert, also

[delphi]
LoadKeyboardLayout(PChar(Layouts[1]), KLF_ACTIVATE);
[delphi/]

btw: definiert ist -> Layouts : array [0..16] of HKL;

Funzt aber nicht. Wenn ich vergleiche was ich in meinem HKL Memo angezeigt bekomme, dann Stimmern die ermittelten HKLs nicht mit denen aus "pcKeyboard" überein.

Deutsch (Deutschland) -> 67568647(ermittelt s.o.) <> '00000407' - german
Englisch (USA)-> 67699721(ermittelt s.o.) <> '00000409' - english

kann es sein das diese noch umgewandelt werden müssen?

lG Martin


jaenicke - So 10.10.10 10:17

Wie ist Layouts denn deklariert?
// EDIT:
Schon gesehen.

Ein fixed Array ist kein Zeiger. Deshalb musst du hier (bei GetKeyboardLayoutList) mit @Layouts arbeiten um den Pointer auf den Array zu übergeben. Ich frage mich warum das überhaupt zu kompilieren ging. :gruebel:


Seven of Nine - So 10.10.10 10:27

Ähm, ich hoffe das ist für einen "Sonntagmorgen" nicht zu unverschämt: Könntest du mir ein Codeschnipsel dazu posten ?

lG M


jaenicke - So 10.10.10 10:28

Ich habe gerade in Delphi mal selbst nachgeschaut. Da ist das ein var-Parameter, so dass doch kein Pointer übergeben werden muss. Insofern ist das so doch richtig. Ich schau aber einmal.

// EDIT:
Ah, die IDs sind schon richtig. Und wenn du die dann an ActivateKeyboardLayout stattdessen fütterst, dann klappt das auch. ;-)


Seven of Nine - So 10.10.10 10:46

Scheint zu funktionieren. SUPER, das Wochenende scheint gerettet!

Ich überarbeite meine Code nochmals und poste das dann hier im Thread


1000-Dank nochmals für die superflotte Hilfe Sebastian.
Wenn ich könnte würde ich dir dafür 'ne virtuelle Weißwurstbrotzeit rüberschicken ;)

lG M


Seven of Nine - Mo 11.10.10 20:24

0.) zuerst einige Variablen Definitonen

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
const
  Size: Integer = 250;

Var
  MyLang: PChar;
  ActualHKL : HKL;  //beinhaltet später den HKL der aktuell in Windows ausgewählten Sprache
  LayoutsHKL: array [0..16of HKL; // Zum abspeichernm von aktuell bis 16 HKLs. kann natürlich eröht werden...
  Count: Integer ; //ein Zähler



1.) Ermitteln des bei Programmstart in Windows gesetzten Keyboard-Layouts
(um später innerhlab der Applikation wieder darauf zurückschalten können

Delphi-Quelltext
1:
  ActualHKL := GetKeyboardLayout(0);                    


2.) Ermitteln "aller" in Windows installierten Keyborad-Layouts (Anzeigetext und HKL)
zu Test/demozwecken werden hier beide in Memos gespeichert



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
  //Detect all KeyBoardLayouts
  GetMem(MyLang, Size);
  Count:=GetKeyboardLayoutList(16, LayoutsHKL);

  //Clear Memos
  Memo1.Lines.Clear;
  Memo2.Lines.Clear;
 
  for i:=0 to Count-1 do
  begin
    VerLanguageName(LayoutsHKL[i], MyLang, Size);
    Memo1.Lines.Add(StrPas(MyLang));  //Anzeigetexte der Keyboard-Layouts
    Memo2.Lines.Add(IntToStr(LayoutsHKL[i])); //HKLs der der Keyboard-Layouts
  end;
  FreeMem(MyLang);


3.) auf das "x.te" Layout innerhalb der geladenen umschalten
Das erste Layout hat die nr "0", x ist hier eine beliebige Int Variable

Delphi-Quelltext
1:
  ActivateKeyboardLayout(LayoutsHKL[x], 0);                    



4.) auf das bei Programmstart gewählte Layout zurückschalten

Delphi-Quelltext
1:
ActivateKeyboardLayout(ActualHKL, 0);                    



have phun
...Martin