Форум: "WinAPI";
Текущий архив: 2005.01.16;
Скачать: [xml.tar.bz2];
ВнизКак отловить событие, когда была переключена раскладка клавиатуры Найти похожие ветки
← →
Dmitry_04 (2004-11-24 23:03) [0]Как отловить событие, когда была переключена раскладка клавиатуры
← →
Dmitry_04 (2004-11-24 23:33) [1]Я обрабатываю сообщение WM_INPUTLANGCHANGEREQUEST , в нем я определяю на какую раскладку поменялась клавиатура... Так вот у меня определяется почему-то какая была, а не какая стала... наверно это объясняется тем, что наверно моя программа определяет быстрее раскладку, чем сама виндовс успевает меняеть раскладку... Так вот есть ли какоенибудь сообщение, когда уже поменялась раскладка клавиатуры...
← →
Юрий Зотов © (2004-11-24 23:43) [2]Естественно, это же Request - запрос. Конечно, он приходит ПОСЛЕ того, как раскладку переключил ЮЗЕР, но ДО то того, как ее реально переключит СИСТЕМА. Программа ведь может и запретить переключение - вот зачем это нужно.
Но есть еще и WM_INPUTLANGCHANGE.
← →
Dmitry_04 (2004-11-24 23:50) [3]а обрабатывая это сообщение что-то совсем не работает...
← →
Игорь Шевченко © (2004-11-25 01:05) [4]http://www.schevchenko.net.ru/SRC/EnumFunctions_60.zip
← →
Dmitry_04 (2004-11-25 01:21) [5]Я уже там смотрел :)
← →
Leonid Troyanovsky (2004-11-25 09:20) [6]
> Dmitry_04 (24.11.04 23:03)
> Как отловить событие, когда была переключена раскладка клавиатуры
http://groups.google.com/groups?selm=a4gdj7%245j%241574%40www.fido-online.com
--
С уважением, LVT.
← →
Dmitry_04 (2004-11-25 15:35) [7]т.е. обрабатывать сообщение HSHELL_LANGUAGE ? Я так понимаю?
← →
Dmitry_04 (2004-11-25 15:37) [8]или там как-то с хуками?
← →
Dmitry_04 (2004-11-25 16:50) [9]из примера который дал Leonid Troyanovsky
http://groups.google.com/groups?selm=a4gdj7%245j%241574%40www.fido-online.com
Я сделал вот как:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, AppEvnts;
type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
ApplicationEvents1: TApplicationEvents;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure GetKeyboardLanguage;
private
{ Private declarations }
public
{ Public declarations }
end;
type
TResultData = record
ALParam: LParam;
Path : array [0..MAX_PATH] of Char;
end;
PResultData = ^TResultData;
procedure SetShellHook(AHWND:HWND; AMsg: UINT); external "shlhook.dll";
function GetResult: PResultData; external "shlhook.dll";
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.GetKeyboardLanguage;
begin
Label1.Caption:="";
case GetKeyboardLayout(0) of
67240962: Label1.Caption:="BG";
67437573: Label1.Caption:="CS";
67503110: Label1.Caption:="DA";
67568647: Label1.Caption:="DE";
67634184: Label1.Caption:="EL";
67699721: Label1.Caption:="EN";
67765258: Label1.Caption:="ES";
67830795: Label1.Caption:="FI";
67896332: Label1.Caption:="FR";
68027406: Label1.Caption:="HU";
68092943: Label1.Caption:="IS";
68158480: Label1.Caption:="IT";
68355091: Label1.Caption:="NL";
68420628: Label1.Caption:="NO";
68486165: Label1.Caption:="PL";
68551702: Label1.Caption:="PT";
68682776: Label1.Caption:="RO";
68748313: Label1.Caption:="RU";
68813850: Label1.Caption:="HR";
68879387: Label1.Caption:="SK";
68944924: Label1.Caption:="SQ";
69010461: Label1.Caption:="SV";
69141535: Label1.Caption:="TR";
69338146: Label1.Caption:="UK";
69403683: Label1.Caption:="BE";
69469220: Label1.Caption:="SL";
69534757: Label1.Caption:="ET";
69600294: Label1.Caption:="LV";
69665831: Label1.Caption:="LT";
69993516: Label1.Caption:="AZ";
70190127: Label1.Caption:="MK";
70779960: Label1.Caption:="FO";
70911034: Label1.Caption:="ML";
70976571: Label1.Caption:="NO";
71238719: Label1.Caption:="KK";
71304256: Label1.Caption:="KY";
71566404: Label1.Caption:="TT";
71631941: Label1.Caption:="BN";
72090700: Label1.Caption:="MY";
72352848: Label1.Caption:="MO";
72483922: Label1.Caption:="EN";
75564161: Label1.Caption:="MR";
135661590: Label1.Caption:="PT";
135923738: Label1.Caption:="SR";
137103404: Label1.Caption:="AZ";
138610755: Label1.Caption:="UZ";
203033626: Label1.Caption:="SR";
269225996: Label1.Caption:="FR";
337253402: Label1.Caption:="BS";
403249161: Label1.Caption:="EN";
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
SetShellHook(Handle, WM_USER+1);
GetKeyboardLanguage;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
GetKeyboardLanguage;
end;
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
if Msg.lParam=HSHELL_LANGUAGE then GetKeyboardLanguage;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SetShellHook(0, 0);
end;
end.
Все работает, только вот почему-то событие ловится один раз... Второй раз когда переключишь раскладку уже не ловится... Что не так?
← →
Dmitry_04 (2004-11-25 18:13) [10]Удалено модератором
Примечание: Создание пустых сообщений
← →
Dmitry_04 (2004-11-25 22:15) [11]Удалено модератором
Примечание: Создание пустых сообщений
← →
Leonid Troyanovsky (2004-11-26 10:46) [12]
> Dmitry_04 (25.11.04 16:50) [9]
> из примера который дал Leonid Troyanovsky
>
> http://groups.google.com/groups?selm=a4gdj7%245j%241574%40www.fido-online.com
>
> Я сделал вот как:
Немного не то.
Во-первых, нет нужды перечислять короткие имена языков.
Посмотри мое сообщение в
http://delphimaster.net/view/4-1101255335/
Во-вторых, для формы сделать обработчик WM_USER+1 (см. пример)
в котором и расшифровывать сообщение о изменении языка,
т.е. msg.WPARAM, который будет содержать новый hkl
(то же самое, что обычно возвращает GetKeyboardLayout).
Ну, а твой вызов GetKeyboardLayout(0) дает лишь раскладку
своего потока.
--
С уважением, LVT.
← →
Dmitry_04 (2004-11-26 16:12) [13]Я сейчас посмотрел чему равны константы: LANG_ENGLISH, LANG_RUSSIAN, и что-то не очень понял.... $<число>. Что значит этот знак доллара $ ?
← →
Dmitry_04 (2004-11-27 00:13) [14]Что-то у меня всеравно не работает... Leonid Troyanovsky Помоги!!! При смене языка ничего не определяет... А при запуске программы определяет только английский, если он стоит по умолчанию, русский, если стоит по умолчанию не определяет... Но самое интересное то, что при нажатии на кнопку все определяется, и русский и английский. Вот код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure WmUser1(var Message: TMessage); Message WM_USER+1;
private
{ Private declarations }
public
{ Public declarations }
end;
type
TResultData = record
ALParam: LParam;
Path : array [0..MAX_PATH] of Char;
end;
PResultData = ^TResultData;
procedure SetShellHook(AHWND:HWND; AMsg: UINT); external "shlhook.dll";
function GetResult: PResultData; external "shlhook.dll";
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
SetShellHook(Handle, WM_USER+1);
case GetKeyboardLayout(GetWindowThreadProcessID(GetForegroundWindow, nil)) and $3FF of
LANG_ENGLISH: Label1.Caption := "EN";
LANG_RUSSIAN: Label1.Caption := "RU";
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption:="";
case GetKeyboardLayout(GetWindowThreadProcessID(GetForegroundWindow, nil)) and $3FF of
LANG_ENGLISH: Label1.Caption := "EN";
LANG_RUSSIAN: Label1.Caption := "RU";
end;
end;
procedure TForm1.WmUser1(var Message: TMessage); // Message WM_USER+1
begin
if Message.LParam = HSHELL_LANGUAGE then
begin
Label1.Caption:="";
case Message.WParam and $3FF of
LANG_ENGLISH: Label1.Caption := "EN";
LANG_RUSSIAN: Label1.Caption := "RU";
end;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SetShellHook(0, 0);
end;
end.
← →
Игорь Шевченко © (2004-11-27 01:27) [15]А мой пример не работает ? :)
← →
Dmitry_04 (2004-11-27 02:00) [16]Он работает, только я как понял вот как... В начале в ListBox считывает все раскладки которые стоят на компъютере... А потом по очереди показывает какая стоит расскладка, при ее смене... Но мне не нужен ListBox и вообще TStrings...
← →
Игорь Шевченко © (2004-11-27 12:19) [17]Dmitry_04 (27.11.04 02:00) [16]
> Но мне не нужен ListBox и вообще TStrings...
А...можно узнать, почему ?
← →
Dmitry_04 (2004-11-27 15:43) [18]Как тебе объяснить... мне нужно чтобы в Label-е показывалась расскладка, и все... При вводе пароля :) А зачем мне это в ListBox-е показывать? Хотя можно конечно создать TStrings и чтобы он висел в памяти...
← →
GanibalLector © (2004-11-28 02:19) [19]У меня прекрасно работает этот код:(причем без всяких там dll и WM_INPUTLANGCHANGE)
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
if Msg.message = WM_INPUTLANGCHANGEREQUEST then begin
if Msg.lParam=68748313 then Label1.Caption:="rus" ;
if Msg.lParam=69338146 then Label1.Caption:="ukr" ;
if Msg.lParam=67699721 then Label1.Caption:="en" ;
end;
← →
GanibalLector © (2004-11-28 02:20) [20]забыл это :
procedure TForm1.FormCreate(Sender: TObject);
begin
if GetKeyboardLayout(0)=68748313 then Label1.Caption:="rus" ;
if GetKeyboardLayout(0)=69338146 then Label1.Caption:="ukr" ;
if GetKeyboardLayout(0)=67699721 then Label1.Caption:="en" ;
end;
← →
grom (2004-11-28 12:16) [21]http://delphi.vitpc.com/asp/answer.asp?IDAnswer=24922
← →
Leonid Troyanovsky (2004-11-29 15:28) [22]
> Dmitry_04 (27.11.04 00:13) [14]
> Что-то у меня всеравно не работает... Leonid Troyanovsky
> Помоги!!! При смене языка ничего не определяет... А при
> запуске программы определяет только английский, если он
> стоит по умолчанию, русский, если стоит по умолчанию не
> определяет... Но самое интересное то, что при нажатии на
> кнопку все определяется, и русский и английский. Вот код:
Виноват, немного попутал. В том коде, который я давал
hkl передается в mmf: ALParam, т.е. GetResult.ALparam.
Хотя, конечно, если данная библиотека используется
только для отслеживания раскладки, то его (hkl)
лучше посылать прямо в одном из параметров сообщения.
Кроме того, лучше использовать PostMessage instead Send
(в приведеном коде Send нужен был для синхронизации,
т.к. передавалось еще имя экзешника).
PostMessage здесь лучше тем, что SendMessage будет мешать
отладке приложения.
--
С уважением, LVT.
← →
Dmitry_04 (2004-11-29 15:59) [23]А я тут придумал вот как... все работает и все просто...
procedure TForm1.FormCreate(Sender: TObject);
var
tmp : array[0..255] of char;
begin
GetLocaleInfo(LOWORD(GetKeyboardLayout(0)), LOCALE_SABBREVLANGNAME, tmp, SizeOf(tmp));
tmp[2] := " ";
Label1.Caption:=tmp;
end;
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
var
tmp : array[0..255] of char;
begin
if Msg.message = WM_INPUTLANGCHANGEREQUEST then
begin
GetLocaleInfo(LOWORD(Msg.lParam), LOCALE_SABBREVLANGNAME, tmp, SizeOf(tmp));
tmp[2] := " ";
Label1.Caption:=tmp;
end;
end;
← →
Leonid Troyanovsky (2004-11-30 10:14) [24]
> Dmitry_04 (29.11.04 15:59) [23]
> А я тут придумал вот как... все работает и все просто...
Ясное дело, со своим потоком можно просто.
--
С уважением, LVT.
ЗЫ События бывают разные.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.01.16;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.04 c