Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Как отловить момент смены раскладки?


Автор: timself 20.10.2008, 17:05
Подскажите, пожалуйста, как в своей программе отловить момент смены раскладки клавиатуры (языка ввода). Причем не важно как она происходит, программно или по нажатию Ctrl+Shift, или еще как, тут важен сам факт. Какие языки в системе - тоже не важно. 
Отлов нажатия спец. клавиш мне не подходит:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;  Shift: TShiftState);
Код

begin
    if ((ssCtrl in Shift) and (ssShift in Shift)) or
       ((ssAlt in Shift) and (ssShift in Shift)) or (Key=192) then
       begin
       // <----- тут проверка...
       // ...она опережает момент смены раскладки (!)
       end;
end;

Пробовал делать и так:
Код

procedure TForm1.Timer1Timer(Sender: TObject);
begin
   if GetKeyboardLayout(0) = 67699721 then Label1.Caption:='EN'
   else Label1.Caption:='RU';   
end;

Это работает. Но это тупо! (тут каждые полсекунды таймер проверяет раскладку). 
Может система выдает сообщение о смене раскладки? Подскажите как сделать...

Автор: Rrader 20.10.2008, 17:36
Ловить сообщение WM_INPUTLANGCHANGEREQUEST

Автор: timself 20.10.2008, 22:58
А можно пример, хоть простенький, как отловить это сообщение?
(с синтаксисом не особо знаком)

Автор: Christoph 21.10.2008, 00:07
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
  procedure CatchTheMess(var Message: TMessage); message WM_INPUTLANGCHANGEREQUEST;
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.CatchTheMess(var Message: TMessage);
begin
  ShowMessage('Переключили клавиатуру');
end;

end.


Catch The Mess ;)

Автор: Frees 21.10.2008, 06:35
Christoph, ммм у меня не работает, потому что виста. если ОС виста то я по таймеру смотрю какой язык, но наверно есть болие лучшее решение.

Автор: Christoph 21.10.2008, 08:59
Frees, на ХР работает, мне кажется что это самый простой способ словить сообщение smile

Автор: Frees 21.10.2008, 10:35
Christoph, согласен что самый простой, тока хочется что бы и в висте работало, может для вистой месагу другую надо ловить

Автор: MetalFan 21.10.2008, 11:57
в инете однозначного решения проблемы не нашел, но народ тоже с эти сталкивается.
имхо надо копать в сторону ITfLanguageProfileNotifySink

Автор: Poseidon 21.10.2008, 11:59
 smile 

Christoph, про соглашение об именах процедур что-нить читал?

Автор: timself 21.10.2008, 15:18
Надо так делать..., но не могу теперь установить локальный хук!  (Vista)
Копилятор стопорится на SetWindowsHookEx.
Пишет, что:   Incompartible tipes: "Integer" and "Cardinal"
Где тут ошибка ???   Ничего не пойму...
Код

var
  Form1: TForm1;
  FMsgHook:HHOOK;
...
function MsgHookProc(nCode:Integer;wParam:UINT;lParam:UINT):LRESULT; stdcall;
begin
  if nCode>=0 then
  if (PMsg(lParam).message=WM_INPUTLANGCHANGEREQUEST) or
  (PMsg(lParam).message=WM_INPUTLANGCHANGE) then beep;
  Result:=CallNextHookEx(FMsgHook,nCode,wParam,lParam);
end;
...
// установка ловушки
procedure TForm1.Button1Click(Sender: TObject);
begin
  // ниже вылазит ошибка...
  FMsgHook:=SetWindowsHookEx(WH_GETMESSAGE,MsgHookProc,0,GetCurrentThreadId);
  Win32Check(FMsgHook<>0);
end;
...

Автор: Christoph 21.10.2008, 15:27
Цитата(Poseidon @ 21.10.2008,  11:59)
smile 

Christoph, про соглашение об именах процедур что-нить читал?

Я Исправлюсь  smile 

Автор: MetalFan 21.10.2008, 18:47
сверь типы параметров у SetWindowsHookEx

Автор: timself 21.10.2008, 23:02
Спасибо, с этим я разобрался, там ошибка синтаксиса MsgHookProc вместо @MsgHookProc.
Но WM_INPUTLANGCHANGE и WM_INPUTLANGCHANGEREQUEST всё равно не ловятся под OS Vista.
Перепробывал все варианты, не отлавливается, и всё тут. Может в Висте другое сообщение при смене раскладки... Это напасть какая-то.

Автор: Christoph 21.10.2008, 23:49
Может быть ActivateKeyboardLayout, но я не знаю подойдет ли для твоей задачи или нет :(

Автор: timself 22.10.2008, 22:47
Проблема решена обходным методом. Сообщение так и не удалось поймать...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)