vc编程的ime输入法菜单开发

如何初识

WINDOWS

IME

编程

IME

编程心得

第一章

Windows9x

系统下汉字输入法的基本原理

第二章

Windows9x

系统提供的

ime

管理函数

第三章

ime

文件中必须使用的结构

自由拼音输入法的测试

输入法程序

[ime]

的调试方法

输入法

(IME)

实现原理
大家知道,

DELPHI

许多控件有

IME

属性。这么好用的东西

VC

可没自带,怎么办呢?其

实,可通过注册表,用

API

实现。下面说一下本人对

IME

的研究结果,并提供示例工程供

大家参考

:

1

、将用到的

API

Cpp

代码

  1. RegOpenKey

:打开注册表一键

  1. RegQueryValue

:查询一键值

  1. RegQueryValueEx

:同上

  1. RegCloseKey

:关闭打开的键

  1. LoadKeyboardLayout

:装载输入法

  1. ActivateKeyboardLayout

:激活输入法

2

IME

信息在注册表中的位置

HKEY_USERS:“.DEFAULT\keyboard layout\preload”

放的是已安装的输入法,下有几

个以数字为名的子键,内容是输入法代号

(keyboard layout)

,如

“e0040804”,

其中左

4

位是

设备代码

(device identifier)

,右

4

位是语言代码

(language identifier)

。例如上面:左

e004

指智能

ABC,

0804

指大陆中文。

(

详见

MSDN)

HKEY_LOCAL_MACHINE:“System\CurrentControlSet\Control\Keyboard Layouts"

的是已注册的输入法。他的子键名为输入法代号

(keyboard layout)

,内容为该输入法的

ime

文件,名称等信息。

3

、主要思路

我们可先把已装的输入法枚举出来

(

从注册表

)

,用户选择其一后,再激活该输入法。

两关键函数:

HKL LoadKeyboardLayout(LPCTSTR pwszKLID,UINT Flags);

第一个参数是待打开的输入法代号,如

“e0040804”(

智能

ABC);

第二个参数是标志位,如

KLF_ACTIVATE(

激活

)

HKL ActivateKeyboardLayout(HKL hkl,UINT Flags);

第一个参数是打开的输入法句柄

(

LoadKeyboardLayout

返回

);

第二个参数是标志位,如

KLF_SETFORPROCESS

(

详见

MSDN)

4

、例子程序

新建一基于对话框的工程,加入一

combobox

控件,增加控制变量

m_cb1

。加入一

edit

件,增加控制变量

m_edt1.

combobox,

增加对

CBN_SELCHANGE

的映射函数

OnSelchangeCombo1()

。对

edit1

,增加对

EN_SETFOCUOS

SetfocusEdit1().

在对话

框类头文件的

public:

下加入数组声明:

CString lst[10];

OnInitDialog()

return

前加如下代码:

Cpp

代码

HKEY

hk,hk1;

long

cp=16;

char

lp[15];

char

a[2];

a[0]=‘1‘;

a[1]=‘\0‘;

CString str,str1;

  1. str=“.DEFAULT\keyboard layout\preload\“;//

已装的输入法。注:

win2000

有所不

  1. str+=a;

int

i=0;

  1. while(::RegOpenKey(HKEY_USERS,str,&hk)==ERROR_SUCCESS)//

打开键

  1. {
  2. a[0]++;//

下一子键

  1. str=".DEFAULT\\keyboard layout\\preload\\";
  2. str+=a;
  3. if(::RegQueryValue(hk,NULL,lp,&cp)!=ERROR_SUCCESS)//

已装的输入法

  1. MessageBox("Error");
  2. ::RegEnumKeyEx
  3. str1="System\\CurrentControlSet\\Control\\Keyboard Layouts\\";//keyboardlay

outLayout

  1. str1+=lp;
  2. lst[i++]=lp;
  3. //

打开对应的

keyboardlayoutLayout

  1. if(RegOpenKey(HKEY_LOCAL_MACHINE,str1,&hk1)==ERROR_SUCCESS

)

  1. {

LPBYTE

lpD=new

BYTE

[80];//DataValue

DWORD

lpT=REG_SZ;//DataType

DWORD

lpS=80; //DataSize

  1. if(RegQueryValueEx(hk1,"Layout text",NULL,&lpT,lpD,&lpS)!=ERROR_SUC

CESS)

  1. MessageBox("Query error",(

LPCTSTR

)lpD);

  1. m_cb1.AddString((

LPCTSTR

)lpD);

  1. delete lpD;
  2. }
  3. else MessageBox("open error");
  4. RegCloseKey(hk1);
  5. }
  6. ::RegCloseKey(hk);
  7. m_cb1.SetCurSel(0);

OnSetfocusEdit1()

加入如下代码:

Cpp

代码

CString temp;

  1. temp=m_cb1.GetCurSel()!=CB_ERR?st[m_cb1.GetCurSel()]:“00000409”;

HKL

hkl;

  1. hkl=LoadKeyboardLayout(temp,KLF_ACTIVATE);//

装载输入法

if(hkl==NULL) OnOK();

  1. ActivateKeyboardLayout(hkl,KLF_SETFORPROCESS);//

激活输入法

OnSelchangeCombo1()

加入如下代码:

Cpp

代码

  1. m_edt1.SetFocus();

即可编译运行。

5

、注意:

win2000

下有所不同。注册表

HKEY_USERS:“.DEFAULT\keyboard

layout\preload

没有子键只有以数字为名的项,值为输入法代号

(keyboard layout)

。在示例

代码中不仅提供了

WIN 9X

下的代码,也提供了

2000

下的相应代码段,具体请参考示例

工程。

IME

编程心得

一、基础知识

:(

不断补充

)

1.

输入法管理器

(IMM)

2.

输入法编程器

(IME)

3.

输入上下文

(IC)

4.

应用程序

(App)

二、

IMM-IME

结构的基本工作过程及特点

用户键盘消息

->

系统通过

IMM

传递给与当前线程对应的

IME->IME

根据输入的消息和输入

上下文中记录的数据,将用户的键盘动作转换成结果串

->

以字串消息的形式返回给

IMM->

放到应用程序窗口的消息队列中。

三、

IME

的构成

1.IME

转换接口

(IME conversion interface)

2.IME

用户接口

(IME user interface)

由用户实现的一组窗口

,

这些窗口用来接收和处理由

IMM

发来的输入消息

,

提供与用户交互

的界面

.

由下面的窗口组成

:

1)

缺省的

IME

窗口

(Default IME window)

2)

用户接口窗口

(UI interface)

3)

用户接口窗口的组件

:

状态窗口

(status window);

编码窗口

(compsition window);

候选窗口

(candidate window).

4)

软键盘和系统菜单

/

图标等

四、

IME

的实现

1.IME

转换接口的实现

这些接口函数在供管理器在适当的时候调用

.

这些函数并非每个都要进行自己的处理

,

大部

分保留一个空函数即可

,

但没有却不可

.

系统默认是要调用的

,

找不到就不行

.

有以下函数

:

1)ImeInquire

2)ImeConfigure

3)ImeProcessKey

4)ImeToAsciiEx

5)ImeSelect

6)ImeSetActiveContext

7)NotifyIME

8)ImeDestroy

9)ImeConversionList

10)ImeEscape

11)ImeSetCompsitionString

12)ImeRegisterWord

13)ImeUnregisterWord

14)ImeGetRegisterWordStyle

15)ImeEnumRegisterWord

2.IME

用户接口的实现

主要包括用户接口窗口

(

窗口类和窗口过程

),

用户界面窗口的组件

(

状态窗口

,

编码窗口和候

选窗口的窗口类和窗口过程

),

输入法的配置窗口

,

软键盘

,

任务条上的指示器窗口

(

图标

,

菜单

,

工具提示

)

和输入法热键等

.

1)

用户接口窗口

:

编程中主要是处理由缺省的

IME

窗口传入的

IME

消息

,

当然

,

并非所有的

IME

消息都需要给出具体处理

(

可以看出这是

IME

编程中的一个原则

).

:

WM_IME_COMPOSITION

WM_IME_STARTCOMPSITION/WM_IME_ENDCOMPOSITION

WM_IME_SELECT

WM_IME_NOTIFY

WM_IME_CHAR

五、具体实现步骤:

IME

实质上是一个

DLL

实现,由系统调用。而这个

DLL

则分别实现了系统要调用的功能

函数。所以有些函数虽然不做什么事情,但是必需挂上一个空壳。否则调用出错。

1.DLLMain()

的架构

1)

进入进程

DLL_PROCESS_ATTACH

事件中,注册用户接口窗口类及其组件的窗口类:使用

RegisterClassEx()

完成此注册过程。设置类名字段

(lpszClassName)

为用户接口窗口类类

名(包括结束标志

‘\0‘

在内最长可达

16

字符),在类风格

(style)

字段中必须包括

CS_IME

风格。设置附加内存大小(

cbWndExtra

)。

2)

退出进程

注销上述与输入法编辑器有关的窗口类,进行全局性的清理工作。

2.

打开

/

关闭输入法编辑器时进行的初始化操作

1)

用户接口窗口是由缺省的

IME

窗口在接到

WM_IME_SELECT

消息时创建的。输入法管

理器通过调用

ImeRequire

接口函数获取输入法编辑器的相关信息

(

属性、用户接口窗口

类,可选项

)

,据此进行输入法编辑器的初始化工作,创建输入法编辑器的用户接口窗口。

所以

ImeRequire

是输入法转换接口必须实现的第一个函数。

2)

在用户接口窗口被创建后,可以进行输入法编辑器全局性的一些初始化工作,比如申请

自己的私有内存,建立私有上下文等,这些工作一般在处理

WM_IME_SELECT

消息或在

接口函数

ImeSelect

中进行,也可以在窗口过程处理

WM_CREATE

消息时进行。

3.

进入进程后

:

1)

初始化词库

2)

创建字体

3)

注册窗口类

4.

UI

窗口建立后

,

建立写作窗口和候选窗口

各个窗口下进行各自的消息函数处理

在这里有疑问

:UI

窗口是什么

?UI

窗口处理了

IME

的好多消息

.–

解答参看

?

基于

IMM-IME

输入法接口的实现方法

下一个任务

:

看这个论文

UI

窗口是对用户不可见的

,

但是它是所有用户界面窗口的组件窗口的父窗口

,

是全部组件窗

口的管理者

.

5.

构建框架的问题

projects-settings-c/c++-catagory:prepossessor:additional include directories:./

避免添加系统默认的头文件

