博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Mobile 输入法接口简介收藏
阅读量:3660 次
发布时间:2019-05-21

本文共 3970 字,大约阅读时间需要 13 分钟。

 

 | 

<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>

1. 概述

        Windows Mobile中的软输入面板(SIP)是一种用来支持用户自定义输入的机制。默认情况下,它主要包括标准键盘、块识别器和字母识别器。SIP作为一种 COM对象,通过IInputMethod接口来实现自定义输入。但由于其特殊性,不能像普通应用程序一样进行调试,所以在编写过程中有点复杂。

        为了代码层次分明,这里我对Mobile输入法的三个主要类:CClassFactory,CInputMethod和CIMWnd分别进行分析说明。前 面两个类分别继承于IClassFactory和IInputMethod,是能让系统正常调用输入法所必须的com接口;而CIMWnd则是输入法的窗 口,和普通的应用程序无异。

        这三个类的关系是CClassFactory通过自身的CreateInstance()函数来创建一个CInputMethod类的对象,然后CInputMethod类中会调用CIMWnd类来显示一个输入法窗口。下面我已图片的方式列出三者关系:

Mobile 输入法要用到的相关API如下:

  • Shell Reference
  • IInputMethod Interface
  • ATL
  • COM
  • Sequence of Events

2. 详细介绍

先来看看CClassFactory类的声明:

class CClassFactory : public IClassFactory
{
public:
// Ctor, Dtor
CClassFactory(REFCLSID rclsid);
virtual ~CClassFactory();
// IUnknown methods
STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj);
STDMETHOD_(ULONG,AddRef) (VOID);
STDMETHOD_(ULONG,Release) (VOID);
// IClassFactory methods
STDMETHOD(CreateInstance) (IUnknown FAR* pUnkOuter, REFIID riid,LPVOID FAR *ppunkObject);
STDMETHOD(LockServer) (BOOL fLock);
protected:
ULONG m_cRef;
CLSID m_clsid;
};

IUnknown标准接口:

QueryInterface:该函数用来查看对象支持哪种方法,这也是COM接口最先调用的函数。
AddRef:增加一次对象调用计数。
Release:减少一次对象调用计数。
IClassFactory特有的接口:
CreateInstance:系统调用该函数去创建另一个所需的实例。本文的例子中,这个函数体内创建了一个CInputMethod类的对象。
LockServer:用来标识该DLL是否被卸载。本文中,只有检测到m_plDllCnt变量为0值,也就是说该DLL已经没有被引用,此时管理器才会卸载该DLL。

下面让我们再来看看CInputMethod类:

BEGIN_INTERFACE_PART(CInputMethod, IInputMethod)
public:
// Ctor, Dtor
CInputMethod( IUnknown *pUnkOuter, HINSTANCE hInstance );
~CInputMethod();
// IInputMethod methods
STDMETHOD(Select) (HWND hwndSip);
STDMETHOD(Deselect) (void);
STDMETHOD(Showing) (void);
STDMETHOD(Hiding) (void);
STDMETHOD(GetInfo) (IMINFO *pimi);
STDMETHOD(ReceiveSipInfo) (SIPINFO *psi);
STDMETHOD(RegisterCallback) (IIMCallback *pIMCallback);
STDMETHOD(GetImData) (DWORD dwSize, void *pvImData);
STDMETHOD(SetImData) (DWORD dwSize, void *pvImData);
STDMETHOD(UserOptionsDlg) (HWND hwndParent);
private:
int m_cRef;
LPUNKNOWN m_pUnkOuter;
END_INTERFACE_PART(CInputMethod)

CInputMethod的IUnknown标准接口的作用和CClassFactory相同。

IInputMethod特有接口:
SetImData:应用程序可以通过该接口来获取输入法(IM)的信息。
GetImData:传递特定的信息给输入法。
RegisterCallback:SIP提供给输入法的回调函数接口。通过该回调函数接口,输入法可以给调用输入法的应用程序发送字符或键盘信息等等。这个是比较重要的一个函数,输入法就是通过该函数传递过来的接口函数来建立和外部的联系。
ReceiveSipInfo:SIP通过该接口传递消息给输入法。
GetInfo:SIP通过该接口来获取输入法的信息。
Hiding:隐藏输入法。
Showing:显示输入法。
Deselect:输入法即将从内存中卸载的时候将调用该接口。
Select:输入法装载到内存之前调用该接口。最明显的用户感受是在输入法管理器中选择某种输入法时,该接口即被调用。
UserOptionsDlg:控制面板通过该接口用来设置输入法的属性。

下面对输入法中用到的全局函数作一简单介绍:

static void WINAPI IM_DrawArea( HDC hdc, RECT *prcUpdate ): 用来绘制输入键盘区域
__inline static KEYENTRY* WINAPI IM_GetKeyFromCoord( RECT *prcKey ): 根据用户点击位置计算哪个键被击中,填充该键后返回键码
__inline static LRESULT WINAPI IM_OnMouseEvent( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ): 处理用户的鼠标信息
static BOOL WINAPI IM_PressKey( BOOL fPress, KEYENTRY *pKey, RECT *prcKey ): 根据标志符fPress按下按键或弹起该键。fPress为ture则按下该键,反之则弹起该键
__inline static void WINAPI IM_SetDownKeys( void ): 在开始时初始化所有按键为未按下状态,同时在用户切换到其它输入法之前确保其所有按钮为未按下状态且撤销大写状态
static void WINAPI IM_SwitchBitmap( void ): 刷新整个键盘位图
LRESULT WINAPI ImWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ): 主程序窗口过程

下面介绍下输入法dll部分:

extern “C” BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID): DLL模块进入口
STDAPI DllCanUnloadNow(void): 判定DLL是否可以被OLE卸载
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv): 返回一类工厂用来创建指定的对象
HRESULT RegisterAClsid(LPTSTR pszClsid): 添加所有用来生成CLSID所需的注册实体到一个SIP
STDAPI DllRegisterServer(void): 添加所有实体注册到系统
STDAPI DllUnregisterServer(void): 撤销所有在系统的注册实体

        输入法界面窗口和普通的应用程序的窗口没有什么不同,唯一最大的差异就是输入法窗口不能也不应该发送PostQuiteMessage,否则将导致输入法管理器的退出。至于接口的具体实现牵涉到一大堆代码,在这就不一一列出来了。

你可能感兴趣的文章
正则表达式
查看>>
Java中集合的输出方式
查看>>
数组排序的四种方法
查看>>
Java学习笔记
查看>>
JDBC技术(一)
查看>>
JDBC技术(三)——预防SQL注入攻击
查看>>
JDBC技术(五)——JDBC工具类
查看>>
JDBC(六)——JDBC读取数据表,将数据存入对象中,并将对象存储到集合中
查看>>
hibernate原理
查看>>
IDEA快捷键
查看>>
Struts2原理
查看>>
activemq总结
查看>>
jdk环境变量配置
查看>>
mybatis原理
查看>>
spring原理
查看>>
AOP
查看>>
JDK和JRE的区别
查看>>
zookeper正式集群搭建(非伪集群)
查看>>
linux定时备份mysql(可用)
查看>>
linux使用链接下载文件
查看>>