diff EXCLUDE/GLIMM/src/IMM.cpp @ 4741:bb189d44af16

Added GLIMM (using IMM instead of TSF) Uses small bit of TSF to fully disable cicero (TSF for non-TSF enabled apps)
author dewyatt
date Wed, 30 Jun 2010 17:29:20 -0400
parents
children 0aaa54fbd2bc
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/src/IMM.cpp	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,165 @@
+#include "IMM.hpp"
+#include <stdexcept>
+
+IMM::IMM() : my_COM_Initialized(false),
+			 my_Thread_Manager(0),
+			 my_Window(0),
+			 my_Context(0),
+			 my_HKL(0),
+			 my_Vertical_Candidates(false)
+{
+
+}
+
+IMM::~IMM()
+{
+	Finalize();
+}
+
+void IMM::Initialize(HWND Window)
+{
+	Finalize();
+
+	my_Window = Window;
+
+	if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
+	{
+		my_COM_Initialized = true;
+		if (SUCCEEDED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast<LPVOID *>(&my_Thread_Manager))))
+		{
+			ITfDocumentMgr *Document_Manager = 0;
+			if (FAILED(my_Thread_Manager->AssociateFocus(Window, NULL, &Document_Manager)))
+				printf("Warning: ITfThreadMgr->AssociateFocus failed\n");
+
+			if (Document_Manager)
+				Document_Manager->Release();
+		}
+		else
+			printf("Warning: Failed to create ITfThreadMgr instance\n");
+	}
+	else
+		printf("Warning: Failed to initialize COM\n");
+
+	ImmDisableTextFrameService(-1);
+
+	my_Context = ImmGetContext(my_Window);
+	if (!ImmReleaseContext(my_Window, my_Context))
+		throw std::runtime_error("Error releasing context");
+
+	if (!my_Context)
+		throw std::runtime_error("No context");
+
+	Update_Input_Locale();
+}
+
+void IMM::Finalize()
+{
+	if (my_Thread_Manager)
+	{
+		my_Thread_Manager->Release();
+		my_Thread_Manager = 0;
+	}
+	if (my_COM_Initialized)
+	{
+		CoUninitialize();
+		my_COM_Initialized = false;
+	}
+}
+
+#define GET_LANG(hkl) LOWORD((hkl))
+#define GET_PRIMLANG(hkl) ((WORD)PRIMARYLANGID(GET_LANG((hkl))))
+#define GET_SUBLANG(hkl) SUBLANGID(GET_LANG((hkl)))
+
+void IMM::Update_Input_Locale()
+{
+	static HKL Previous_HKL = 0;
+	my_HKL = GetKeyboardLayout(0);
+	if (Previous_HKL == my_HKL)
+		return;
+
+	Previous_HKL = my_HKL;
+	my_Vertical_Candidates = false;
+	switch (GET_PRIMLANG(my_HKL))
+	{
+	case LANG_CHINESE:
+		my_Vertical_Candidates = true;
+		switch (GET_SUBLANG(my_HKL))
+		{
+		case SUBLANG_CHINESE_SIMPLIFIED:
+			my_Vertical_Candidates = false;
+			break;
+		}
+		break;
+	case LANG_JAPANESE:
+		my_Vertical_Candidates = true;
+		break;
+	}
+}
+
+LRESULT IMM::Handle_Message(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam, bool &Ate)
+{
+	Ate = false;
+	switch (Message)
+	{
+	case WM_INPUTLANGCHANGE:
+		Update_Input_Locale();
+		break;
+	case WM_IME_SETCONTEXT:
+		lParam = 0;
+		return DefWindowProcW(my_Window, Message, wParam, lParam);
+		break;
+	case WM_IME_STARTCOMPOSITION:
+		Ate = true;
+		break;
+	case WM_IME_COMPOSITION:
+		{
+			Ate = true;
+			HIMC Context = ImmGetContext(Window);
+			if (!Context)
+				break;
+
+			if (lParam & GCS_RESULTSTR)
+			{
+				LONG Length = ImmGetCompositionStringW(Context, GCS_RESULTSTR, 0, 0);
+				std::wstring Composition(Length / sizeof(wchar_t), 0);
+				Length = ImmGetCompositionStringW(Context, GCS_RESULTSTR, &Composition[0], Composition.size() * sizeof(Composition[0]));
+				printf("GCS_RESULTSTR: ");
+				for (LONG i = 0; i < Length / sizeof(wchar_t); ++i)
+					printf("U+%04X ", Composition[i]);
+
+				printf("\n");
+			}
+			if (lParam & GCS_COMPSTR)
+			{
+				LONG Length = ImmGetCompositionStringW(Context, GCS_COMPSTR, 0, 0);
+				std::wstring Composition(Length / sizeof(wchar_t), 0);
+				Length = ImmGetCompositionStringW(Context, GCS_COMPSTR, &Composition[0], Composition.size() * sizeof(Composition[0]));
+				printf("GCS_COMPSTR: ");
+				for (LONG i = 0; i < Length / sizeof(wchar_t); ++i)
+					printf("U+%04X ", Composition[i]);
+
+				printf("\n");
+			}
+			ImmReleaseContext(Window, Context);
+		}
+		break;
+	case WM_IME_ENDCOMPOSITION:
+		break;
+	case WM_IME_NOTIFY:
+		switch (wParam)
+		{
+		case IMN_SETCONVERSIONMODE:
+
+			break;
+		case IMN_SETOPENSTATUS:
+			Update_Input_Locale();
+			break;
+		case IMN_OPENCANDIDATE:
+		case IMN_CHANGECANDIDATE:
+			Ate = true;
+			break;
+		}
+		break;
+	}
+	return 0;
+}