技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 26621|回复: 84
收起左侧

【输入法】C语言获取输入法候选词的方法

  [复制链接]

1090

主题

2609

帖子

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
237
威望
495 点
宅币
21514 个
贡献
45959 次
宅之契约
0 份
在线时间
2070 小时
注册时间
2014-1-26
发表于 2014-3-30 06:20:53 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
注意:我这里指的是Windows GUI编程。
当你设计一个3D游戏的时候,如果这个游戏不能拦截输入法,你就会觉得很难受,打字的时候看不到候选词,而游戏中按了Ctrl+空格之后各种难受、各种卡。
因此对于这样的程序,它就应该学会捕获输入法的操作,自己显示候选词列表。就像LOL(英雄联盟)那样,有自己的输入法框。
这个是怎么实现的呢?很简单,处理WM_IME_开头的窗口消息就行。
WM_IME_SETCONTEXT:
这个必须处理,告诉输入法,我自己绘制候选词列表的界面。
return DefWindowProc(hWnd,WM_IME_SETCONTEXT,wp,lp&(~ISC_SHOWUIALLCANDIDATEWINDOW));
只要这个消息被这样处理了以后,输入法的候选词框就不会出来了。
WM_IME_STARTCOMPOSITION:
处理这个消息请返回0。否则输入法的候选词框会出来。
return 0;
当你开始打字,候选词框出来的那一下,就会触发WM_IME_STARTCOMPOSITION这个消息。
WM_IME_NOTIFY:
这个消息非常重要。通过处理这个消息你可以获取候选词列表。
WPARAM的值是“子消息”,需要考虑进去。当它是以下数值的时候处理它可以获得候选词列表。
IMN_OPENCANDIDATE://开始选词
IMN_SETCANDIDATEPOS://选词窗口移动
IMN_CHANGECANDIDATE://改变选词
IMN_CLOSECANDIDATE://关闭选词窗口
这些消息触发的时候,你应该调用一些API来获取候选词列表。这个时候你需要声明一个HIMC(输入法句柄)
HIMC hIMC=ImmGetContext(hWnd);//取得输入法句柄
输入法句柄在用完后需要释放。代码如下:
ImmReleaseContext(hWnd,hIMC);//释放输入法句柄
候选词是以一个结构体的形式存储的。而且这个结构体的大小是不确定的。因此你需要取得候选词结构体的大小。
DWORD dwBufLen=ImmGetCandidateList(hIMC,0,NULL,0);//取得候选词列表结构体的大小
取得了大小,你就需要分配内存来读取候选词结构体。
LPCANDIDATELIST pList=(LPCANDIDATELIST)malloc(dwBufLen);//建立结构体
然后再次调用ImmGetCandidateList取得候选词列表
ImmGetCandidateList(hIMC,0,pList,dwBufLen);//取得候选词列表
通过pList->dwSelection可以得到当前选中的候选词的序号。pList->dwCount得到候选词个数。pList->dwOffset是一个数组,它的值是候选词的位置偏移。
取得候选词字符串指针的方法:(TCHAR*)((BYTE*)pList+pList->dwOffset[候选词序号]);//取得候选词
处理这个消息后返回0。
WM_IME_COMPOSITION:
这个消息也很重要,输入法在组字的时候发送这个消息。
这个时候需要处理LPARAM,它的值是多个常数通过按位或组合出来的值,因此需要拆开处理。
[C] 纯文本查看 复制代码
if(lp&CS_INSERTCHAR)//当前光标插入一个字符
{
    wp是字符的值。;
    if(CS_NOMOVECARET)
         不移动插入符;
}
if(lp&GCS_CURSORPOS)//取得正在输入的字符串(拼音之类的)的插入符的位置
{
    HIMC hIMC=ImmGetContext(hWnd);
    插入符的位置=ImmGetCompositionString(hIMC,GCS_CURSORPOS,NULL,0);
    ImmReleaseContext(hWnd,hIMC);
}
if(lp&GCS_COMPSTR)//取得正在输入的字符串(拼音之类的)
{
    HIMC hIMC=ImmGetContext(hWnd);
    UINT uLen,uMem;
    TCHAR*szCompStr;

    uLen=ImmGetCompositionString(hIMC,GCS_COMPSTR,NULL,0);//取得正在输入的字符串大小
    szCompStr=(TCHAR*)malloc(uMem=(uLen+sizeof(TCHAR)));//分配内存
    if(szCompStr)
    {
        SIZE Size;
        szCompStr[uLen]=0;//结尾的\0
        ImmGetCompositionString(hIMC,GCS_COMPSTR,szCompStr,uMem);//取得正在输入的字符串
        显示字符串szCompStr,长度为uLen;
        然后记得绘制插入符;
        free(szCompStr);
    }
    ImmReleaseContext(hWnd,hIMC);
}
if(lp&GCS_RESULTSTR)//取得结果字符串
{
    HIMC hIMC=ImmGetContext(hWnd);
    UINT uLen,uMem;
    TCHAR*szCompStr;

    uLen=ImmGetCompositionString(hIMC,GCS_RESULTSTR,NULL,0);//取得结果字符串大小
    szCompStr=(TCHAR*)malloc(uMem=(uLen+sizeof(TCHAR)));//分配内存
    if(szCompStr)
    {
        szCompStr[uLen]=0;//结尾的\0
        ImmGetCompositionString(hIMC,GCS_RESULTSTR,szCompStr,uMem);//取得结果字符串
        把结果字符串添加到最终输出的文本里面。;
        free(szCompStr);
    }
    ImmReleaseContext(hWnd,hIMC);
}
return 0;
WM_IME_ENDCOMPOSITION://打完字
这个消息需要处理,返回0即可。收到这个消息说明候选词窗口被关闭了。
最后,我把一个写好的程序发上来。
EXE下载:
GetIME.exe (40 KB, 下载次数: 106)
源代码下载:
游客,如果您要查看本帖隐藏内容请回复

