OSDN Git Service

Ignore inactive IMEs.
[xkeymacs/xkeymacs.git] / xkeymacs / imelist.cpp
1 #include "imelist.h"\r
2 #include <vector>\r
3 #include <Imm.h>\r
4 #include <msctf.h>\r
5 \r
6 IMEListIterator IMEList::begin()\r
7 {\r
8         if (list.empty())\r
9                 GetIMEList();\r
10         return list.begin();\r
11 }\r
12 \r
13 IMEListIterator IMEList::end()\r
14 {\r
15         return list.end();\r
16 }\r
17 \r
18 void IMEList::GetIMEList()\r
19 {\r
20         GetIMM();\r
21         GetTSF();\r
22 }\r
23 \r
24 void IMEList::GetIMM()\r
25 {\r
26         const int n = GetKeyboardLayoutList(0, NULL);\r
27         if (!n)\r
28                 return;\r
29         std::vector<HKL> hkls(n);\r
30         GetKeyboardLayoutList(n, &hkls[0]);\r
31         for (std::vector<HKL>::const_iterator p = hkls.begin(); p != hkls.end(); ++p) {\r
32                 IMEInfo info;\r
33                 if (ImmGetDescription(*p, info.szDescription, WINDOW_TEXT_LENGTH) &&\r
34                                 ImmGetIMEFileName(*p, info.szFileName, MAX_PATH))\r
35                         list.push_back(info);\r
36         }\r
37 }\r
38 \r
39 void IMEList::GetTSF()\r
40 {\r
41         CoInitialize(NULL);\r
42         HRESULT hr;\r
43         ITfInputProcessorProfiles *pProfiles;\r
44         hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER, IID_ITfInputProcessorProfiles, reinterpret_cast<LPVOID*>(&pProfiles));\r
45         if (FAILED(hr)) {\r
46                 CoUninitialize();\r
47                 return;\r
48         }\r
49         const LANGID langid = GetUserDefaultLangID();\r
50         IEnumTfLanguageProfiles *pEnum;\r
51         hr = pProfiles->EnumLanguageProfiles(langid, &pEnum);\r
52         if (FAILED(hr))\r
53                 goto fail;\r
54         TF_LANGUAGEPROFILE prof;\r
55         ULONG fetch;\r
56         while (pEnum->Next(1, &prof, &fetch) == S_OK) {\r
57                 if (!prof.fActive)\r
58                         continue;\r
59                 BSTR bstr;\r
60                 hr = pProfiles->GetLanguageProfileDescription(prof.clsid, langid, prof.guidProfile, &bstr);\r
61                 if (FAILED(hr))\r
62                         continue;\r
63                 IMEInfo info;\r
64 #ifdef _MBCS\r
65                 WideCharToMultiByte(CP_ACP, 0, bstr, -1, info.szDescription, MAX_PATH, NULL, NULL);\r
66 #else\r
67                 wcscpy_s(info.szDescription, WINDOW_TEXT_LENGTH, bstr);\r
68 #endif\r
69                 bool exist = false;\r
70                 for (IMEListIterator p = list.begin(); p != list.end(); ++p)\r
71                         if (!_tcscmp(info.szDescription, p->szDescription)) { // already get via IMM\r
72                                 exist = true;\r
73                                 break;\r
74                         }\r
75                 if (!exist) {\r
76                         _tcscpy_s(info.szFileName, _T("IME"));\r
77                         list.push_back(info);\r
78                         break;\r
79                 }\r
80         }\r
81         pEnum->Release();\r
82 fail:\r
83         pProfiles->Release();\r
84         CoUninitialize();\r
85 }\r