输入法工作原理

     

 

      在了解工作原理前,必先清楚几个概念。

 

 

 

 

 

 

 

 

 

 

 

 

        以下为输入法工作原理,如果不知道工作原理,只看输入法程序,那很难理解,同时,只知道工作原理,而不清楚程序是如何实现,也无法深入理解输入法。二者相辅相成,共同参照,方可加深理解。

 

       输入法工作原理 如下图:

 

 

 

 

 以下结合IME转换接口 分别对其说明:

 

 

输入法初始化:

 

ImeInquire : 刚选择某输入法时,IMM调用此函数,获得输入法相关信息,并根据用户界面类UICLASSNAME,自动创建用户界面。

ImeSelect  : 打开或关闭输入法时被调用,在此函数中对输入法上下文进行初始化或恢复释放

 

 

IMM将键盘消息传递给IME:

 

IMM 通过IME 转换接口ImeProcessKey 将键盘消息发动到IME

此函数对键盘消息进行筛选处理,用以判断此消息是发送给IME 还是直接发送给应用程序。

如果返回TRUE 则发送给IME  否则,直接发送给应用程序

 

 

IME将键盘消息转换为相应汉字:

 

IME 通过ImeToAsciiEx 函数来处理ImeProcessKey 发送过来的键盘消息,并最终转换为输出的结果串

 

 

IME 将汉字以字符消息的形式返回给IMM:

 

IME将使用WM_IME_CHAR或 WM_IME_COMPOSITION/GCS_RESULT消息把组合好的字符发送给窗体中的应用程序。如果应用程序没有处理这些消息,DefWindowProc函数会把它们翻译成一条或多条WM_CHAR消息

 

示例:

MakeResultString  将转换结果保存在输入上下文中将

GenerateMessage   发送WM_IME_COMPOSITION/GCS_RESULT消息给应用程序,从而使得应用程序获得结果串

 

BOOL MakeResultString(BOOL fFlag)
{
	HIMC				hIMC;
	LPINPUTCONTEXT		lpIMC			= NULL;
	LPCOMPOSITIONSTRING	lpIMECompStr	= NULL;
	LPTSTR			lpResultStr			= NULL;
	GENEMSG			GnMsg				= {0};

	GetIMC(&hIMC, &lpIMC);
	lpIMECompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);

	if (fFlag) 
	{
		lpResultStr = GetResultStr();
		if (!lpResultStr) return FALSE;
		_tcscpy((LPTSTR)((LPBYTE)(lpIMECompStr) + (lpIMECompStr)->dwResultStrOffset), lpResultStr);
		lpIMECompStr->dwResultStrLen = _tcslen(lpResultStr);
	}
	else
	{
		*((LPTSTR)((LPBYTE)(lpIMECompStr) + (lpIMECompStr)->dwResultStrOffset)) = _T('\0'); 
		lpIMECompStr->dwResultStrLen = 0;
	}

	InitBMStr();
	InitCandStrPage();
	InitCandList();

	ImmUnlockIMCC(lpIMC->hCompStr);
	GenerateMessage(WM_IME_COMPOSITION,0,GCS_RESULTSTR);
	GenerateMessage(WM_IME_ENDCOMPOSITION,0,0);
	ImmUnlockIMC(hIMC);
	return TRUE;
}

BOOL GenerateMessage(UINT message,WPARAM wParam,LPARAM lParam)
{
	HIMC				hIMC			= {0};
	LPINPUTCONTEXT		lpIMC			= NULL;
	LPDWORD				lpdwTransBuf	= NULL;

	GetIMC(&hIMC, &lpIMC);
	if (IsWindow(lpIMC->hWnd))
	{
		// re-allocate the memory block for the message buffer.
		lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) *  sizeof(DWORD) * 3);
		if (!lpIMC->hMsgBuf) goto Error;

		// Lock the memory for the message buffer.
		lpdwTransBuf = (LPDWORD)ImmLockIMCC(lpIMC->hMsgBuf);
		if (!lpdwTransBuf) goto Error;
		
		// Set the messages that the IME wants to generate.
		*(lpdwTransBuf++) = message;
		*(lpdwTransBuf++) = wParam;
		*(lpdwTransBuf++) = lParam;

		// Set the number of the messages.
		(lpIMC->dwNumMsgBuf)++;
		
		// Unlock the memory for the message buffer and the Input Context.
		ImmUnlockIMCC(lpIMC->hMsgBuf);

		// Call ImmGenerateMessage function.
		ImmGenerateMessage(hIMC);
	}

Error:
	ImmUnlockIMC(hIMC);
	return TRUE;
}


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(输入法)