Изменить раскладку клавиатуры для другого процесса

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

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

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

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

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

Когда вы переключаете языки с помощью встроенной в Windows горячей клавиши, это не влияет на разные потоки, не так ли?

JXG 05.11.2008 18:12

переключение раскладки клавиатуры по потоку? В отличие от общесистемного переключения раскладки? Что-то делаете с аккордами?

jcolebrand 01.11.2010 20:13

@drachenstern: не существует такой вещи, как общесистемное переключение раскладки клавиатуры; активная раскладка клавиатуры - это состояние для каждого потока пользовательского интерфейса. Я пытаюсь заменить Alt + Shift, чтобы случайно не нажать, поэтому аккорды не подходят (если я понимаю, что вы имели в виду).

SLaks 01.11.2010 20:21

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

jcolebrand 01.11.2010 22:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
16
4
10 288
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

Взгляни на http://www.codeproject.com/KB/threads/winspy.aspx

Ответ принят как подходящий

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

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

PostMessage(handle, 
    WM_INPUTLANGCHANGEREQUEST, 
    0, 
    LoadKeyboardLayout( StrCopy(Layout,'00000419'), KLF_ACTIVATE)
);

Это отлично работает с GetForegroundWindow для handle. Единственным исключением являются программы WPF, которые, похоже, блокируются в ответ на это сообщение.

Roman Starkov 01.11.2015 17:42

@RomanStarkov Как узнать, какая версия WPF затронута и в чем причина?

Dims 12.04.2019 01:01

@ Dims Я не знаю ни одного из них. Интересно, связана ли причина как-то с это (но это не поможет вам решить проблему)

Roman Starkov 12.04.2019 16:53
  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;

Другие вопросы по теме