本帖被以下淘专辑推荐:

回复

使用道具 举报

1090

主题

2609

帖子

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
237
威望
495 点
宅币
21514 个
贡献
45959 次
宅之契约
0 份
在线时间
2070 小时
注册时间
2014-1-26
 楼主| 发表于 2014-3-30 06:37:52 | 显示全部楼层
下图是运行效果
20140330063512.PNG
编程的过程中发现微软头文件一个拼写错误,dwIndex被写成了deIndex
deIndex.PNG

5

主题

48

帖子

197

积分

用户组: 小·技术宅

UID
167
精华
0
威望
3 点
宅币
132 个
贡献
11 次
宅之契约
0 份
在线时间
30 小时
注册时间
2014-3-30
发表于 2014-3-30 19:37:52 | 显示全部楼层
请先验证邮箱

评分

参与人数 1威望 -10 宅币 -100 贡献 -10 收起 理由
0xAA55 -10 -100 -10 拿这种充满诱导性质的文字来做开门钥匙是对.

查看全部评分

1090

主题

2609

帖子

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
237
威望
495 点
宅币
21514 个
贡献
45959 次
宅之契约
0 份
在线时间
2070 小时
注册时间
2014-1-26
 楼主| 发表于 2014-3-30 19:43:38 | 显示全部楼层

拿这种充满诱导性质的文字来做开门钥匙是对论坛不利的。。。

0

主题

1

帖子

16

积分

用户组: 初·技术宅

UID
184
精华
0
威望
1 点
宅币
12 个
贡献
1 次
宅之契约
0 份
在线时间
0 小时
注册时间
2014-4-8
发表于 2014-4-8 12:52:54 | 显示全部楼层
正好需要这个,谢谢

0

主题

2

帖子

20

积分

用户组: 初·技术宅

UID
531
精华
0
威望
1 点
宅币
16 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2014-10-17
发表于 2014-10-17 09:31:46 | 显示全部楼层
这是我需要的,我可以下载吗?

0

主题

3

帖子

28

积分

用户组: 初·技术宅

UID
545
精华
0
威望
2 点
宅币
21 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2014-11-10
发表于 2014-11-10 15:50:40 | 显示全部楼层
可以试试这个。

0

主题

2

帖子

20

积分

用户组: 初·技术宅

UID
531
精华
0
威望
1 点
宅币
16 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2014-10-17
发表于 2014-11-11 16:36:11 | 显示全部楼层
szCompStr[uLen]=0;//结尾的\0

