通过 Keyboard Layout 获取
BOOL GetIMEsV1(int layoutId)
{
BOOL result = TRUE;
BOOL initialized = FALSE;
ITfInputProcessorProfiles* lpProfiles = nullptr;
IEnumTfLanguageProfiles* lpEnum = nullptr;
__try
{
HRESULT hr = CoInitialize(nullptr);
if (FAILED(hr))
{
result = FALSE;
__leave;
}
initialized = TRUE;
hr = CoCreateInstance(
CLSID_TF_InputProcessorProfiles,
nullptr,
CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfiles,
(VOID**)&lpProfiles
);
if (FAILED(hr))
{
result = FALSE;
__leave;
}
hr = lpProfiles->EnumLanguageProfiles(layoutId, &lpEnum);
if (FAILED(hr))
{
result = FALSE;
__leave;
}
if (lpEnum != nullptr)
{
TF_LANGUAGEPROFILE profile;
ULONG fetched = 0;
while (lpEnum->Next(1, &profile, &fetched) == S_OK)
{
BSTR bstrDesc = nullptr;
BOOL bEnabled = FALSE;
hr = lpProfiles->IsEnabledLanguageProfile(profile.clsid, profile.langid, profile.guidProfile, &bEnabled);
if (SUCCEEDED(hr) && bEnabled) {
hr = lpProfiles->GetLanguageProfileDescription(profile.clsid, profile.langid, profile.guidProfile, &bstrDesc);
if (SUCCEEDED(hr))
{
_tprintf(_T("%s\n"), bstrDesc);
SysFreeString(bstrDesc);
}
}
}
}
}
__finally
{
if (lpProfiles != nullptr)
{
lpProfiles->Release();
lpProfiles = nullptr;
}
if (lpEnum != nullptr)
{
lpEnum->Release();
lpEnum = nullptr;
}
if (initialized)
{
CoUninitialize();
}
}
return result;
}
int main()
{
_tsetlocale(LC_ALL, _T("zh-CN"));
auto num = GetKeyboardLayoutList(0, nullptr);
HKL* list = new HKL[num];
GetKeyboardLayoutList(num, list);
for (auto i = 0; i < num; i++)
{
//@see HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts
auto hkl = list[i];
auto device = HIWORD(hkl);
if ((device & 0xF000) != 0xF000)
{
// 例如 0x804 对应中文
auto layoutId = LOWORD(hkl);
GetIMEsV1(layoutId);
}
}
delete[] list;
return 0;
}
缺点:
获取 Layout
比较复杂,上述代码只是简单地从低位获取,具体的处理方法可以参考 How to create a list of Keyboards. Extract KLID from HKL?
遍历所有语言及语言下安装的输入法
BOOL GetIMEsV2()
{
BOOL result = FALSE;
BOOL initialized = FALSE;
ITfInputProcessorProfiles* lpProfiles = nullptr;
ITfInputProcessorProfileMgr* lpMgr = nullptr;
IEnumTfInputProcessorProfiles* lpEnum = nullptr;
__try
{
HRESULT hr = CoInitialize(nullptr);
if (FAILED(hr))
{
result = FALSE;
__leave;
}
hr = CoCreateInstance(
CLSID_TF_InputProcessorProfiles,
nullptr,
CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfileMgr,
(LPVOID*)&lpMgr
);
if (FAILED(hr))
{
result = FALSE;
__leave;
}
hr = CoCreateInstance(
CLSID_TF_InputProcessorProfiles,
nullptr,
CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfiles,
(LPVOID*)&lpProfiles
);
if (FAILED(hr))
{
result = FALSE;
__leave;
}
// 第一个参数为 0 遍历本机所有语言,否则跟第一版一样,例如 0x804 对应中文
hr = lpMgr->EnumProfiles(0, &lpEnum);
if (FAILED(hr))
{
result = FALSE;
__leave;
}
TF_INPUTPROCESSORPROFILE profile = { 0 };
ULONG fetched = 0;
while (lpEnum->Next(1, &profile, &fetched) == S_OK)
{
BSTR bstrDesc = nullptr;
BOOL bEnabled = FALSE;
hr = lpProfiles->IsEnabledLanguageProfile(profile.clsid, profile.langid, profile.guidProfile, &bEnabled);
if (SUCCEEDED(hr) && bEnabled) {
hr = lpProfiles->GetLanguageProfileDescription(profile.clsid, profile.langid, profile.guidProfile, &bstrDesc);
if (SUCCEEDED(hr))
{
_tprintf(_T("%s\n"), bstrDesc);
SysFreeString(bstrDesc);
}
}
ZeroMemory(&profile, sizeof(TF_INPUTPROCESSORPROFILE));
}
}
__finally
{
if (lpMgr != nullptr)
{
lpMgr->Release();
lpMgr = nullptr;
}
if (lpProfiles != nullptr)
{
lpProfiles->Release();
lpProfiles = nullptr;
}
if (lpEnum != nullptr)
{
lpEnum->Release();
lpProfiles = nullptr;
}
if (initialized)
{
CoUninitialize();
}
}
return result;
}
int main()
{
_tsetlocale(LC_ALL, _T("zh-CN"));
GetIMEsV2();
return 0;
}
切换到对应的输入法
BOOL SetIME(_In_ LPCTSTR name)
{
BOOL result = FALSE;
BOOL initialized = FALSE;
ITfInputProcessorProfiles* lpProfiles = nullptr;
ITfInputProcessorProfileMgr* lpMgr = nullptr;
IEnumTfInputProcessorProfiles* lpEnum = nullptr;
__try
{
HRESULT hr = CoInitialize(nullptr);
if (FAILED(hr))
{
result = FALSE;
__leave;
}
hr = CoCreateInstance(
CLSID_TF_InputProcessorProfiles,
nullptr,
CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfileMgr,
(LPVOID*)&lpMgr
);
if (FAILED(hr))
{
result = FALSE;
__leave;
}
hr = CoCreateInstance(
CLSID_TF_InputProcessorProfiles,
nullptr,
CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfiles,
(LPVOID*)&lpProfiles
);
if (FAILED(hr))
{
result = FALSE;
__leave;
}
hr = lpMgr->EnumProfiles(0, &lpEnum);
if (FAILED(hr))
{
result = FALSE;
__leave;
}
TF_INPUTPROCESSORPROFILE profile = { 0 };
ULONG fetched = 0;
while (lpEnum->Next(1, &profile, &fetched) == S_OK)
{
BSTR bstrDest = nullptr;
hr = lpProfiles->GetLanguageProfileDescription(
profile.clsid,
profile.langid,
profile.guidProfile,
&bstrDest
);
if (SUCCEEDED(hr))
{
if (_tcscmp(name, bstrDest) == 0)
{
hr = lpMgr->ActivateProfile(
TF_PROFILETYPE_INPUTPROCESSOR,
profile.langid,
profile.clsid,
profile.guidProfile,
NULL,
TF_IPPMF_FORSESSION | TF_IPPMF_DONTCARECURRENTINPUTLANGUAGE
);
if (SUCCEEDED(hr))
{
result = TRUE;
break;
}
else {
result = FALSE;
__leave;
}
}
SysFreeString(bstrDest);
}
ZeroMemory(&profile, sizeof(TF_INPUTPROCESSORPROFILE));
}
}
__finally
{
if (lpMgr != nullptr)
{
lpMgr->Release();
lpMgr = nullptr;
}
if (lpProfiles != nullptr)
{
lpProfiles->Release();
lpProfiles = nullptr;
}
if (lpEnum != nullptr)
{
lpEnum->Release();
lpProfiles = nullptr;
}
if (initialized)
{
CoUninitialize();
}
}
return result;
}
int main()
{
SetIME(TEXT("微信输入法"));
return 0;
}