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