Помогите с GetKeyboardLayout

Общие вопросы, не зависящие от языка реализации.

Модераторы: Duncon, Hawk, Romeo, Eugie

Ответить
BTGStranger
Сообщения: 6
Зарегистрирован: 18 сен 2010, 10:34

Подскажите пожалуйста, почему не пашет.

Код: Выделить всё

Process [] ps = Process.GeyProcessByName("taskmgr");
Process p = Process.GetProcessById(ps[0].Id);
Console.WriteLine(GetKeyboardLayout(pid)>>16);
Пытаюсь получить раскладку в чужом окне, скажем в диспетчере, но возвращает всегда одно значение.
Раскладку в своем окне GetKeyboardLayout(0) определяет исправно .
Аватара пользователя
Duncon
Сообщения: 2085
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

GeyProcessByName
[syntax=Delphi] [/syntax]
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

1. GetKeyboardLayout() принимает не processId, a threadId - идентификатор потока (http://msdn.microsoft.com/en-us/library ... 85%29.aspx)
2. GetKeyboardLayout() - функция Win32 API, ее нужно вызывать через механизм PInvoke.

Ниже приведен пример опроса раскладок клавиатуры для заданного процесса. Внешний цикл пробегает по копиям процесса, внутренний - по потокам, т.к. у каждого в принципе может быть своя раскладка. В качестве теста можно запустить 2 копии Блокнота, в одном переключить раскладку. Другой интересный пример - процесс devenv (Visual Studio), многопоточный с разными раскладками.

Код: Выделить всё

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Sample
{
    class Program
    {
        [DllImport("user32.dll")]
        public static extern IntPtr GetKeyboardLayout(uint idThread);

        static void Main(string[] args)
        {
            Console.Write("Имя процесса: ");
            string pname = Console.ReadLine();
            Process[] ps = Process.GetProcessesByName(pname);
            foreach (Process p in ps)
            {
                Console.WriteLine("Process instance Id: {0}", p.Id);
                foreach (ProcessThread pt in p.Threads)
                {
                    uint tid = (uint)pt.Id;
                    Console.WriteLine("  ThreadId: {0} KeyboardLayoutId: {1}", tid, GetKeyboardLayout(tid).ToInt32() >> 16);
                }
            }
        }
    }
}
BTGStranger
Сообщения: 6
Зарегистрирован: 18 сен 2010, 10:34

threadId!
В каком-то интернет справочнике видел именно processId - это и сбило столку. Но теперь все работает.
Спасибо, Eugie!
Ответить