1 // Scintilla source code edit control 2 /** @file HanjaDic.cxx 3 ** Korean Hanja Dictionary 4 ** Convert between Korean Hanja and Hangul by COM interface. 5 **/ 6 // Copyright 2015 by Neil Hodgson <[email protected]> 7 // The License.txt file describes the conditions under which this software may be distributed. 8 9 #include <string> 10 #include <string_view> 11 12 #include <windows.h> 13 14 #include "UniConversion.h" 15 #include "HanjaDic.h" 16 17 namespace Scintilla { 18 19 namespace HanjaDict { 20 21 interface IRadical; 22 interface IHanja; 23 interface IStrokes; 24 25 typedef enum { HANJA_UNKNOWN = 0, HANJA_K0 = 1, HANJA_K1 = 2, HANJA_OTHER = 3 } HANJA_TYPE; 26 27 interface IHanjaDic : IUnknown { 28 STDMETHOD(OpenMainDic)(); 29 STDMETHOD(CloseMainDic)(); 30 STDMETHOD(GetHanjaWords)(BSTR bstrHangul, SAFEARRAY* ppsaHanja, VARIANT_BOOL* pfFound); 31 STDMETHOD(GetHanjaChars)(unsigned short wchHangul, BSTR* pbstrHanjaChars, VARIANT_BOOL* pfFound); 32 STDMETHOD(HanjaToHangul)(BSTR bstrHanja, BSTR* pbstrHangul); 33 STDMETHOD(GetHanjaType)(unsigned short wchHanja, HANJA_TYPE* pHanjaType); 34 STDMETHOD(GetHanjaSense)(unsigned short wchHanja, BSTR* pbstrSense); 35 STDMETHOD(GetRadicalID)(short SeqNumOfRadical, short* pRadicalID, unsigned short* pwchRadical); 36 STDMETHOD(GetRadical)(short nRadicalID, IRadical** ppIRadical); 37 STDMETHOD(RadicalIDToHanja)(short nRadicalID, unsigned short* pwchRadical); 38 STDMETHOD(GetHanja)(unsigned short wchHanja, IHanja** ppIHanja); 39 STDMETHOD(GetStrokes)(short nStrokes, IStrokes** ppIStrokes); 40 STDMETHOD(OpenDefaultCustomDic)(); 41 STDMETHOD(OpenCustomDic)(BSTR bstrPath, long* plUdr); 42 STDMETHOD(CloseDefaultCustomDic)(); 43 STDMETHOD(CloseCustomDic)(long lUdr); 44 STDMETHOD(CloseAllCustomDics)(); 45 STDMETHOD(GetDefaultCustomHanjaWords)(BSTR bstrHangul, SAFEARRAY** ppsaHanja, VARIANT_BOOL* pfFound); 46 STDMETHOD(GetCustomHanjaWords)(long lUdr, BSTR bstrHangul, SAFEARRAY** ppsaHanja, VARIANT_BOOL* pfFound); 47 STDMETHOD(PutDefaultCustomHanjaWord)(BSTR bstrHangul, BSTR bstrHanja); 48 STDMETHOD(PutCustomHanjaWord)(long lUdr, BSTR bstrHangul, BSTR bstrHanja); 49 STDMETHOD(MaxNumOfRadicals)(short* pVal); 50 STDMETHOD(MaxNumOfStrokes)(short* pVal); 51 STDMETHOD(DefaultCustomDic)(long* pVal); 52 STDMETHOD(DefaultCustomDic)(long pVal); 53 STDMETHOD(MaxHanjaType)(HANJA_TYPE* pHanjaType); 54 STDMETHOD(MaxHanjaType)(HANJA_TYPE pHanjaType); 55 }; 56 57 extern "C" const GUID __declspec(selectany) IID_IHanjaDic = 58 { 0xad75f3ac, 0x18cd, 0x48c6, { 0xa2, 0x7d, 0xf1, 0xe9, 0xa7, 0xdc, 0xe4, 0x32 } }; 59 60 class HanjaDic { 61 private: 62 HRESULT hr; 63 CLSID CLSID_HanjaDic; 64 65 public: 66 IHanjaDic *HJinterface; 67 68 HanjaDic() : HJinterface(nullptr) { 69 hr = CLSIDFromProgID(OLESTR("mshjdic.hanjadic"), &CLSID_HanjaDic); 70 if (SUCCEEDED(hr)) { 71 hr = CoCreateInstance(CLSID_HanjaDic, nullptr, 72 CLSCTX_INPROC_SERVER, IID_IHanjaDic, 73 (LPVOID *)& HJinterface); 74 if (SUCCEEDED(hr)) { 75 hr = HJinterface->OpenMainDic(); 76 } 77 } 78 } 79 80 ~HanjaDic() { 81 if (SUCCEEDED(hr)) { 82 hr = HJinterface->CloseMainDic(); 83 HJinterface->Release(); 84 } 85 } 86 87 bool HJdictAvailable() { 88 return SUCCEEDED(hr); 89 } 90 91 bool IsHanja(int hanja) { 92 HANJA_TYPE hanjaType; 93 hr = HJinterface->GetHanjaType(static_cast<unsigned short>(hanja), &hanjaType); 94 if (SUCCEEDED(hr)) { 95 return (hanjaType > 0); 96 } 97 return false; 98 } 99 }; 100 101 int GetHangulOfHanja(wchar_t *inout) { 102 // Convert every hanja to hangul. 103 // Return the number of characters converted. 104 int changed = 0; 105 HanjaDic dict; 106 if (dict.HJdictAvailable()) { 107 const size_t len = wcslen(inout); 108 wchar_t conv[UTF8MaxBytes] = {0}; 109 BSTR bstrHangul = SysAllocString(conv); 110 for (size_t i=0; i<len; i++) { 111 if (dict.IsHanja(static_cast<int>(inout[i]))) { // Pass hanja only! 112 conv[0] = inout[i]; 113 BSTR bstrHanja = SysAllocString(conv); 114 const HRESULT hr = dict.HJinterface->HanjaToHangul(bstrHanja, &bstrHangul); 115 if (SUCCEEDED(hr)) { 116 inout[i] = static_cast<wchar_t>(bstrHangul[0]); 117 changed += 1; 118 } 119 SysFreeString(bstrHanja); 120 } 121 } 122 SysFreeString(bstrHangul); 123 } 124 return changed; 125 } 126 127 } 128 } 129