6.

注意的细节问题

:

1)global.c

中的

pragma data_seg(“.zhenhuadic”),

应详细了解其作用

,

其与

Czh.def

中的定

义有相关联的地方

.(

对我们的工程名

Czh

来说

)

2)freepy.exp : warning LNK4070: /OUT:Czh.ime directive in .EXP differs from output

filename;C:\WINDOWS\system32\freepy.ime; ignoring directive

对于这个

BUILD

中的错误

,

关联之处在于

Czh.def

中定义了

lib

的输出名为

Czh,

要求这个

lib

的输出名与

Output file name freepy

相同

.

3)

如果

.ime

名和上述

2)

中说的问题没有的话

,

freepy.h(

原工程

)

中的

define

FREEPYFILENAME

_T(“freepy.ime”)

定义正确

,

则在

HZfreepy.h

中改变以下几个文件名

C:\windows\system32(window xp

系统下

)

下的相关文件名相同则可

:

freepy.tab–

字库

freepysys.dic–

系统词库

freepyusr.dic–

用户词库

4)

ImeSelect

的函数中

,

有个注册表键值的处理与工程有关联

5)

有四条消息的遗漏

:

imm:NotifyIME

imm:NotifyIME:NI_CONTEXTUPDATED

imm:NotifyIME:NI_CONTEXTUPDATED:IMC_SETCOMPOSITIONWINDOW

UIWnd

UIWnd:WM_IME_NOTIFY

UIWnd:WM_IME_NOTIFY:IMN_SETCOMPOSITIONWINDOW

UIWnd:3

UIWnd

UIWnd:WM_IME_NOTIFY

UIWnd:WM_IME_NOTIFY:IMN_SETOPENSTATUS

UIWnd:3

UIWnd

UIWnd:WM_IME_NOTIFY

UIWnd:WM_IME_NOTIFY:IMN_SETCONVERSIONMODE

UIWnd:3

UIWnd

UIWnd:WM_IME_NOTIFY

UIWnd:WM_IME_NOTIFY:IMN_SETSENTENCEMODE

在开发过程中

,

初始化的四条消息缺漏

.

考察

:

与代码有关还是与安装有关

?

自己开发安装是手动完成的

,

即通过直接改注册表来实现的

.

为了检测

,

我将自己的开发代码

工程作如下变动

:

—-settings-output file name\freepy.ime



字库词库名不变

,

但存在

system32

目录下

只要这样

,

就可以出现了上述的消息

.

这时还与

ImeSelect

下的注册表项读取无关、与

czh.h

中的文件名定义无关、与

czh.def

中的

lib

定义无关。但是在调试时,选择输入法时却可将

本工程的图标之类的调出来。这样看来,只是无法输入文字(还没实现相关的功能),目

前的结论是:四个消息的遗漏与安装有关。

7)

制作安装程序

:

仿照

freepy

的安装程序

,

制作一个自己的安装程序

,

然后重新安装

,

安装之后

要进行更新

,

也就是到输入法的添加删除界面进行删除然后再添加进来

,

注销系统之后

,

就可

以用了

.

这样安装的结果是

:

多出了上面的第二条消息

,

其它仍然不行

.–

哪究竟与谁有关系

?

是不是与

代码有关

?

只要将

,settings

中的作改变就可以实现消息补充

.

这与什么有关系

?

8)

再重新安装一次

,

这次重装是这样的

:

–HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Keyboard Layouts\

下对应

的振华输入法子项都删除

–HKEY_CURRENT_USER\Keyboard Layout\preload

下对应的本输入法的子项删除

–HKEY_LOCAL_MACHINE\software\

下的

czhhua

删除

.

这样重装之后

,

消息出现

.

7.

流程分析

:

1)

字库的装载

这个工作是在程序进入

DLL

的开始部分就执行的

,

将字典内容保存到存储区

,

以备将

COMPSTR

转成汉字时调用存储区

.

第一章

Windows9x

系统下汉字输入法的基本原理

Windows

系统下汉字输入法实际上是将输入的标准

ascii

字符串按照一定的编码规则转换

为汉字或汉字串,进

入到目的地。

由于应用程序各不相同,用户不可能自己去设计转换程序,因此,汉字输入自然而然

落到

WINDOWS

系统管理中。

一、输入法与系统的关系

键盘事件

应用程序

Windows

USER.EXE

输入法管理器

输入法

系统的键盘事件有

windows

user.exe

软件接收后,

user.exe

在将键盘事件传导输入法

管理器

(Input Method

Manager,

简称

IMM)

中,管理器

再将键盘事件传到输入法中,输入法根据用户编码字

典,翻译键盘事件为对

应的汉字

(

或汉字串

)

然后再反传到

user.exe

中,

user.exe

再将翻译后的键盘事件传

给当前正运行的应用

程序,从而完成汉字的输入。

二、汉字输入法的组成

微软

Windows9x

系统中汉字输入法的名称是

“Input Method Editor” ,

简称

IME,

输入法的程

序名称为

:*.ime,

数据文

件名称为

*.MB,

即通常说的输入法编码表

(

字典

).

实际上

IME

文件是一个动态连接库程序(

DLL

),它与

dll

文件没有区别,只是名称不同

而已。

一般汉字输入法都由三个窗口组成

:

状态窗口(

Status Windows)-

显示当前的输入法状态(中文还是英文等站环信息);

编码输入窗口

(Composition Windows)-

显示当前击键情况;

汉字选择窗口

(Candidates Windows)-

列出当前编码的全部汉字

(

),

供用户选择或查询。

上述三个窗口由基本的用户接口(

User Interface

)函数管理着。

现在我们用

Dumpbin.exe

打开微软提供的拼音输入法

WINDOWS\SYSTEM\WINPY.IME

)看看它有什么组成(这里一

WINDOWS98

为例,并假定

windows

系统安装在

c:

盘下):

Cpp

代码

  1. C:\Dumpbin

c:\windows\system\winpy.ime

Microsoft ? COFF Binary File Dumper Version 6.00.8168

Copyright ? Microsoft Corp 1992-1998. All rights reserved.

Dump of file WINPY.IME

File Type: DLL

//

IME

实际为

dll

程序

Section contains the following exports for WINPY.ime

0 characteristics

34A37323 time date stamp Fri Dec 26 17:04:35 1997

  1. 0.00 version
  2. 1 ordinal base
  3. 19 number of functions //

共有19个函数

  1. 19 number of names

//

对应19个名称

  1. ordinal hint RVA name
  2. 1 0 0000A010 CandWndProc

//”

选择汉字窗口

"

注册函数

  1. 2 1 0000E750 CompWndProc

//”

输入编码窗口

"

注册函数

  1. 3 2 0000FB50 ImeConfigure

//

配置当前

ime

参数函数

  1. 4 3 0000FEC0 ImeConversionList//

将字符或字符串转换成目标字符

  1. 5 4 0000FFA0 ImeDestroy

//

退出当前使用的

IME

  1. 6 5 000030D0 ImeEnumRegisterWord
  2. 7 6 0000FFB0 ImeEscape //

应用软件访问输入法的接口函数

.

  1. 8 7 00003080 ImeGetRegisterWordStyle
  2. 9 8 0000E9A0 ImeInquire

//

启动并初始化当前

IME

输入法

  1. 10 9 0000A800 ImeProcessKey

//IME

输入键盘事件管理函数

  1. 11 A 00002C20 ImeRegisterWord //

向输入法字典注册字符串

  1. 12 B 000109A0 ImeSelect //

启动当前

IME

输入法

  1. 13 C 000109E0 ImeSetActiveContext //

设置当前的输入处于活动状态

.

  1. 14 D 0000C850 ImeSetCompositionString

由应用程序设置输入法编码

  1. 15 E 0000AEE0 ImeToAsciiEx

//

将输入的键盘事件转换为汉字编码事件

  1. 16 F 00002F40 ImeUnregisterWord //

删除被注册的字符串

.

  1. 17 10 0000CA90 NotifyIME

//IME

事件管理函数

  1. 18 11 00005160 StatusWndProc

//

状态窗口注册函数

  1. 19 12 00002350 UIWndProc

//

用户界面接口函数

  1. Summary
  2. 5000 .ShareDa
  3. 7000 .data
  4. 2000 .idata
  5. 1000 .rdata
  6. 3000 .reloc
  7. 5000 .rsrc
  8. 2000 .sgroup
  9. 18000 .text

从上述可以看出,

IME

程序共有19个出口函数组成,每一个函数都有特定的格式,它们

担负着与

windows

系统传递信息的作用,这些函数是供

Windows

系统调用的。

三、输入法的函数简介

下面我们将介绍上述各个函数的功能及接口格式。

Cpp

代码

BOOL

ImeInquire( //

初始化

IME

  1. LPIMEINFO

lpIMEInfo,

//

用于初始化该输入法的结构地址

LPTSTR

lpszWndClass, //

当前输入法的名称

LPCTSTR

或者

dword lpszData //

系统信息

,9X

系列值为

0,NT/2000

下有实际值

)

如果该函数初始化成功

,

返回

TURE,

否则为

FALSE

用户应该搞清楚

IMEINFO

结构

,

特关系着你设计的输入法是否成功

.

有关该结构请

"

结构

"

一章

.

  1. 2.

DWORD

IMEConversionList( //

将某字符或字符串转换成目标字符串

  1. HIMC

hIMC,

//

与当前输入法相关的应用程序句柄

  1. LPCTSTRlpSrc, //

要转换的字符串

(

也可能是结果串

,

可由

uFlag

指定

)

  1. LPCANDIDATELIST lpDst, ///

转换后的字符串

(

也可能是源串

,

可由

uFlag

指定

)

DWORD

dwBufLen, //

转换后有几个字符

UINT

uFlag //

指定结果的存放位置

  1. )

如果成功

,

返回转换后的字符串长度

  1. 3.

BOOL

ImeConfigure( //

用户设置输入法接口

HKL

hKL, //

当前输入法句柄

HWND

hWnd, //

配置窗口的父窗口

DWORD

dwMode, //

配置什么

LPVOID

lpData //

用户设置的数据

  1. )

该函数的功能是提供给输入法使用者一个可以更改某些隐含设置的能力

.

如果你用过别人的输入法

,

其中的

"

配置输入法

…”

功能既是也

!

对于一个初写输入法的人

,

可以不予理它

.

  1. 4.

BOOL

ImeDestroy( //

关闭当前输入法

UINT

uReserved //

无用

(0)

  1. )

成功返回

TURE,

否则为

