Изменить раскладку клавиатуры для другого процесса - PullRequest
15 голосов
/ 04 ноября 2008

Я пишу программу на C #, которая работает в фоновом режиме и позволяет пользователям использовать горячие клавиши для переключения раскладок клавиатуры в активном окне. (Windows поддерживает только CTRL + SHIFT и ALT + SHIFT )

Я использую RegisterHotKey, чтобы поймать горячую клавишу, и она работает нормально.

Проблема в том, что я не могу найти API для изменения раскладки клавиатуры для сфокусированного окна.

ActivateKeyboardLayout и LoadKeyboardLayout могут изменять только раскладку клавиатуры для вызывающего потока.

Кто-нибудь знает, как изменить раскладку клавиатуры для другого потока (как это делает языковая панель)?

Ответы [ 4 ]

8 голосов
/ 22 апреля 2010
PostMessage(handle, 
    WM_INPUTLANGCHANGEREQUEST, 
    0, 
    LoadKeyboardLayout( StrCopy(Layout,'00000419'), KLF_ACTIVATE)
);
2 голосов
/ 05 ноября 2008

Я думаю, уловка состоит в том, чтобы заставить ваш код выполняться в контексте потока, раскладку клавиатуры которого вы хотите изменить. Вам нужно будет поработать над Win32 и узнать об DLL Injection, чтобы ваш код выполнялся в удаленном потоке.

A обработчик крюка клавиатуры выглядит здесь как хороший вариант.

Посмотрите на http://www.codeproject.com/KB/threads/winspy.aspx

1 голос
/ 09 февраля 2009

Другой способ, который может быть приемлем, если вы пишете что-то только для себя: определите отдельную комбинацию клавиш для каждой раскладки (например, Alt + Shift + 1 и т. Д.) И используйте SendInput для переключения между им.

Обстоятельства, при которых это можно использовать, ограничены, конечно.

0 голосов
/ 22 апреля 2010
  function ChangeRemoteWndKeyboardLayoutToRussian(
    const RemoteHandle: THandle): Boolean;
  var
    Dumme: DWORD;
    Layout: HKL;
  begin
    Layout := LoadKeyboardLayout('00000419', KLF_ACTIVATE);
    Result := SendMessageTimeOut(RemoteHandle, WM_INPUTLANGCHANGEREQUEST,
      0, Layout, SMTO_ABORTIFHUNG, 200, Dumme) <> 0;
    if Result then    
      Result := SendMessageTimeOut(RemoteHandle, WM_INPUTLANGCHANGEREQUEST,
        RUSSIAN_CHARSET, Layout, SMTO_ABORTIFHUNG, 200, Dumme) <> 0;
  end;
...