c++实现输入法窗口自定义的代码
#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
};
//=======================================================
#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.
}
c++实现输入法窗口自定义的代码的更多相关文章
- sublime 自定义快捷代码
选择打开tools ->developer->new snippet <snippet> <content><![CDATA[Hello, ${1:this} ...
- Android窗口管理服务WindowManagerService对输入法窗口(Input Method Window)的管理分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8526644 在Android系统中,输入法窗口 ...
- CEGUI 输入法窗口实现
游戏中经常要输入汉字,但当我们游戏没有自己实现输入法窗口时,windows会使用用户安装的输入法,但这个输入法窗口只会显示在游戏窗口外头,而且当我们游戏全屏时(真全屏,不是那种窗口式的假全屏),屏幕上 ...
- 雷林鹏分享:jQuery EasyUI 窗口 - 自定义窗口工具栏
jQuery EasyUI 窗口 - 自定义窗口工具栏 默认情况下,窗口(window)有四个工具:collapsible.minimizable.maximizable 和 closable.比如我 ...
- 雷林鹏分享:jQuery EasyUI 窗口 - 自定义带有工具条和按钮的对话框
jQuery EasyUI 窗口 - 自定义带有工具条和按钮的对话框 您可以创建一个带有工具栏(toolbar)和按钮(button)的对话框(dialog),可以从 HTML 标记创建.这个教程描述 ...
- 自定义sublime代码片段
sublime text 已经有一些他们内置的一些代码片段,但是有时候,这些并不能满足我们,这就需要我们自定义一些代码片段. 步骤如下: 1.打开sublime text 2.选择 tools -&g ...
- sublime自定义snippet代码片段
相信很多人喜欢sublime编辑工具有两个原因:第一sublime很轻巧方便:第二sublime提供很多自定义拓展功能,包括很简单且和很好用的代码片段功能snippet文件. 今天,在这里就介绍下su ...
- 重新想象 Windows 8 Store Apps (27) - 选取器: 联系人选取窗口, 自定义联系人选取窗口
原文:重新想象 Windows 8 Store Apps (27) - 选取器: 联系人选取窗口, 自定义联系人选取窗口 [源码下载] 重新想象 Windows 8 Store Apps (27) - ...
- 重新想象 Windows 8 Store Apps (26) - 选取器: 自定义文件选取窗口, 自定义文件保存窗口
原文:重新想象 Windows 8 Store Apps (26) - 选取器: 自定义文件选取窗口, 自定义文件保存窗口 [源码下载] 重新想象 Windows 8 Store Apps (26) ...
随机推荐
- myeclipse/eclipse添加Spket插件实现ExtJs4.2/ExtJs3智能提示
前言 感谢luotao,本博客是copy这篇博客的:http://www.cnblogs.com/luotaoyeah/p/3803926.html ,因为太重要了,所以笔者再写一次. 重要说明:ec ...
- 给定一颗二叉搜索树,请找出其中的第k小的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。
// ConsoleApplication2.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include "stdafx.h ...
- [51 nod]1009 数字1的数量
1009 数字1的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如: ...
- 将Windows上的文件上传到Linux上
下载一个SSH Secure Shell Client即可. SSHSecureShellClient-3.2.9下载地址: 免费下载地址在 http://linux.linuxidc.com/ 用户 ...
- uva 11825
刘书上例题 关于集合的动态规划 #include <cstdio> #include <cstdlib> #include <cmath> #include &l ...
- Javascript 中判断是谷歌浏览器和IE浏览器的方法
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- mysql 中 isnull 和 ifnull 判断字段是否为null
对于统计count(type)和avg(type) 都不起作用 SQL中有ISNULL方法,介绍如下: ISNULL使用指定的替换值替换 NULL. 语法ISNULL ( check_expressi ...
- eclipse中(装了插件m2eclipse后的)导入maven工程显示"感叹号"
有时候导入一些开源工程(maven结构的),在eclipse中(装了插件m2eclipse后的)该工程前面会有一个小的红色感叹号,但点开工程后没有发现有打小红叉的内容,这种情况其实大部分是jar包 ...
- SQLite操作(C# )
C#连接SQLite的...方法 http://www.cnblogs.com/virusswb/archive/2010/09/17/SQLite1.html 1 SQLite简介 SQLite,是 ...
- iOS开发网络篇--NSURLConnection
S简介 NSURLConnection: 作用: 1.负责发送请求,建立客户端和服务器的连接发送数据给服务器 2.并收集来自服务器的响应数据 步骤: 1.创建一个NSURL对象,设置请求路径 2.传入 ...