FALSE

  1. 5.

LRESULT

ImeEscape( //

用户软件访问输入法内部信息的接口

  1. HIMC hIMC, //

当前的应用程序句柄

UINT

uEscape, //

设置函数功能

  1. //=IME_ESC_QUERY _SUPPORT
  2. //=IME_ESC_RESERVED_LAST IME_ESC_RESERVED_FIRST
  3. //=IME_ESC_PRIVATE_FIRST IME_ESC_PRIVATE_LAST
  4. //=IME_ESC_SEQUENCE_TO_ INTERNAL
  5. //=IME_ESC_GET_EUDC_ DICTIONARY
  6. //=IME_ESC_SET_EUDC_ DICTIONARY
  7. //=IME_ESC_MAX_KEY
  8. //=IME_ESC_IME_NAME
  9. //=IME_ESC_SYNC_HOTKEY
  10. //=IME_ESC_HANJA_MODE
  11. //=IME_ESC_GETHELPFILENAME(

只适应

Windows 98

Windows 2000)

  1. //=IME_ESC_PRIVATE_HOTKEY(w95

下不可用

)

LPVOID

lpData //

当前功能所需的数据

  1. )

如果失败

,

返回

0,

否则有个功能决定

有时

,

人们可以用此函数怀区输入法的名称、帮助文件名称等。当然,我们可以不

提供这些功能。

  1. 6

BOOL

ImeSetActiveContext( //

激活或搁置当前的输入法

  1. HIMC hIMC, //

当前用户程序句柄

BOOL

fFlag //

激活或搁置:

=TRUE

激活

=FALSE

搁置

  1. )

成功返回

TRUE,

否则为

FALSE

  1. 7

BOOL

ImeProcessKey( //

处理应用程序传入的所有击键事件,监测是否是当前

输入法所需的

  1. HIMC hIMC, //

应用程序句柄

UINT

uVirKey, //

需处理的虚键

DWORD

lParam, //

击键消息参数

  1. CONST

LPBYTE

lpbKeyState //

当前键盘状态(

256

字节)

  1. )

如果此键是该输入法需要的,则返回

TRUE,

否则为

FALSE

只有返回

true

的击键,

IME

才去处理

  1. 8

BOOL

NotifyIME( //

输入法选择窗口状态管理函数:

  1. HIMC hIMC, //

当前的应用程序句柄

DWORD

dwAction, //

状态值

DWORD

dwIndex, //

与状态值有关的序号

DWORD

dwValue //

与状态值有关的值

  1. )

状态值说明:

  1. =NI_OPENCANDIDATE

打开编码选择窗口

  1. =NI_CLOSECANDIDATE

关闭当前的编码选择窗

  1. =NI_SELECTCANDIDATESTR

选摘编码

此时:

dwIndex

被选择的编码列表序号

.

  1. dwValue

被选中的编码在当前的编码列表中的序号

  1. =NI_CHANGECANDIDATELIST

改变当前的编码列表(按

pageup

等键操作)

此时:

dwIndex

被选择的编码列表序号

.

  1. dwValue

不用

  1. =NI_SETCANDIDATE_PAGESTART

设置编码开始页号

此时:

dwIndex

被改变的编码列表序号

  1. dwValue

新页的开始序号

.

  1. =NI_SETCANDIDATE_PAGESIZE

改变编码列表页的大小

此时:

dwIndex

当前编码页序号

  1. dwValue

新的页大小

  1. =NI_CONTEXTUPDATED

更新应用程序的信息的输入法的信息:移动位置,设置

模式,设置编码窗口,字体。

此时:

dwIndex

只用

dwValue=IMC_SETCONVERSIONMODE, IMC_SETSENTENCEMODE

  1. dwValue

可取由

WM_IME_CONTROL

发送的下列值

:

  1. IMC_SETCANDIDATEPOS
  2. IMC_SETCOMPOSITIONFONT
  3. IMC_SETCOMPOSITIONWINDOW
  4. IMC_SETCONVERSIONMODE
  5. IMC_SETSENTENCEMODE
  6. IMC_SETOPENSTATUS
  7. =NI_COMPOSITIONSTR

改变编码窗口中的编码

此时:

dwIndex

取下列值:

CPS_COMPLETE

完成编码转换

  1. CPS_CONVERT

转换编码

  1. CPS_REVERT

取消当前的编码

  1. CPS_CANCEL

清除编码,并关闭编码窗

  1. dwValue

不用

此函数成功,返回

TRUE

,否则为

FALSE

  1. 9

BOOL

ImeSelect( //

初始化输入法

  1. HIMC hIMC, //

当前应用程序句柄

BOOL

fSelect //

是否初始化当前输入法,

TRUE

表示初始化

  1. )

返回:成功返回

true

,否则为

FALSE

  1. The ImeSetCompositionString function is used by an application to set the IME
  2. composition string structure with the data contained in the lpComp or lpRead
  3. parameters. The IME then generates a message.
  4. 10

BOOL

WINAPI ImeSetCompositionString( //

将编码窗口中输入的编码保存

的编码结构中,

  1. //

同志发送编码完成的消息

  1. //

WM_IME_COMPOSITION

)给系统,

  1. HIMC hIMC, //

当前的应用程序句柄

DWORD

dwIndex, //

设置此函数功能

  1. //=SCS_SETSTR
  2. //=SCS_CHANGEATTR
  3. //=SCS_CHANGECLAUSE
  4. //= SCS_QUERYRECONVERTSTRING
  5. //=SCS_RECONVERTSTRING
  6. //=SCS_SETRECONVERTSTRING

LPCVOID

lpComp, //

编码数据区

DWORD

dwCompLen, //

编码数据区长度

LPCVOID

lpRead, //

读入的编码数据

DWORD

dwReadLen //

读入的编码数据长度

  1. 11

UINT

ImeToAsciiEx( //

转换编码称汉字(串)

UINT

uVirKey, //

虚键

UINT

uScanCode, //

扫描码

  1. CONST

LPBYTE

lpbKeyState, //

用户定义的键盘状态

LPDWORD

lpdwTransBuf, //

转换后的数据存放区

UINT

fuState, //

活动菜单标志

  1. HIMC hIMC //

当前的应用程序句柄

  1. )

返回:返回值表示有几个消息,可理解为:本编码对应的汉字串有几个汉字组成

(当然,这并不相等)。

  1. 12

BOOL

WINAPI ImeRegisterWord(

LPCTSTR

lpszReading,

DWORD

dwStyle,

LPCTSTR

lpszString

  1. )
  2. 13

BOOL

WINAPI ImeUnregisterWord(

LPCTSTR

lpszReading,

DWORD

dwStyle,

LPCTSTR

lpszString

  1. )
  2. 14

UINT

WINAPI

  1. ImeGetRegisterWordStyle(

UINT

nItem,

  1. LPSTYLEBUF lpStyleBuf
  2. )
  3. 15

UINT

WINAPI ImeEnumRegisterWord(

  1. hKL,
  2. REGISTERWORDENUMPROC lpfnEnumProc,

LPCTSTR

lpszReading,

DWORD

dwStyle,

LPCTSTR

lpszString,

LPVOID

lpData

  1. )
  2. 16

DWORD

WINAPI ImeGetImeMenuItems(

  1. HIMC hIMC,

DWORD

dwFlags,

DWORD

dwType,

  1. LPIMEMENUITEMINFO lpImeParentMenu,
  2. LPIMEMENUITEMINFO lpImeMenu,

DWORD

dwSize

  1. )

.ime

的版本信息

(

与普通

DLL

的区别

)

Cpp

代码

  1. VS_VERSION_INFO

VERSIONINFO

代表字符

含义

  1. FILEVERSION

4,0,0,950 //4.00.950 95

PRODUCTVERSION 4,0,0,950 //4.00.950 95

FILEFLAGSMASK 0x3fL

  1. FILEFLAGS

0xaL

FILEOS 0x10004L //VOS_DOS_WINDOWS32 WIN32

软件

,

可在

DOS

下运行

FILETYPE 0x3L //VFT_DRV

驱动程序

FILESUBTYPE 0xbL //VFT2_DRV_INPUTMETHOD

输入法驱动程序

  1. BEGIN
  2. BLOCK “StringFileInfo”
  3. BEGIN
  4. BLOCK “080403a8”
  5. BEGIN
  6. VALUE “Comments”, “\0”
  7. VALUE “CompanyName”, "

唐码软件开发工作室

\0”

  1. VALUE “FileDes cription”, "

唐码输入法

版本

1.0\0”

  1. VALUE “FileVersion”, “4.00.950\0”
  2. VALUE “InternalName”, "

唐码输入法

版本

1.0\0”

  1. VALUE “LegalCopyright”, “Copyright ?

唐码软件开发工作室

1999-1999\0”

  1. VALUE “LegalTrademarks”, “\0”
  2. VALUE “OriginalFilename”, “TM.IME\0”
  3. VALUE “PrivateBuild”, “\0”
  4. VALUE “ProductName”, "

唐码输入法

版本

1.0\0”

  1. VALUE “ProductVersion”, “4.00.950\0”
  2. VALUE “SpecialBuild”, “\0”
  3. END

第二章

Windows9x

系统提供的

ime

管理函数

上一章

,

我们介绍了

ime

文件中必须设计的函数

,

这些函数要靠我们自己来设计。要完成这

些函数的设计,

需用到

windows

系统提供的管理函数

(Input Method Manager,

简称

IMM)

IMM

函数可以被

IME

函数使用,也可用于应用软件直接管理

IME

相关术语:

(1)input method context

简称

IMC–

输入法相关部分,在这里解释为:相关连的应用程序

(进程)

(2)component of the input context

简称

IMCC–IMC

的部件,是

INPUTCONTEXT

结构的

成员。

一、

IME

中使用的

IMM

函数清单

Cpp

代码

  1. ImmGetCompositionWindow

//

取编码窗口信息

  1. ImmSetCompositionWindow

//

设置编码窗口信息

  1. ImmGetCandidateWindow

//

取选择窗口信息

  1. ImmSetCandidateWindow

//

设置选择窗口信息

  1. ImmGetCompositionString

//

取编码窗口的某一信息

  1. ImmSetCompositionString

//

设置编码窗口的某一信息

  1. ImmGetCompositionFont

//

取编码字体

  1. ImmSetCompositionFont

//

设置编码字体

  1. ImmGetNumCandidateList

//

取选择区中编码数

  1. ImmGetCandidateList //

取选择区中编码

  1. ImmGetGuideLine
  2. ImmGetConversionStatus //