这一句是有问题的,只是在本程序中碰巧可以运行。但很感谢楼主的分享。希望认识楼主。看到的话请加我扣:289七叁四32。再次感谢楼主。

1090

主题

2609

帖子

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
237
威望
495 点
宅币
21514 个
贡献
45959 次
宅之契约
0 份
在线时间
2070 小时
注册时间
2014-1-26
 楼主| 发表于 2014-11-11 17:33:20 | 显示全部楼层
dakuiz@163.com 发表于 2014-11-11 16:36
szCompStr=0;//结尾的\0

这一句是有问题的,只是在本程序中碰巧可以运行。但很感谢楼主的分享。希望认识楼 ...

szCompStr[uLen]=0;//结尾的\0

这一句是没有问题的。因为
szCompStr=(TCHAR*)malloc(uMem=(uLen+sizeof(TCHAR)));//分配内存
这句多分配了一个字符。所以我觉得没有问题。如果你觉得不是这个原因请告知我。

1

主题

3

帖子

15

积分

用户组: 初·技术宅

UID
562
精华
0
威望
1 点
宅币
10 个
贡献
0 次
宅之契约
0 份
在线时间
2 小时
注册时间
2014-11-17
发表于 2014-11-19 16:41:05 | 显示全部楼层
有点意思。响应也挺快的。

0

主题

2

帖子

19

积分

用户组: 初·技术宅

UID
611
精华
0
威望
1 点
宅币
15 个
贡献
0 次
宅之契约
0 份
在线时间
2 小时
注册时间
2014-12-23
发表于 2014-12-23 21:43:58 | 显示全部楼层
赞啊,太强大了

0

主题

2

帖子

19

积分

用户组: 初·技术宅

UID
611
精华
0
威望
1 点
宅币
15 个
贡献
0 次
宅之契约
0 份
在线时间
2 小时
注册时间
2014-12-23
发表于 2015-1-9 14:30:35 | 显示全部楼层
楼主应该在写一篇如何获取TSF 框架输入法候选的文章~

7

主题

11

帖子

5154

积分

用户组: 技术宅的结界VIP成员

UID
641
精华
1
威望
13 点
宅币
5111 个
贡献
1 次
宅之契约
0 份
在线时间
11 小时
注册时间
2015-1-28
发表于 2015-1-28 17:21:08 | 显示全部楼层
使用,全屏的时候需要

1

主题

23

帖子

80

积分

用户组: 小·技术宅

UID
742
精华
0
威望
0 点
宅币
54 个
贡献
3 次
宅之契约
0 份
在线时间
6 小时
注册时间
2015-3-18
发表于 2015-3-18 21:56:20 | 显示全部楼层
谢谢楼主!我一直都在疑惑这个问题,终于知道资料了

4

主题

47

帖子

146

积分

用户组: 小·技术宅

UID
208
精华
0
威望
1 点
宅币
97 个
贡献
0 次
宅之契约
0 份
在线时间
7 小时
注册时间
2014-4-16
发表于 2015-5-2 23:18:57 | 显示全部楼层
学长学长学长学长!!!我来啦

0

主题

1

帖子

8

积分

用户组: 初·技术宅

UID
858
精华
0
威望
1 点
宅币
5 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2015-5-12
发表于 2015-5-12 13:18:19 | 显示全部楼层
看看看看看看看看
蓝莓味绿茶 该用户已被删除
发表于 2015-7-22 15:34:37 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

0

主题

1

帖子

7

积分

用户组: 初·技术宅

UID
1032
精华
0
威望
1 点
宅币
4 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2015-8-10
发表于 2015-8-10 11:40:10 | 显示全部楼层
不错不错,要的就是这个效果
卡卡 该用户已被删除
发表于 2015-8-10 16:49:04 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

0

主题

1

帖子

7

积分

用户组: 初·技术宅

UID
1067
精华
0
威望
1 点
宅币
4 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2015-8-23
发表于 2015-8-23 17:28:58 | 显示全部楼层
支持  不错 看看

本版积分规则

QQ|申请友链||Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2021-12-9 17:42 , Processed in 0.060209 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表