Как найти текущий язык ввода - PullRequest
0 голосов
/ 17 января 2019

Я пытаюсь создать программу, которая получает имя процесса, находит его идентификатор, а затем находит язык с помощью функции GetKeyboardLayout.

Хотя у меня трудности, и, похоже, это не работает. Он находит processID, хотя возвращаемый язык всегда 00000000.

Это мой код:

#include <iostream>
#include <windows.h>
#include <string>
#include <tlhelp32.h>

DWORD FindProcessId(LPCTSTR ProcessName);

int main() {
    HKL currentKBLayout;
    DWORD processID;

    LPCTSTR processName = "chrome.exe";
    while (true) {
            processID = FindProcessId(processName);
            if (processID == 0); // TODO: pause system for 5 seconds
            else { 
                currentKBLayout = GetKeyboardLayout(processID);
                std::cout << processID << " | "<< currentKBLayout << std::endl;
            }
    }
    system("pause");
    return 0;
}
DWORD FindProcessId(LPCTSTR ProcessName)
{
    PROCESSENTRY32 pt;
    HANDLE hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    pt.dwSize = sizeof(PROCESSENTRY32);
    if (Process32First(hsnap, &pt)) { // must call this first
        do {
            if (!lstrcmpi(pt.szExeFile, ProcessName)) {
                CloseHandle(hsnap);
                return pt.th32ProcessID;
            }
        } while (Process32Next(hsnap, &pt));
    }
    CloseHandle(hsnap); // close handle on failure
    return 0;
}


1 Ответ

0 голосов
/ 17 января 2019

Я согласен с комментарием Ремиса об использовании более простого способа получить раскладку клавиатуры для процессов, если это все, что вам нужно. Однако, если вы заинтересованы в добавлении дополнительной информации к вашему текущему подходу с использованием снимков, это может быть началом. Он делает снимок всех процессов и потоков. Каждый Process имеет vector из Thread объектов. Добавление Thread объектов к каждому Process осуществляется через unordered_map<processId, Process>. Чтобы получить уникальный набор раскладок клавиатуры для каждого процесса (поскольку каждый поток теоретически может иметь свой собственный), используется unordered_set<HKL>.

#include "pch.h"
#include <iostream>
#include <string>
#include <vector>
#include <unordered_set>
#include <unordered_map>

#include <windows.h>
#include <tlhelp32.h>

struct Thread {
    DWORD m_id;
    HKL m_keyboard_layout;

    Thread(DWORD Id) :
        m_id(Id), m_keyboard_layout(GetKeyboardLayout(m_id))
    {}
};

struct Process {
    std::vector<Thread> m_threads;
    DWORD m_id;
    std::wstring m_exefile;

    Process() = default;
    Process(DWORD Id, std::wstring Name) :
        m_id(Id), m_exefile(Name) 
    {}

    // get a unique set of HKL:s from all the threads in the process 
    std::unordered_set<HKL> GetKeyboardLayouts() const {
        std::unordered_set<HKL> rv;
        for (auto& t : m_threads) {
            if(t.m_keyboard_layout) // does it have a keyboard layout?
                rv.emplace(t.m_keyboard_layout);
        }
        return rv;
    }

    // if you'd like to iterate over the individual threads
    std::vector<Thread>::iterator begin() { return m_threads.begin(); }
    std::vector<Thread>::iterator end() { return m_threads.end(); }
};

class Snapshot {
    HANDLE hSnap;
    std::unordered_map<DWORD, Process> m_processes;

    void GetProcesses() {
        PROCESSENTRY32 pt;
        pt.dwSize = sizeof(pt);
        if (Process32First(hSnap, &pt)) { // must call this first
            do {
                m_processes[pt.th32ProcessID] = Process(pt.th32ProcessID, pt.szExeFile);
            } while (Process32Next(hSnap, &pt));
        }
    }

    void GetThreads() {
        THREADENTRY32 pt;
        pt.dwSize = sizeof(pt);
        if (Thread32First(hSnap, &pt)) { // must call this first
            do {
                m_processes[pt.th32OwnerProcessID].m_threads.emplace_back(pt.th32ThreadID);
            } while (Thread32Next(hSnap, &pt));
        }
    }

    void Populate() {
        GetProcesses();
        GetThreads();
    }
public:
    Snapshot() :
        hSnap(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0)),
        m_processes()
    {
        // TODO: make this exception better
        if (hSnap == INVALID_HANDLE_VALUE) throw GetLastError();
        Populate();
        CloseHandle(hSnap);
    }

    std::unordered_map<DWORD, Process>::iterator begin() { return m_processes.begin(); }
    std::unordered_map<DWORD, Process>::iterator end() { return m_processes.end(); }
};

int main() {
    Snapshot snap;

    // show processes with keyboard layouts
    for (const auto& m : snap) { // std::pair  m.first = processId, m.second = Process

        const Process& p = m.second;    
        auto layouts = p.GetKeyboardLayouts();

        if (layouts.size()) { // only show processes with keyboard layouts
            std::wcout << p.m_id << L" " << p.m_exefile << L"\n";

            for (const auto& l : layouts) {
                std::wcout << L" layout " << l << L"\n";
            }
        }
    }

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...