取当前输入法的状态(

ACSII,SHAPE,FULL

等)

  1. ImmGetConversionList //

重新获得选择区转换表

  1. ImmGetOpenStatus //

取输入法打开属性

  1. ImmSetConversionStatus //

设置输入法状态

  1. ImmSetOpenStatus //

设置输入法打开状态

  1. ImmNotifyIME //

通报

IME

,输入法状态被改变

  1. ImmGenerateMessage //

将我们的汉字串法发送到与当前输入法相关联的应用软件

  1. ImmRequestMessage //

向应用程序发送

WM_IME_REQUEST

  1. ImmLockIMC //

获取当前

IMC

INPUTCONTEXT

结构信息,增加

IMC

计数器

  1. ImmUnlockIMC //

释放

IMC

计数器

  1. ImmGetIMCLockCount //

取计数器值

  1. ImmCreateIMCC //

创建

INPUTCONTEXT

结构的一个成员

  1. ImmDestroyIMCC //

删除

IMC

成员缓冲区

  1. ImmLockIMCC //

IMCC

缓冲地址,同时使

IMCC

的计数器值增加

  1. ImmUnlockIMCC //

递减

IMCC

计数器

  1. ImmReSizeIMCC //

重新设置

IMC

的成员的缓冲区大小

  1. ImmGetIMCCSize //

IMC

成员的缓冲区大小

  1. ImmGetIMCCLockCount //

返回

IMC

计数器值

  1. ImmGetHotKey //

取输入法状态键,该函数供控制面板使用

  1. ImmSetHotKey //

设置输入法的热键

  1. ImmCreateSoftKeyboard //

产生一个软键盘

  1. ImmDestroySoftKeyboard //

销毁软键盘

  1. ImmShowSoftKeyboard //

显示或隐藏软键盘

二、

IMM

函数使用格式说明

Cpp

代码

  1. 1

BOOL

WINAPI ImmGenerateMessage( //

将我们的汉字串法发送到与当前输入

法相关联的应用软件中

HIMC hIMC //

与当前输入法相关联的应用软件的句柄,

  1. //

该结构的

hMsgBuf

项即为汉字串消息

)

成功为

TRUE

,否则为

FALSE

  1. 2

LRESULT

WINAPI ImmRequestMessage( //

向应用程序发送

WM_IME_REQUEST

  1. //

只是用于

w98

w2000

  1. HIMC

hIMC,

//

与当前输入法相关联的应用软件的句柄

WPARAM

wParam, //

WM_IME_REQUEST

相关的

wP

LPARAM

lParam //

WM_IME_REQUEST

相关的

LP

  1. //=IMR_COMPOSITIONWINOW
  2. //=IMR_CANDIDATEWINDOW
  3. //=IMR_COMPOSITIONFONT
  4. //=IMR_RECONVERTSTRING
  5. //=IMR_CONFIRMRECONVERTSTRING
  6. //=IMR_QUERYCHARPOSITION
  7. //=IMR_DOCUMENTFEED
  8. )
  9. 3

LPINPUTCONTEXT WINAPI ImmLockIMC( //

获取当前

IMC

INPUTCONTEXT

结构信息,增加

IMC

计数器

  1. HIMC hIMC //

当前应用程序句柄

  1. )

成功返回

INPUTCONTEXT

结构指针,否则为

NULL

  1. 4

BOOL

WINAPI ImmUnlockIMC( //

释放

IMC

计数器

  1. HIMC hIMC //

当前应用程序句柄

  1. )

返回

:

如果

IMC

计数器被减少到

0

,

返回

FALSE,

否则为

TRUE.

注意

:ImmLockIMC

ImmUnlockIMC

必须成对出现

,

必须是相同的

HIMC

  1. 5

HIMCC WINAPI ImmGetIMCLockCount( //

取计数器值

  1. HIMC hIMC //

当前应用程序句柄

  1. )

如果成功返回

HIMC

的计数器值,否则为

NULL.

  1. 6

HIMCC WINAPI ImmCreateIMCC( //

创建

INPUTCONTEXT

结构的一个成员

DWORD

dwSize //

成员的缓冲区长度

  1. )

如果成功返回

IMC

的成员句柄,否则为

NULL

  1. 7

HIMCC WINAPI ImmDestroyIMCC( //

删除

IMC

成员缓冲区

  1. HIMCC hIMCC //

被删除的

IMC

的成员

  1. )

如果成功返回

NULL

,否则等于该

HIMCC.

  1. 8

LPVOID

WINAPI ImmLockIMCC( //

IMCC

缓冲地址,同时使

IMCC

的计数

器值增加

  1. HIMCC hIMCC //IMC

成员句柄

  1. )
  2. If the function is successful, the return value is the pointer for the IMC component

.

  1. Otherwise, the return value is NULL.
  2. 9

BOOL

WINAPI ImmUnlockIMCC( //

递减

IMCC

计数器

  1. HIMCC hIMCC //IMC

成员句柄

  1. )

如果

IMCC

的计数器值为零,则返回

FALSE

,否则为

TRUE.

  1. 10

HIMCC WINAPI ImmReSizeIMCC( //

重新设置

IMC

的成员的缓冲区大小

  1. HIMCC hIMCC, //IMC

的成员句柄

DWORD

dwSize //

新缓冲区大小

  1. )

如果成功,返回新的

HIMCC

,否则为

NULL.

  1. 11

DWORD

WINAPI ImmGetIMCCSize( //

IMC

成员的缓冲区大小

  1. HIMCC hIMCC //IMC

成员句柄

  1. )

返回

IMC

成员的缓冲区大小

  1. 12

DWORD

WINAPI ImmGetIMCCLockCount( //

返回

IMC

计数器值

  1. HIMCC hIMCC //IMC

成员的句柄

  1. )

成功返回该

IMCC

的计数器值,否则为

0

  1. 13

BOOL

WINAPI ImmGetHotKey( //

取输入法状态键,该函数供控制面板使用

DWORD

dwHotKeyID,

  1. LPUINT lpuModifiers,
  2. LPUINT lpuVKey,
  3. LPHKL lphKL
  4. )
  5. 14

BOOL

WINAPI ImmSetHotKey( //

设置输入法的热键

DWORD

dwHotKeyID,

UINT

uModifiers,

UINT

uVKey,

  1. hKL hKL
  2. )
  3. 15

HWND

WINAPI ImmCreateSoftKeyboard( //

产生一个软键盘

UINT

uType, //

软件盘上的键码含义的定义方式

  1. //=SOFTKEYBOARD_TYPE_T1
  2. //=SOFTKEYBOARD_TYPE_C1

UINT

hOwner, //

该输入法的

UI

窗口

int

x, //

定位坐标

int

y //

定位坐标

  1. )

成功返回软键盘的窗口句柄

  1. 16

BOOL

WINAPI ImmDestroySoftKeyboard( //

销毁软键盘

HWND

hSoftKbdWnd //

软年盘窗口句柄

  1. )

成功为

TRUE,

法哦则为

FALSE.

  1. 17

BOOL

WINAPI ImmShowSoftKeyboard( //

显示或隐藏软键盘

HWND

hSoftKbdWnd, //

软年盘窗口句柄

int

nCmdShow //

窗口状态

=SW_HIDE

表示隐藏,

=SW_SHOWNOACTIVATE

示显示

  1. )

如构成功返回

TRUE.

否则为

FALSE.

第三章

ime

文件中必须使用的结构

前二章我们讲述了

ime

imm

函数

,

二者之间是靠下列结构通讯的。

Cpp

代码

  1. 1

IMEINFO

struct tagIMEInfo { //

输入法的接口信息

用于

ImeInquire

函数中

DWORD

dwPrivateDataSize;//

用户设计的数据结构的字节数

DWORD

fdwProperty; //

输入法对键盘事件的相应特性

  1. //

其中其高字可为下列字节位的组合:

  1. //=IME_PROP_AT_CARET

转换窗口是否放置在需插入字符的位置

  1. //=IME_PROP_SPECIAL_UI

该输入法具有特殊用户接口

  1. //=IME_PROP_CANDLIST_START_FROM_1

输入法的选择窗口中汉字串的起始

序号为

1

  1. //=IME_PROP_UNICODE

支持

UNICODE

字符

  1. //

其中其低字可为下列字节位的组合:

  1. //=IME_PROP_END_UNLOAD
  2. //=IME_PROP_KBD_CHAR_FIRST

首先由键盘转换字符

  1. //=IME_PORP_NEED_ALTKEY

ALT

键盘事件传送到

IME

输入法内

  1. //=IME_PROP_IGNORE_UPKEYS

禁止上位键事件进入输入法内

  1. //=IME_PROP_COMPLETE_ON_UNSELECT

当关闭输入法时,完成编码的转

  1. //

用于

W98

2000

DWORD

fdwConversionCaps;//

当前输入法具有的功能特性

,

如有软键、标点、中

西文切换等功能

  1. //=IME_CMODE_NATIVE

设置活动模式

  1. //=IME_CMODE_FULLSHAPE

设置全角模式

  1. //=IME_CMODE_CHARCODE

设置为字符模式

  1. //=IME_CMODE_SOFTKBD //

设置软键盘模式

  1. //=IME_CMODE_NOCONVERSION //

不支持模式变换

  1. //=IME_CMODE_EUDC //
  2. //=IME_CMODE_SYMBOL //

设置标点字符模式

DWORD

fdwSentenceCaps; //

  1. //=IME_SMODE_PLAURALCLAUSE
  2. //=IME_SMODE_SINGLECONVERT
  3. //=IME_SMODE_AUTOMETIC
  4. //=IME_SMODE_CONVERSATION

DWORD

fdwUICaps; //

用户界面能力:支持软键盘等

  1. //=UI_CAP_2700
  2. //=UI_CAP_ROT90
  3. //=UI_CAP_ROTANY
  4. //=UI_CAP_SOFKBD

DWORD

fdwSCSCaps; //

用户设置编码串的能力

  1. //=SCS_CAP_COMPSTR
  2. //=SCS_CAP_MAKEREAD

DWORD

fdwSelectCaps; //

输入法切换时是否使用以前输入法的模式

  1. //=SELECT_CAP_CONVMODE
  2. //=SELECT_CAP_SENTENCE
  3. } IIMEINFO;
  4. 2

COMPOSITIONSTR

