Мне нужно знать, какая установлена раскладка клавиатуры пользователя в данный момент (использую в CALLBACK функции)
Нашел решение:
HKL kbLayout = GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), NULL));
Это работает, но мне кажется, что не очень хорошо при каждом вызове функции запрашивать у системы текущую раскладку.
Нашел ещё одно решение, но не совсем понимаю, как его использовать.
В документации написано:
Чтобы установить этот приемник, получите объект ITfSource
из объекта ITfInputProcessorProfiles
, вызвав ITfInputProcessorProfiles::QueryInterface
с параметром IID_ITfSource
. Затем вызовите ITfSource::AdviseSink
с IID_ITfLanguageProfileNotifySink
.
HRESULT hr;
ITfInputProcessorProfiles *pProfiles;
ITfSource *pSource;
hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfiles,
(LPVOID*) &pProfiles);
if(!SUCCEEDED(hr)) return 1;
hr = pProfiles->QueryInterface(IID_ITfSource, (LPVOID*) &pSource);
if(!SUCCEEDED(hr)) return 1;
// Some code
pSource->Release();
pProfiles->Release();
Вроде удалось получить объект ITfSource
, но дальше непонятно, как вызвать AdviseSink
HRESULT AdviseSink(
REFIID riid,
IUnknown *punk,
DWORD *pdwCookie
);
Я так понимаю - в качестве riid
нужно передать IID_ITfLanguageProfileNotifySink
,
pdwCookie
это указатель на переменную, в которую будет записан идентификатор, который позже используется в ITfSource::UnadviseSink
.
Но что такое IUnknown *punk
? В примерах кода в интернете туда обычно передают this
.
То еcть мне нужно создать функцию (или класс?) и писать все это там?
А дальше нужно реализовать метод OnLanguageChanged
. Буду очень благодарен, если покажете как это сделать.
И последний вопрос - мне нужно получать это событие глобально, даже если окно моего приложения не в фокусе. Надеюсь, что это возможно
UPDATE
Может мне нужно создать класс, наследоваться от ITfLanguageProfileNotifySink
, реализовать методы OnLanguageChange
и OnLanguageChanged
, а в AdviseSink
в качестве параметра punk
передавать ссылку на объект этого класса?
Мысли вслух...
UPDATE 2
Спустя некоторое время, получилось реализовать интерфейс ITfLanguageProfileNotifySink
(спасибо @user7860670)
Реализация:
header
#ifndef LANGAUGECHANGEHANDLER_H
#define LANGAUGECHANGEHANDLER_H
#include <msctf.h>
class LangaugeChangeHandler : ITfLanguageProfileNotifySink {
private:
ULONG cRef;
LANGID id;
public:
LangaugeChangeHandler();
virtual ~LangaugeChangeHandler();
HRESULT STDMETHODCALLTYPE OnLanguageChange(LANGID id, WINBOOL *pfAccept) override;
HRESULT STDMETHODCALLTYPE OnLanguageChanged() override;
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override;
ULONG STDMETHODCALLTYPE AddRef(void) override;
ULONG STDMETHODCALLTYPE Release(void) override;
};
#endif // LANGAUGECHANGEHANDLER_H
cpp
#include "langauge_change_handler.h"
#include <iostream>
LangaugeChangeHandler::LangaugeChangeHandler() {
cRef = 0;
}
LangaugeChangeHandler::~LangaugeChangeHandler() {
}
HRESULT STDMETHODCALLTYPE LangaugeChangeHandler::OnLanguageChange(LANGID id, WINBOOL *pfAccept) {
(void) pfAccept;
this->id = id;
return S_OK;
}
HRESULT STDMETHODCALLTYPE LangaugeChangeHandler::OnLanguageChanged() {
std::cout << id << std::endl;
return S_OK;
}
HRESULT STDMETHODCALLTYPE LangaugeChangeHandler::QueryInterface(REFIID riid, void** ppvObject) {
if (!ppvObject)
return E_INVALIDARG;
if(riid == IID_IUnknown || riid == IID_ITfLanguageProfileNotifySink) {
*ppvObject = this;
AddRef();
return S_OK;
} else
return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE LangaugeChangeHandler::AddRef(void) {
InterlockedIncrement(&cRef);
return cRef;
}
ULONG STDMETHODCALLTYPE LangaugeChangeHandler::Release(void) {
ULONG ulRefCount = InterlockedDecrement(&cRef);
if (cRef == 0) {
delete this;
return 0;
} else
return ulRefCount;
}
Но я всё ещё не понимаю, как заставить это работать...
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Может ли новосозданный вектор после вызова метода reserve(x) иметь capacity больше, чем x? Если да, то правда ли, что чтобы получить вектор с нужным...
Не понимаю, в чем ошибка, ведь значение вычисляется правильно, иногда даже выводиться в консоль, но с вводом первого числа ,как 1, а второго...
вот код программы, из книги олимпиадное программированиеОн должен решать задачу о количестве способов разместить n ферзей на доске n*n чтобы...