实现输入法窗口自定义

GetIme.h源码清单

#pragma once #include <Windows.h> #include <imm.h> #include <string> #pragma comment ( lib , "imm32.lib" ) //字符串临时缓存长度 #ifndef _MAX_BUF_ #define _MAX_BUF_ 256 #endif /* 功能:取输入法窗口候选字列表,输入法名称及状态 为自己绘制“输入法窗口”创造必要条件。 标题:实现输入法窗口自定义 关键词:IME VC 输入法 输入法窗口 最后修改日期:2010-09-02 Remark:当前环境VS2008+SP1 WinXPSP3。编译选项为Unicode。 http://dev.gameres.com/Program/Control/ime.htm CGetIme为单实例类 测试:在Irrlicht1.7.1中测试通过。 在标准Win32窗口程序中测试通过。 */ class CGetIme { public: CGetIme(void) { m_hWnd = NULL ; } ~CGetIme(); //功能:初始化当前类的实例,使之可用。 //Remark:你只能在hWnd的属主(线程)中调用这个函数 //建议在WM_CREATE或WM_IME_SETCONTEXT中调用 void setHWnd(HWND hWnd); //功能:取候选字列表,和当前输入的候选key //Remark:建议在WM_IME_NOTIFY的wParam为以下 //IMN_OPENCANDIDATE和IMN_CHANGECANDIDATE事件 //时调用 //strCS=>已经键入的Key,strCL=>候选字列表 void getCandidateList(std::string &strCS,std::string &strCL); //功能:取输入法名称 std::string getDescription(); //功能:取输入法状态 std::string getConversion(); //Remark:建议在IMN_CLOSECANDIDATE事件时,关掉对“自定义输入法窗口”的绘制。 //Remark:WM_IME_CHAR事件中,你会得到,转换后的字符串, //不过你是一个wchar_t一个wchar_t的得到,参考下面的代码段 //char bits [2] = { (char) ((wParam & 0xff00)>> 8), (char) (wParam & 0xff) },wchar_t t = bits; //禁止输入法 void disableIME(); //允许输入法 void enableIME(); protected: HWND m_hWnd; HIMC m_hIMC; std::string m_candidate; //候选字列表 std::string m_description; //输入法名称 std::string m_conversion; //输入法状态 std::string m_compstr; //已经键入的key };

GetIme.cpp源码清单