用于编码管理

  1. typedef struct tagCOMPOSITIONSTR { //

用于存放编码信息的信息

:

所有的实际信

息放在本结构的后面

DWORD

dwSize; //

当前编码信息需要的存储空间

=

读入的编码

+

属性

+

子串

+

属性

+

编码

+

属性

+

结果

+

属性

DWORD

dwCompReadAttrLen; //

读入的编码属性长度

DWORD

dwCompReadAttrOffset; //

存放在内存的位置

DWORD

dwCompReadClsLen; //

读入的子串长度

DWORD

dwCompReadClsOffset; //

存放在内存的位置

DWORD

dwCompReadStrLen; //

读入的编码长度

DWORD

dwCompReadStrOffset; //

存放在内存的位置

DWORD

dwCompAttrLen; //

编码属性长度

DWORD

dwCompAttrOffset; //

存放在内存的位置

DWORD

dwCompClsLen; //

编码子串长度

DWORD

dwCompClsOffset; //

存放在内存的位置

DWORD

dwCompStrLen; //

编码串长度

DWORD

dwCompStrOffset; //

存放在内存的位置

DWORD

dwCursorPos; //

当前光标位置

DWORD

dwDeltaStart; //

被修改编码的位置

DWORD

dwResultReadClsLen; //

读入结果子串长度

DWORD

dwResultReadClsOffset; //

存放在内存的位置

DWORD

dwResultReadStrLen; //

读入的编码长度

DWORD

dwResultReadStrOffset; //

存放在内存的位置

DWORD

dwResultClsLen; //

结果子串长度

DWORD

dwResultClsOffset; //

存放在内存的位置

DWORD

dwResultStrLen; //

结果串长度

DWORD

dwResultStrOffset; //

存放在内存的位置

DWORD

dwPrivateSize; //

用户自定义数据长度

DWORD

dwPrivateOffset; //

存放在内存的位置

  1. } COMPOSITIONSTR;
  2. 3

CANDIDATEINFO

用于编码选择管理

  1. typedef struct tagCANDIDATEINFO { //

编码选择信息的信息,其后为实际编码列

表数据

DWORD

dwSize; //

数据所占内存大小

DWORD

dwCount; //

表马列表个数

DWORD

dwOffset[32]; //

各个编码列表的内存位置

DWORD

dwPrivateSize; //

自定义数据尺寸

DWORD

dwPrivateOffset; //

缓冲区位置

  1. } CANDIDATEINFO;
  2. 4

GUIDELINE

  1. typedef struct tagGUIDELINE {

DWORD

dwSize;

DWORD

dwLevel; // the error level.

  1. // GL_LEVEL_NOGUIDELINE,
  2. // GL_LEVEL_FATAL,
  3. // GL_LEVEL_ERROR,
  4. // GL_LEVEL_WARNNING,
  5. // GL_LEVEL_INFORMATION

DWORD

dwIndex; // GL_ID_NODICTIONARY and so on.

DWORD

dwStrLen; // Error Strings, if this is 0, there

  1. // is no error string.

DWORD

dwStrOffset;

DWORD

dwPrivateSize;

DWORD

dwPrivateOffset;

  1. } GUIDELINE;
  2. 5

CANDIDATELIST

  1. The CANDIDATELIST structure contains information about a candidate list.
  2. typedef struct tagCANDIDATELIST { //

编码选择列表信息

=

〉管理编码窗口中的列

表信息

DWORD

dwSize; //

用字节表示的内存大小:

=sizeof(CANDIDATELIST)+

选择字符

数据

DWORD

dwStyle; //

列表串的取值方式

  1. //=IME_CAND_UNKNOWN

列表数据的格式无定义

  1. //=IME_CAND_READ

读到什么数据即为什么数据

,

一般我们使用该属性

  1. //=IME_CAND_CODE

如果

dwCount=1

dwOffset

不是地址,而是实际数据,

  1. // >1 dwOffset

表示地址

  1. //=IME_CAND_MEANING
  2. //=IME_CAND_RADICAL
  3. //=IME_CAND_STROKES

DWORD

dwCount; //

当前列表个数

DWORD

dwSelection; //

当前选择的列表序号

DWORD

dwPageStart; //

在列表窗口中所显示的列表的起始序号(上下翻页时

用)

DWORD

dwPageSize; //

一页显示的列表个数

DWORD

dwOffset[]; //

列表数据存放区地址:

[

];[

]

。。。。

  1. } CANDIDATELIST;
  2. 6

COMPOSITIONFORM

  1. typedef tagCOMPOSITIONFORM { //

窗口位置、大小信息:

  1. } RECONVERTSTRING;
  2. 11

IMEMENUITEMINFO

  1. typedef _tagIMEMENUITEMINFO { //

输入法菜单结构,

W98/2000

UINT

cbSize;

UINT

fType;

UINT

fState;

UINT

wID;

HBITMAP

hbmpChecked;

HBITMAP

hbmpUnchecked;

DWORD

dwItemData;

TCHAR

szString[48];

HBITMAP

hbmpItem;

  1. }
  2. 12

INPUTCONTEXT

  1. The INPUTCONTEXT structure is an internal data structure that stores Input
  2. Context data.
  3. typedef struct tagINPUTCONTEXT { //IMC

数据存放区

HWND

hWnd; //

使用该

IMC

的窗口

BOOL

fOpen; //IME

的打开与关闭状态

  1. POINT ptStatusWndPos; //

状态窗口的位置

  1. POINT ptSoftKbdPos; //

软键盘的位置

DWORD

fdwConversion; //IME

状态

(

活动、不活动,全角等)

DWORD

fdwSentence; //

编码方式

  1. union {
  2. LOGFONTA A;
  3. LOGFONTW W;
  4. } lfFont; //

字体

  1. COMPOSITIONFORM cfCompForm; //

编码格式结构

  1. CANDIDATEFORM cfCandForm[4]; //

列表选择结构

  1. HIMCC hCompStr; //
  2. HIMCC hCandInfo;
  3. HIMCC hGuideLine
  4. HIMCC hPrivate;

DWORD

dwNumMsgBuf; //

存放在

hMsgBuf

中的消息数

  1. HIMCC hMsgBuf; //

存放的消息,格式:

[

消息

1] [wParam1] [lParam1] {[

] [wParam2] [lParam2]…

  1. //

注意

:

我们输入的汉字串存放在这里

DWORD

fdwInit //

系统根据此值来初始本结构相应的信息

  1. //=INIT_STATUSWNDPOS

初始化

ptStatusWndPos

  1. //=INIT_CONVERSION

初始化

fdwConversion

  1. //=INIT_SENTENCE

初始化

fdwSentence

  1. //=INIT_LOGFONT

初始化

lfFont

  1. //=INIT_COMPFORM

初始化

cfCompForm

  1. //=INIT_SOFTKBDPOS

初始化

ptSoftKbdPos

DWORD

dwReserve[3]; //

将来版本扩展的信息

  1. } INPUTCONTEXT;

UI

窗口下需要处理下列

windows

消息

.

1

WM_IME_SETCONTEXT

激活或休眠输入法

LRESULT CALLBACK UIWndProc(HWND hUIWnd,UINT uMsg,WPARAM

wParam,LPARAM lParam)

{

case WM_IME_SETCONTEXT:

fSet= (BOOL) wParam;

lISCBits = lParam;

}

如果

fSet

TRUE,

系统将激活当前输入法的某个窗口

(

状态窗、列表窗等),为

FALSE

休眠当前输入法

.

其中

lISCBits

中指出对哪个窗口操作。

数值

含义

ISC_SHOWUICOMPOSITIONWINDOW

显示编码窗口

ISC_SHOWUIGUIDWINDOW

显示信息窗口

ISC_SHOWUICANDIDATEWINDOW

显示

0

号列表窗口

(ISC_SHOWUICANDIDATEWINDOW ? 1)

显示

1

号列表窗口

.

(ISC_SHOWUICANDIDATEWINDOW ? 2)

显示

2

号列表窗口

.

(ISC_SHOWUICANDIDATEWINDOW ? 3)

显示

3

号列表窗口

.

2

WM_IME_CONTROL

管理当前输入法

wSubMessage= wParam;

WM_IME_CONTROL

控制的消息

lpData = (LPVOID) lParam;

对应的数据

其中子消息有下列消息:

1

IMC_GETCANDIDATEPOS

获取列表窗口的位置

.

此时

lParam

传送的是

CANDIDATEFORM

结构地址。

如果此消息成功返回

0

,否则非零。

通常如果你设计此部分了,返回

0

。否则返回

1

2

IMC_GETCOMPOSITONFONT

获取编码窗口字体结构,

lParam

LOGFONT

结构地址

如果此消息成功返回

0

,否则非零。

通常如果你设计此部分了,返回

0

。否则返回

1

3

IMC_GETCOMPOSITONWINDOW

获取编码窗口位置,

lParam

COMPOSITIONFORM

结构地址。

如果此消息成功返回

0

,否则非零。

通常如果你设计此部分了,返回

0

。否则返回

1

4

IMC_GETSOFTKBDFONT

获取软键盘字体。

lParam

字体结构

LOGFONT

地址。

5

IMC_GETSOFTKBDPOS

获取软键盘位置,

lParam = 0;

返回软键盘在屏幕窗口中的坐标结构

POINTS

6

IMC_GETSOFTKBDSUBTYPE

wSubMessage= IMC_GETSOFTKBDSUBTYPE;

注意:

UI

窗口不接受此消息,它的管理函数是

NotifyIME

11

IMC_SETSOFTKBDDATA

设置软键盘数据,此时

lParam

传送的是

SOFTKBDDATA

结构地址,用户设定自己的软

键盘字符。

wSubMessage= IMC_SETSOFTKBDDATA;

lpSoftKbdData= (LPSOFTKBDDATA) lParam;

如果此消息成功返回

0

,否则非零。

注意:

UI

窗口不接受此消息,它的管理函数是

NotifyIME

12

IMC_SETSOFTKBDSUBTYPE

设置软键盘类型

wSubMessage= IMC_SETSOFTKBDSUBTYPE;

lSubType= lParam;

成功返回

subtype

,否则返回

-1.

注意:

UI

窗口不接受此消息,它的管理函数是

NotifyIME

13

IMC_SETSOFTKBDFONT

设置软键盘字体,此时

lParam

传送的是

LOGFONT

结构地址

wSubMessage= IMC_SETSOFTKBDFONT;

lpLogFont= (LPLOGFONT)lParam;

如果此消息成功返回

0

,否则非零。

注意:

UI

窗口不接受此消息,它的管理函数是

NotifyIME

14

IMC_SETSOFTKBDPOS

设置软件位置,此时

lParam

传送的是

POINTS

结构

wSubMessage= IMC_SETSOFTKBDPOS;

ptsPt= (POINTS)lParam;

如果此消息成功返回

0

,否则非零。

15

IMC_SETSTATUSWINDOWPOS

设置状态窗口位置,此时

lParam

传送的是

POINTS

结构

wSubMessage= IMC_SETSTATUSWINDOWPOS;

ptsPt= (POINTS)lParam;

如果此消息成功返回

0

,否则非零。

3

WM_IME_COMPOSITION

当用户改变了编码状态时,发送此消息

WM_IME_COMPOSITION

应用程序可以通过调用

ImmGetCompositionString

获取新的编码状态。

wChar= wParam;

最后输入到编码窗口的

2

字节的

DBCS

字符

lAttribute= lParam;

当前编码的含义。

lAttribute

可取下列值得组合:

含义

GCR_ERRORSTR

修正错误

GCR_INFORMATIONSTR

修正信息串

GCS_COMPATTR

修正编码串属性

.

GCS_COMPCLAUSE

修正编码信息

.

GCS_COMPREADATTR

修正读入串的属性

GCS_COMPREADCLAUSE

修正读入串的属性

.

GCS_COMPREADSTR

修正读入串。

GCS_COMPSTR

修正当前的编码

GCS_CURSORPOS

修正当前编码的光标位置

.

GCS_DELTASTART

修正当前编码的开始位置

GCS_RESULTCLAUSE

修正结果串的信息

.

GCS_RESULTREADCLAUSE

修正读入串的信息

.

GCS_RESULTREADSTR

修正读入串

.

GCS_RESULTSTR

修正编码结果串

.

CS_INSERTCHAR

在当前位置插入一个字符

CS_NOMOVECARET

替换结果串

4

WM_IME_COMPOSITIONFULL

用户接口窗口不能增加编码窗口的尺寸时,

ime

用户接口窗口将发送

WM_IME_COMPOSITIONFULL

消息,可不处理。

wParam = 0

lParam= 0

5

WM_IME_ENDCOMPOSITION

当编码结束时

ime

发送此消息

WM_IME_ENDCOMPOSITION

wParam = 0

lParam= 0

用户程序可以接受此消息,以便自己显示用户输入的编码。

6

WM_IME_SELECT

系统发出

WM_IME_SELECT

以便选择一个新的

ime

fSelect= (BOOL)wParam; TRUE

表示新的

IME

已选择,

FALSE

表示不被选择或关闭该输

入法。

hKL= lParam;

系统利用这个消息产生或关闭老的输入法用户窗口。

7

WM_IME_STARTCOMPOSITION

当用户开始输入编码时,系统立即发送该消息到

IME

中,

IME

打开编码窗口。

wParam = 0

lParam= 0

8

WM_IME_NOTIFY

IME

消息组:

wSubMessage= wParam;

lParam= lParam;

各消息说明:

1

IMN_CLOSESTATUSWINDOW

关闭状态窗口时,系统发送

IMN_CLOSESTATUSWINDOW

消息。

wSubMessage = IMN_CLOSESTATUSWINDOW;

lParam= 0;

当用户接口窗口接收到此消息时,将关闭状态窗口。

2

IMN_OPENSTATUSWINDOW

产生或打开状态窗口

wSubMessage = IMN_OPENSTATUSWINDOW;

lParam= 0;

ime

接收到此消息时

,

将产生状态窗口

.

有关状态串口的信息可用

ImmGetConversionStatus

获取

,

设置状态窗口的信息可用

ImmSetConversionStatus.

3

IMN_OPENCANDIDATE

打开或产生列表选择窗口

wSubMessage = IMN_OPENCANDIDATE;

lCandidateList= lParam;

4

IMN_CHANGECANDIDATE

更新当前的列表选择窗口

WM_IME_NOTIFY

wSubMessage = IMN_CHANGECANDIDATE;

lCandidateList= lParam;

5

IMN_CLOSECANDIDATE

关闭选择窗口

wSubMessage = IMN_CLOSECANDIDATE;

lCandidateList= lParam;

UI

窗口接收此消息后

,

将销毁列表选择窗口

IMN_SETCONVERSIONMODE

改变输入法状态模式管理

wSubMessage = IMN_SETCONVERSIONMODE;

lParam= 0;

IMN_SETOPENSTATUS

设置输入法状态

wSubMessage = IMN_SETOPENSTATUS;

lParam= 0;

IMN_SETCANDIDATEPOS

设置列表窗口位置

wSubMessage = IMN_SETCANDIDATEPOS;

lCandidateList= lParam;

Parameters

IMN_SETCOMPOSITIONFONT

设置编码窗口字体

wSubMessage = IMN_SETCOMPOSITIONFONT;

lParam= 0;

IMN_SETCOMPOSITIONWINDOW

设置编码窗口

wSubMessage = IMN_SETCOMPOSITIONWINDOW;

lParam= 0;

IMN_GUIDELINE

错误信息处理

wSubMessage = IMN_GUIDELINE;

lParam= 0;

IMN_SOFTKBDDESTROYED

关闭软键盘

wSubMessage = IMN_SOFTKBDDESTROYED;

lParam= 0;

自由拼音输入法的测试

李振春先生写的自由拼音可以从下面的网址下载:

项目主页

http://gforge.osdn.net.cn/projects/freepyce

可以用:

svn checkout http://gforge.osdn.net.cn/svn/freepyce

获得最新的源码。

编程源代码后,生成

DLL

文件:

freepy.dll

。复制它和

library

目录的

freepy.tab

freepysys.dic

文件到

CE

设备的

windows

目录。

最好的做法,是通过

PB

将上述的三个文件集成到

CE

映像文件中,同时修改注册表。这

样将不再加载微软输入法,而加载自由拼音输入法。

ActiveSync

连接

CE

设备,用

Remote Register Editor

连接系统嵌入式板的注册表:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Layouts\e0010804

修改,

Ime File

键值从

msimepy.dll

改为

freepy.dll

CE

设备上打开

Microsoft WordPad

程序,然后选择输入法。对自由拼音进行测试

!

注:不能使用

CE

设备上已经运行的程序,如

explorer

,或给桌面文件改名来测试。由于

系统本来的微软输入法仍然存在,它们还在调用的微软输入法。

输入法程序

[ime]

的调试方法

以自由拼音

(freepy3.1)

为例

第一步:

安装

freepy3.1

第二步:

a)

如果是

VC6.0

打开

freepy3.1

工程,打开

vc

主菜单的

Project/settings

Link

属性页

下的

output file name

输入

c:\winnt\system32\freepy.ime,

这是

win2000,

如果是

xp

则可能是

c:\windows\system32\freepy.ime

;还要在

Debug

属性页下的

Executable for

debug seesion

下输入

c:\windows\system32\notepad.exe

b)

如果是

VS.NET

打开

freepy3.1

工程,项目

->freepy3.1

属性,进入链接器页,设置输入

文件为

c:\windows\system32\freepy.ime

,然后进入调试页,将命令设置为:

c:\windows\system32\notepad.exe

。根据操作系统不同可能有别,请做相应修改!

第三步:

设置断点,然后按

F5

,进行调试,这时候打开任务栏右下脚输入法里的自由拼音输入法就

可以了。

完成以上几步,就可以在记事本里输入汉字,然后跟踪输入法代码,从中理解各个函数之

间的相互调用顺序!

输入法

(IME)

实现原理

一、实现原理

1.

中文输入法的组成

微软

Windows

系统中输入法由程序(

DLL

)名称为:

*.ime

文件和码表文件(字典)

名称为

*.mb

文件组成。

2.

中文输入法的界面

http://wjy.hanwenhua.com/images/Projec6.gif

3.

Windows

任务栏

“EN

图标

中增加输入法名称

这也就是

Setup

程序的关键,实际上,可以利用

Win32Api

函数

ImmInstallIME()

该函数的原形是:

HKL ImmInstallIME( LPCTSTR lpszIMEFileName, LPCTSTR lpszLayoutText);

前一个参数

lpszIMEFileName

“.ime”

文件的路径,

Win9x

“\System”

下,

WinNT/2000

“\System32”

下。后一个参数

lpszLayoutText

是输入法的明称。如

HKL

MyIme=ImmInstallIME(“Windows\system\3jaja.ime”,“3++

输入法

“);

如果

MyIme

不返回

NULL

,则调用成功。

4.“.ime”

文件的实现

程序中的输出函数(必须)即文件

“.def”

中的函数,以下为函数的名称和原形,部分函数给

出了原函数,

希望对你能有所帮助。

Cpp

代码

  1. //

初始化输入法函数

BOOL

WINAPI ImeInquire(LPIMEINFO lpImeInfo,

LPTSTR

lpszWndCls,

DWORD

lpszOptions)

{

  1. if (!lpImeInfo)
  2. return (FALSE);
  3. lpImeInfo->dwPrivateDataSize = sizeof(PRIVCONTEXT);
  4. lpImeInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST | IME_PROP_CAN

DLIST_START_FROM_1 | IME_PROP_IGNORE_UPKEYS;

  1. lpImeInfo->fdwConversionCaps = IME_CMODE_NATIVE|IME_CMODE_NATI

VE|IME_CMODE_FULLSHAPE|IME_CMODE_CHARCODE | IME_CMODE_SOF

TKBD | IME_CMODE_NOCONVERSION;

  1. lpImeInfo->fdwSentenceCaps = 0;
  2. lpImeInfo->fdwUICaps = UI_CAP_ROT90 | UI_CAP_SOFTKBD;
  3. lpImeInfo->fdwSCSCaps = SCS_CAP_COMPSTR | SCS_CAP_MAKEREAD;
  4. lpImeInfo->fdwSelectCaps = (

DWORD

)0;

  1. lstrcpy(lpszWndCls, (

LPTSTR

)szUIClassName);

  1. return (TRUE);
  2. }
  3. //

自定义汉字编码格式,未作处理。

DWORD

WINAPI ImeConversionList(HIMC hIMC,

LPCTSTR

lpszSrc,

DWORD

uB

ufLen,

UINT

uFlag)

  1. {
  2. return (0);
  3. }
  4. //

设置输入法状态函数,如光标跟随等

BOOL

WINAPI ImeConfigure(

HKL

hKL,

HWND

hAppWnd,

DWORD

dwMode,

LPV

OID

lpData)

  1. {
  2. switch (dwMode)
  3. {
  4. case IME_CONFIG_GENERAL:
  5. DialogBox(hInst, MAKEINTRESOURCE(SETIME), (

HWND

)hAppWnd, (DLG

PROC)ImeSetDlgProc);

  1. break;
  2. default:
  3. return (FALSE);
  4. break;
  5. }
  6. return (TRUE);
  7. }
  8. //