#include "StdAfx.h" #include "GetIme.h" #include <assert.h> #include "../T3D3_Irrlicht161/Utils.h" void CGetIme::setHWnd(HWND hWnd) { m_hWnd = hWnd; //ImmGetContext cannot get input context of other process. ImmGetContext internally //checks whether the process of the target window is the current process. //If the check fails, the function returns NULL. m_hIMC = ::ImmGetContext(m_hWnd); assert(m_hIMC); //Below,Hide IME window HWND hWndIME = ::ImmGetDefaultIMEWnd(hWnd); if (hWndIME) ::ShowWindow(hWndIME,SW_HIDE); } CGetIme::~CGetIme() { //Show IME window HWND hWndIME = ::ImmGetDefaultIMEWnd(m_hWnd); if (hWndIME) ::ShowWindow(hWndIME,SW_SHOW); ImmReleaseContext(m_hWnd, m_hIMC); } void CGetIme::getCandidateList(std::string &strCS,std::string &strCL) { std::string sR(""); wchar_t buf[32]; char *p; int nR; DWORD dwSize; LPCANDIDATELIST lp; m_candidate = ""; m_compstr = ""; HKL hKL = ::GetKeyboardLayout(0);//获得键盘布局 if (hKL==0) { OutputDebugString(L"hKL==0/n"); return ; } if( m_hIMC == NULL) { OutputDebugString(L"hIMC ==0/n"); return ; } ZeroMemory(buf,sizeof(buf)); ImmGetCompositionString(m_hIMC, GCS_COMPSTR, buf, 20); std::wstring wsB=buf; strCS = ws2s(wsB); m_compstr = strCS; dwSize = ImmGetCandidateList(m_hIMC, 0, NULL, 0); if (dwSize>0) { p=new char[dwSize]; lp = (LPCANDIDATELIST)p; nR = ImmGetCandidateList(m_hIMC, 0, lp, dwSize); //若是取其它窗口的IMM状态,则lp->dwStyle的值为零(Unknown)。 //否则返回一,表示可以读取lp指向的数据结构! if (nR && lp->dwCount>1) { int i=1; strCL = ""; char temp[_MAX_BUF_]; ZeroMemory(temp,sizeof(temp)); int nOffset; while ( (i<lp->dwCount-lp->dwSelection+1) && (i<lp->dwPageSize+1) ) { std::wstring sT= (wchar_t *)(p + lp->dwOffset[lp->dwPageStart+(i-1)]); sprintf( temp , " %d." , i); strCL = strCL + temp; strCL = strCL + "" + ws2s(sT); i++; } if (strCL.find_first_not_of(' ') != -1) { strCL =strCL.substr(strCL.find_first_not_of(' '),strCL.length()); //例如“万能五笔输入法中”状态中输入字符"k",strCL变为下值 //1.中 2.口 3.员工maa 4.哎呀aka 5.只w 6.员m } } delete p; } else { OutputDebugString(L"Error: dwSize = ImmGetCandidateList(hIMC, 0, NULL, 0);<= 0 /n"); } m_candidate = strCL; } //取输入法名称 std::string CGetIme::getDescription() { std::string sR(""); m_description = ""; HKL hKL = ::GetKeyboardLayout(0);//获得键盘布局 if (hKL==0) return sR; int iSize = ::ImmGetDescription(hKL, NULL, 0);//获得输入法名称大小 if (iSize>=_MAX_BUF_) { OutputDebugString(L"CShowIMEUI::getDescription iSize>=MAX_BUF_SIZE CallError/n"); return sR; } if (iSize==0) { //如果名称大小为0则不显示输入法状态 OutputDebugString(L"CShowIMEUI::getDescription iSize==0 CallError/n"); return sR; } wchar_t name[_MAX_BUF_]; ::ImmGetDescription(hKL,name, _MAX_BUF_ );//获得输入法名称 std::wstring wsName = name; sR = ws2s(wsName); m_description = sR; return sR; } //取输入法状态 std::string CGetIme::getConversion() { DWORD dwConversion; DWORD dwSentence; LPDWORD lpfdwConversion = &dwConversion; LPDWORD lpfdwSentence = &dwSentence; std::string conversion; m_conversion = ""; if (m_hIMC==NULL) { return ""; } BOOL ret = ::ImmGetConversionStatus(m_hIMC, lpfdwConversion, lpfdwSentence); ::ImmReleaseContext(m_hWnd,m_hIMC); char pOutputBuf[_MAX_BUF_]; memset(pOutputBuf,0,_MAX_BUF_); if (*lpfdwConversion & 0x01) strcat(pOutputBuf, " 中文"); else strcat(pOutputBuf, " 英文"); if (*lpfdwConversion & 0x08) strcat(pOutputBuf, " 全角"); else strcat(pOutputBuf, " 半角"); if (*lpfdwConversion & 0x400) strcat(pOutputBuf, " 中文标点"); else strcat(pOutputBuf, " 英文标点"); if (*lpfdwConversion & 0x80) strcat(pOutputBuf, " 软键盘"); else conversion = ""; conversion = pOutputBuf; m_conversion = conversion; return conversion; } void CGetIme::disableIME() { m_hIMC = ImmAssociateContext(m_hWnd, NULL); // It makes IME disable for hWnd window. // Then you can do whatever you want without IME. //如果是MFC程序~~~~ 最好在 InitInstance() 下加一句~~ //ImmDisableIME(GetCurrentThreadId()); } void CGetIme::enableIME() { ImmAssociateContext(m_hWnd, m_hIMC); // If you want to enable IME again, // then you can use the previous stored IME // context(hIMC) to restore IME. }

建议以类继承方式使用CGetIme类提供的功能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值