退出

BOOL

WINAPI ImeDestroy(

UINT

uReserved)

  1. {
  2. if (uReserved)
  3. return (FALSE);
  4. return (TRUE);
  5. }
  6. //

应用接口函数

LRESULT

WINAPI ImeEscape(HIMC hIMC,

UINT

uSubFunc,

LPVOID

lpData)

  1. {

LRESULT

lRet;

  1. switch (uSubFunc)
  2. {
  3. case IME_ESC_QUERY_SUPPORT:
  4. if ( lpData == NULL )
  5. return FALSE;
  6. switch (*(LPUINT)lpData)
  7. {
  8. case IME_ESC_QUERY_SUPPORT:
  9. case IME_ESC_MAX_KEY:
  10. case IME_ESC_IME_NAME:
  11. case IME_ESC_GETHELPFILENAME:
  12. return (TRUE);
  13. case IME_ESC_SEQUENCE_TO_INTERNAL:
  14. case IME_ESC_GET_EUDC_DICTIONARY:
  15. case IME_ESC_SET_EUDC_DICTIONARY:
  16. case IME_INPUTKEYTOSEQUENCE:
  17. return (FALSE);
  18. default:
  19. return (FALSE);
  20. }
  21. break;
  22. case IME_ESC_SEQUENCE_TO_INTERNAL:
  23. case IME_ESC_GET_EUDC_DICTIONARY:
  24. case IME_ESC_SET_EUDC_DICTIONARY:
  25. case IME_INPUTKEYTOSEQUENCE:
  26. return (FALSE);
  27. case IME_ESC_MAX_KEY:
  28. return ((

WORD

) 4);

  1. case IME_ESC_GETHELPFILENAME:
  2. {

TCHAR

szIMEGUDHlpName[MAXSTRLEN];

  1. if (lpData == NULL )
  2. return FALSE;
  3. szIMEGUDHlpName[0] = 0;
  4. GetWindowsDirectory((

LPTSTR

)szIMEGUDHlpName, MAXSTRLEN);

  1. lstrcat((

LPTSTR

)szIMEGUDHlpName, TEXT(“file://HELP//3JaJa.hlp”));

  1. lstrcpy((

char

*)lpData, (

char

*)szIMEGUDHlpName);

  1. return TRUE;
  2. }
  3. default:
  4. return (FALSE);
  5. }
  6. return (lRet);
  7. }
  8. //

启动输入法设置功能

BOOL

WINAPI ImeSelect(HIMC hIMC,

BOOL

fSelect

  1. {
  2. LPINPUTCONTEXT lpIMC;

BOOL

fRet;
  1. if (!hIMC)
  2. return (FALSE);
  3. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  4. if (!lpIMC)
  5. return (FALSE);
  6. fRet = Select(hIMC, lpIMC, fSelect);
  7. ImmUnlockIMC(hIMC);
  8. return (fRet);
  9. }
  10. //

设置输入活动状态

BOOL

WINAPI ImeSetActiveContext(HIMC hIMC,

BOOL

fOn)

  1. {
  2. if (fOn&&hIMC)
  3. {
  4. LPINPUTCONTEXT lpIMC;
  5. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  6. if (!lpIMC)
  7. return (FALSE);
  8. InitContext(lpIMC);
  9. ImmUnlockIMC(hIMC);
  10. }
  11. return (TRUE);
  12. }
  13. //

用户按键处理函数,例如中英文状态,返回

FALSE

为英文状态,按键不作处

理。

BOOL

WINAPI ImeProcessKey(HIMC hIMC,

UINT

uVirtKey,

LPARAM

lParam,C

ONST

LPBYTE

lpbKeyState);

  1. //

输入法编码字符处理。

BOOL

WINAPI ImeSetCompositionString(HIMC hIMC,

DWORD

dwIndex,

LPVOI

D

lpComp,

DWORD

dwCompLen,

LPVOID

lpRead,

DWORD

dwReadLen);

  1. //

将用户按键转换为汉字编码

UINT

WINAPI ImeToAsciiEx(

UINT

uVirtKey,

UINT

uScanCode,CONST

LPBYTE

lpbKeyState,LPTRANSMSGLIST lpTransBuf,

UINT

fuState,HIMC hIMC)

  1. //

处理

IME

消息函数

BOOL

WINAPI NotifyIME(HIMC hIMC,

DWORD

dwAction,

DWORD

dwIndex,

DW

ORD

dwValue);

  1. //

自定义汉字编码格式,未作处理。

BOOL

WINAPI ImeRegisterWord(

LPCTSTR

lpszReading,

DWORD

dwStyle,

LP

CTSTR

lpszString)

  1. {
  2. return (FALSE);
  3. }
  4. //

自定义汉字编码格式,未作处理。

BOOL

WINAPI ImeUnregisterWord(

LPCTSTR

lpszReading,

DWORD

dwStyle,

L

PCTSTR

lpszString)

  1. {
  2. return (FALSE);
  3. }
  4. //

自定义汉字编码格式,未作处理。

UINT

WINAPI ImeGetRegisterWordStyle(

UINT

nItem,LPSTYLEBUF lpStyleBuf)

  1. {
  2. return (FALSE);
  3. }
  4. //

自定义汉字编码格式,未作处理。

UINT

WINAPI ImeEnumRegisterWord(REGISTERWORDENUMPROC lpfnRegi

sterWordEnumProc,

LPCTSTR

lpszReading,

DWORD

dwStyle,

LPCTSTR

lpszStr

ing,

LPVOID

lpData)

  1. {
  2. return (FALSE);
  3. }
  4. //UI

窗口过程

LRESULT

CALLBACK UIWndProc(

HWND

hUIWnd,

UINT

uMsg,

WPARAM

w

Param,

LPARAM

lParam)

  1. {
  2. switch (uMsg)
  3. {
  4. case WM_CREATE:
  5. CreateUIWindow(hUIWnd);
  6. break;
  7. case WM_DESTROY:
  8. DestroyUIWindow(hUIWnd);
  9. break;
  10. case WM_IME_STARTCOMPOSITION:
  11. ......
  12. }
  13. }
  14. //

状态窗口过程

LRESULT

CALLBACK StatusWndProc(

HWND

hStatusWnd,

UINT

uMsg,

WPAR

AM

wParam,

LPARAM

lParam);

  1. //

编码窗口过程

LRESULT

CALLBACK CompWndProc(

HWND

hCompWnd,

UINT

uMsg,

WPAR

AM

wParam,

LPARAM

lParam);

  1. //

侯选汉字窗口过程

LRESULT

CALLBACK CandWndProc(

HWND

hCandWnd,

UINT

uMsg,

WPARA

M

wParam,

LPARAM

lParam);

5.

头文件及链接文件

记得要定义

IMM32.h

及链接文件

IMM32.lib

。至于有关

“ .ime”

程序中必须用到的结构,

大家可参考

MSDN

中的有关文档。

二、常用函数

BOOL WINAPI ImmGenerateMessage( //

将汉字串法发送到与当前输入法相关联的应用软

件中

HIMC hIMC

);//

成功为

TRUE

,否则为

FALSE

LRESULT WINAPI ImmRequestMessage( //

向应用程序发送

WM_IME_REQUEST

消息

HIMC hIMC, //

与当前输入法相关联的应用软件的句柄

WPARAM wParam, //

WM_IME_REQUEST

相关的

wP

LPARAM lParam //

WM_IME_REQUEST

相关的

LP

);

LPINPUTCONTEXT WINAPI ImmLockIMC( //

获取当前

IMC

INPUTCONTEXT

结构信

息,增加

IMC

计数器

HIMC hIMC

);//

成功返回

INPUTCONTEXT

结构指针,否则为

NULL

BOOL WINAPI ImmUnlockIMC( //

释放

IMC

计数器

HIMC hIMC );//

返回

:

如果

IMC

计数器被减少到

0

,

返回

FALSE,

否则为

TRUE.

注意

:ImmLockIMC

ImmUnlockIMC

必须成对出现

,

必须是相同的

HIMC

HIMCC WINAPI ImmGetIMCLockCount( //

取计数器值

HIMC hIMC );//

如果成功返回

HIMC

的计数器值,否则为

NULL.

HIMCC WINAPI ImmCreateIMCC( //

创建

INPUTCONTEXT

结构的一个成员

DWORD dwSize //

成员的缓冲区长度

);//

如果成功返回

IMC

的成员句柄,否则为

NULL

HIMCC WINAPI ImmDestroyIMCC( //

删除

IMC

成员缓冲区

HIMCC hIMCC

);//

如果成功返回

NULL

,否则等于该

HIMCC.

LPVOID WINAPI ImmLockIMCC( //

IMCC

缓冲地址,同时使

IMCC

的计数器值增加

HIMCC hIMCC );

BOOL WINAPI ImmUnlockIMCC( //

递减

IMCC

计数器

HIMCC hIMCC );//

如果

IMCC

的计数器值为零,则返回

FALSE

,否则为

TRUE.

10

HIMCC WINAPI ImmReSizeIMCC( //

重新设置

IMC

的成员的缓冲区大小

HIMCC hIMCC, //IMC

的成员句柄

DWORD dwSize //

新缓冲区大小

);//

如果成功,返回新的

HIMCC

,否则为

NULL.

DWORD WINAPI ImmGetIMCCSize( //

IMC

成员的缓冲区大小

HIMCC hIMCC );//

返回

IMC

成员的缓冲区大小

12

DWORD WINAPI ImmGetIMCCLockCount( //

返回

IMC

计数器值

HIMCC hIMCC

);//

成功返回该

IMCC

的计数器值,否则为

0

BOOL WINAPI ImmGetHotKey( //

取输入法状态键,该函数供控制面板使用

DWORD dwHotKeyID,

LPUINT lpuModifiers,

LPUINT lpuVKey,

LPHKL lphKL

)

BOOL WINAPI ImmSetHotKey( //

设置输入法的热键

DWORD dwHotKeyID,

UINT uModifiers,

UINT uVKey,

hKL hKL

)

HWND WINAPI ImmCreateSoftKeyboard( //

产生一个软键盘

UINT uType, //

软件盘上的键码含义的定义方式

UINT hOwner, //

该输入法的

UI

窗口

int x, //x

坐标

int y //y

坐标

);//

成功返回软键盘的窗口句柄

BOOL WINAPI ImmDestroySoftKeyboard( //

销毁软键盘

HWND hSoftKbdWnd //

软键盘窗口句柄

);//

成功为

TRUE,

法哦则为

FALSE.

17

BOOL WINAPI ImmShowSoftKeyboard( //

显示或隐藏软键盘

HWND hSoftKbdWnd, //

软键盘窗口句柄

int nCmdShow //SW_HIDE=

隐藏,

SW_SHOWNOACTIVATE=

显示

);//

如构成功返回

TRUE.

否则为

FALSE.

二、

IME

文件中的常用结构

1

IMEINFOstruct tagIMEInfo { //

输入法的接口信息

DWORD dwPrivateDataSize;//

用户设计的数据结构的字节数

DWORD fdwProperty; //

输入法对键盘事件的相应特性

DWORD fdwConversionCaps;//

当前输入法具有的功能特性

,

如有软键盘、标点、中西文切

换等功能

DWORD fdwSentenceCaps;

DWORD fdwUICaps; //

用户界面能力:支持软键盘等

DWORD fdwSCSCaps; //

用户设置编码串的能力

DWORD fdwSelectCaps; //

输入法切换时是否使用以前输入法的模式

} IIMEINFO;

2

COMPOSITIONSTR

用于编码管理

typedef struct tagCOMPOSITIONSTR {

DWORD dwSize; //

当前编码信息需要的存储空间

DWORD dwCompReadAttrLen;

//

读入的编码属性长度

DWORD dwCompReadAttrOffset; //

读入的编码的位置

DWORD dwCompReadClsLen;

//

读入的子串长度

DWORD dwCompReadClsOffset; //

读入的子串的位置

DWORD dwCompReadStrLen;

//

读入的编码长度

DWORD dwCompReadStrOffset; //

读入的编码的位置

DWORD dwCompAttrLen; //

编码属性长度

DWORD dwCompAttrOffset; //

编码属性在内存的位置

DWORD dwCompClsLen; //

编码子串长度

DWORD dwCompClsOffset; //

编码子串在内存的位置

DWORD dwCompStrLen; //

编码串长度

DWORD dwCompStrOffset; //

编码串在内存的位置

DWORD dwCursorPos; //

当前光标位置

DWORD dwDeltaStart; //

被修改编码的位置

DWORD dwResultReadClsLen; //

读入结果子串长度

DWORD dwResultReadClsOffset; //

读入结果子串在内存的位置

DWORD dwResultReadStrLen; //

读入的编码长度

DWORD dwResultReadStrOffset;

//

读入的编码在内存的位置

DWORD dwResultClsLen; //

结果子串长度

DWORD dwResultClsOffset; //

结果子串在内存的位置

DWORD dwResultStrLen; //

结果串长度

DWORD dwResultStrOffset; //

结果串在内存的位置

DWORD dwPrivateSize; //

用户自定义数据长度

DWORD dwPrivateOffset; //

用户自定义数据在内存的位置

} COMPOSITIONSTR;

3

CANDIDATEINFO

用于编码选择管理

typedef struct tagCANDIDATEINFO {

DWORD dwSize; //

数据所占内存大小

DWORD dwCount; //

数据个数

DWORD dwOffset[32]; //

各个编码列表的内存位置

DWORD dwPrivateSize; //

自定义数据尺寸

DWORD dwPrivateOffset; //

缓冲区位置

} CANDIDATEINFO;

4

GUIDELINE

typedef struct tagGUIDELINE {

DWORD dwSize;

DWORD dwLevel;

DWORD dwIndex;

DWORD dwStrLen;

DWORD dwStrOffset;

DWORD dwPrivateSize;

DWORD dwPrivateOffset;

} GUIDELINE;

5

CANDIDATELIST

编码选择列表信息

typedef struct tagCANDIDATELIST {

DWORD dwSize; //

用字节表示的内存大小

DWORD dwStyle; //

列表串的取值方式

DWORD dwCount; //

当前列表个数

DWORD dwSelection; //

当前选择的列表序号

DWORD dwPageStart; //

在列表窗口中所显示的列表的起始序号

DWORD dwPageSize; //

一页显示的列表个数

DWORD dwOffset[]; //

列表数据存放区地址

} CANDIDATELIST;

6

COMPOSITIONFORM

窗口位置、大小信息:

typedef tagCOMPOSITIONFORM {

DWORD dwStyle; //

管理窗口方式

POINT ptCurrentPos; //

给定坐标

RECT rcArea;

}COMPOSITIONFORM;

7

CANDIDATEFORM

列表窗口信息

typedef tagCANDIDATEFORM {

DWORD dwIndex; //

列表窗口序号

DWORD dwStyle; //

属性:

POINT ptCurrentPos; //

坐标位置

REC rcArea;

} CANDIDATEFORM;

12

INPUTCONTEXT IMC

数据存放区

typedef struct tagINPUTCONTEXT {

HWND hWnd; //

使用该

IMC

的窗口

BOOL fOpen; //IME

的打开与关闭状态

POINT ptStatusWndPos; //

状态窗口的位置

POINT ptSoftKbdPos; //

软键盘的位置

DWORD fdwConversion; //IME

状态

(

活动、不活动,全角等)

DWORD fdwSentence; //

编码方式

union {
代码编译完毕

时间: 2024-10-07 02:12:07

vc编程的ime输入法菜单开发的相关文章

积累的VC编程小技巧之标题栏和菜单

1.窗口最大最小化按纽的控制 ①怎样在程序开始的时候让它最大化? ②vc++做出来的exe文件在窗体的右上方是没有最大化和最小化按钮的,怎样实现这一功能? ③如何在显示窗口时,使最大化按钮变灰?   ①在App类里的C-App::InitInstance()中把m_pMainWnd->ShowWindow(SW_SHOW)改成m_pMainWnd->ShowWindow(SW_MAXIMIZE); ②在CreateWidnow时用WS_SYSMENU|WS_MINIMIZEBOX|WS_MAX

VC++编程之道读书笔记

第二篇 缪误21:位图数据是按照红绿蓝顺序存储的 大家都知道位图的颜色是由红.绿.蓝三个分量构成的,但是位图颜色数据存储的方式则不是按照这个顺序存储的,而是按照蓝.绿.红的顺序存储的.并且对于真彩色位图来说,位图的颜色数据是倒序存储的,即位图的第一行数据位于位图数据的最底部. 第三篇 细节12 :内存中的数组 在C++中通过数组可以操作内存,创建数组时需要为数组分配内存空间,操作数组时就是对内存空间中的数组元素进行操作.数组创建后,数组引用和数组元素分别存储在栈内存和堆内存中,并通过数组引用与数

Android界面编程——导航栏及菜单(六)

Android界面编程--导航栏及菜单 2.7导航栏及菜单 2.7.1  ActionBar ActionBar是Android3.0(API 11)开始增加的新特性,ActionBar出现在活动窗口的顶部,可以显示标题.icon.Actions按钮.可交互View,可实现应用程序级的导航,如图2.7-1所示 图2.7-1 其中 1. App icon: 主要用于展示App的Logo,如果当前界面不是一级界面,还可以展示返回航. 2.View Control: 用于切换不同的视图或者展示非交互信

用VC++打造有多语言菜单的应用程序[转]

随着计算机技术的快速发展,软件的交流越来越频繁,软件的国际化已成为一个软件开发人员不可回避的一个问题.所谓软件的国际化,就是让软件界面支持多种语言,从而可以被很多国家的人使用.为了使应用程序支持多种语言,一个很好的办法就是使用动态链接库,将不同的语言资源放入不同的库中,根据需要程序加载不同的动态库,从而实现程序的国际化.但是这种方法实现起来不很方便,对软件开发人员要求较高,尤其是对于初学者,难度较大.为了解决这个问题,以实现多语言菜单为例,笔者介绍在VC编程中一种简单实现方法,从而实现软件的国际

VC++编程之道读书笔记(2)

第三篇 技术细节 第七章:细说开发人员必知必会的39个开发细节 细节36:单例模式的应用 在开发程序时,往往需要在整个工程中只需要一个类的实例.而这个实例一旦被创建就不能被其他的实例再创建了,通常我们称这个实现过程为单例模式. 既然要保证类只有一个实例,那么就需要其他的类不能使用实例化该类.因此,需要将其构造方法设为私有的,即使用private关键字修饰.同时,类中提供一个静态方法,该方法的返回值是该类的一个实例.这样就只能使用该静态方法来获取类的实例了,从而保证了唯一性. 下面通过具体代码来实

获取系统当前的输入法列表并通过编程方式切换输入法

1.获取输入法列表 //保存输入法信息的结构     struct _tagInputMethod     {      char szLanguageId[30];      char szLanguageName[100];      char szLanguageImeFileName[100];      HICON hIcon;     }; _tagInputMethod m_InputMethodList[30];     int m_InputMethodCount; //获取输

积累的VC编程小技巧之框架窗口及其他

1.修改主窗口风格 AppWizard生成的应用程序框架的主窗口具有缺省的窗口风格,比如在窗口标题条中自动添加文档名.窗口是叠加型的.可改变窗口大小等.要修改窗口的缺省风格,需要重载CWnd::PreCreateWindow(CREATESTRUCT& cs)函数,并在其中修改CREATESTRUCT型参数cs.CWnd::PreCreateWindow 函数先于窗口创建函数执行.如果该函数被重载,则窗口创建函数将使用CWnd::PreCreateWindow 函数返回的CREATESTRUCT

积累的VC编程小技巧之列表框

1.列表框中标题栏(Column)的添加 创建一个List Control,其ID为IDC_LIST,在其Styles属性项下的View项里选择Report.Align项里选择Top.Sort项里选择None. 然后在该List所在对话框的类(头文件)里创建ClistCtrl的一个对象m_list然后在.cpp文件的OnInitDialog()之类的函数里实现如下代码: CString strname[3]; strname[0]="Screen Name"; strname[1]=&

积累的VC编程小技巧之工具条和状态条

1.工具条和状态条中控件的添加: 方法⑴.只能在ToolBar里创建控件:首先,在ToolBar中创建一个Button,其ID为ID_TOOL_COMBO(我们要将创建的控件放在该Button的位置上). 其次,新创建一个类CMainToolBar,要从CToolBar继承(创建过程大概如下:选择工程/增加到工程/新的类:也可以选择工程的根,然后点击右键,选择新的类:或者CTL+W,选择增加类/新的类 --- 然后在class type里选择Generic Class,在Name栏里输入新类的名