漫谈WinCE输入法的编写(二)

本文详细介绍了在WinCE环境下如何实现输入法的编写过程,包括CClassFactory和CInputMethod类的具体实现细节,以及输入法界面窗口的简单实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//========================================================================
//TITLE:
// 漫谈WinCE输入法的编写(二)
//AUTHOR:
// norains
//DATE:
// Monday 11-February -2007
//Environment:
//EVC4.0 + Standard SDK
//========================================================================

在上一节中我们了解了CClassFactory和CInputMethod的基本架构功能,现在就让我们来看看具体是如何实现的吧.

首先是CClassFactory的实现:


CClassFactory::CClassFactory(
long*plDllCnt,HINSTANCEhInst)
...{
//初始化设置为1次
m_lRef=1;

//Dll的引用次数,该指针指向的是一个外部的变量
m_plDllCnt=plDllCnt;

//保存句柄
m_hInst=hInst;
}


CClassFactory::
~CClassFactory()
...{

}



//---------------------------------------------------------------------
//Description:
//Incrementobjectrefcount
//----------------------------------------------------------------------
STDMETHODIMPCClassFactory::QueryInterface(REFIIDriid,LPVOID*ppv)
...{
//返回IUnknown或IClassFactory对象

if(IsEqualIID(riid,IID_IUnknown)||IsEqualIID(riid,IID_IClassFactory))
...{
//返回指向对象的指针
*ppv=(LPVOID)this;

//增加计数,以避免返回的时候卸载该对象.
AddRef();//Incrementreftopreventdeleteonreturn.

//情况正常,成功返回
returnNOERROR;
}

*ppv=NULL;


//但接口不是调用者所需的,则失败返回.
return(E_NOINTERFACE);

}



//---------------------------------------------------------------------
//Description:
//Incrementobjectrefcount
//----------------------------------------------------------------------
STDMETHODIMP_(ULONG)CClassFactory::AddRef()
...{
ULONGcnt;

cnt
=(ULONG)InterlockedIncrement(&m_lRef);
returncnt;
}



//---------------------------------------------------------------------
//Description:
//Incrementobjectrefcount
//----------------------------------------------------------------------
STDMETHODIMP_(ULONG)CClassFactory::Release()
...{
ULONGcnt;

cnt
=(ULONG)InterlockedDecrement(&m_lRef);
if(cnt==0)
...{
delete
this;
}

returncnt;
}



//---------------------------------------------------------------------
//Description:
//CreateInstance-Calledtohaveclassfactoryobjectcreateotherobjects
//----------------------------------------------------------------------
STDMETHODIMPCClassFactory::CreateInstance(LPUNKNOWNpUnkOuter,REFIIDriid,LPVOID*ppv)
...{

//创建一个指向CInputMethod对象的指针.
CInputMethod*pInputMethod;

HRESULThr;

if(pUnkOuter)
...{
return(CLASS_E_NOAGGREGATION);
}



if(IsEqualIID(riid,IID_IUnknown)||IsEqualIID(riid,IID_IInputMethod)||IsEqualIID(riid,IID_IInputMethod2))
...{
//创建一个输入法对象
pInputMethod=newCInputMethod(m_plDllCnt,m_hInst);
if(!pInputMethod)
...{
//内存分配失败
returnE_OUTOFMEMORY;
}


//查看该输入法对象的接口是否支持是我们所需要的
hr=pInputMethod->QueryInterface(riid,ppv);


//如果不是我们所需的接口方法,那么下面这个函数将会删除刚刚创建的对象
pInputMethod->Release();

returnhr;

}



returnE_NOINTERFACE;
}


//---------------------------------------------------------------------
//Description:
//Incrementobjectrefcount
//----------------------------------------------------------------------
STDMETHODIMPCClassFactory::LockServer(BOOLfLock)
...{

if(fLock)
...{
InterlockedIncrement(m_plDllCnt);
}

else
...{
InterlockedDecrement(m_plDllCnt);
}


returnNOERROR;
}


然后我们来看看CInputMethod类的实现


CInputMethod::CInputMethod(
long*plDllCnt,HINSTANCEhInst)
...{
//获取输入法窗口的实例
m_pIMWnd=CIMWnd::GetInstance();

m_hInst
=hInst;
m_plDllCnt
=plDllCnt;

//增加一次计数
(*m_plDllCnt)++;

m_lRef
=1;//Setrefcountto1oncreate.
}


CInputMethod::
~CInputMethod()
...{
//销毁时减少一次计数
(*m_plDllCnt)--;
}



//-------------------------------------------------------------------------------------------
//Description:
//Thismethodisimplementedtocreatethewindowsandimagelistfortheinputmethod(IM).
//----------------------------------------------------------------------------------------------
HRESULTSTDMETHODCALLTYPECInputMethod::Select(HWNDhWndSip)
...{

//初始化输入法界面窗口
if(m_pIMWnd->Initialize(m_hInst,hWndSip)==FALSE)
...{

returnE_FAIL;
}


returnS_OK;
}


//-------------------------------------------------------------------------------------------
//Description:
//Thismethodisimplementedtoselecttheinputmethod(IM)outofthesoftware-based
//inputpanelwindowandtodestroytheIMwindows.
//----------------------------------------------------------------------------------------------
HRESULTSTDMETHODCALLTYPECInputMethod::Deselect()
...{
//销毁输入法界面窗口
m_pIMWnd->DestroyWindow();

returnS_OK;
}


//-------------------------------------------------------------------------------------------
//Description:
//Thismethodisimplementedtoperformanyinitializationbeforethesoftware-based
//inputpanelwindowisdisplayed
//----------------------------------------------------------------------------------------------
HRESULTSTDMETHODCALLTYPECInputMethod::Showing()
...{
//显示输入法界面窗口
m_pIMWnd->ShowWindow(TRUE);

returnS_OK;
}


//-------------------------------------------------------------------------------------------
//Description:
//Thismethodisimplementedtoperformanysavingroutinesbeforethesoftware-based
//inputpanelishidden.
//----------------------------------------------------------------------------------------------
HRESULTSTDMETHODCALLTYPECInputMethod::Hiding()
...{
//隐藏输入法界面窗口
m_pIMWnd->ShowWindow(FALSE);

returnS_OK;
}



//-------------------------------------------------------------------------------------------
//Description:
//Thismethodisimplementedtoreturninformationaboutthecurrentinput
//method(IM)totheoperatingsystem.
//----------------------------------------------------------------------------------------------
HRESULTSTDMETHODCALLTYPECInputMethod::GetInfo(IMINFO*pimi)
...{

pimi
->cbSize=sizeof(IMINFO);
pimi
->hImageNarrow=0;
pimi
->hImageWide=0;
pimi
->iNarrow=0;
pimi
->iWide=0;
pimi
->fdwFlags=SIPF_DOCKED;

pimi
->rcSipRect.left=0;
pimi
->rcSipRect.top=0;
pimi
->rcSipRect.right=SIP_WND_WIDTH;
pimi
->rcSipRect.bottom=SIP_WND_HEIGHT;
returnS_OK;
}


//-------------------------------------------------------------------------------------------
//Description:
//ThismethodisimplementedfortheIMtoreceiveinformationaboutthesize,
//placement,anddockedstatusofthesoftware-basedinputpanel.
//----------------------------------------------------------------------------------------------
HRESULTSTDMETHODCALLTYPECInputMethod::ReceiveSipInfo(SIPINFO*psi)
...{

returnS_OK;
}


//-------------------------------------------------------------------------------------------
//Description:
//ThismethodisimplementedtoreceiveapointertoanIIMCallbackinterface.
//Aninputmethod(IM)usestheIIMCallbackinterfacetosendkeystrokestoapplications
//andtochangetheiconsontheInputPanelbutton.
//----------------------------------------------------------------------------------------------
HRESULTSTDMETHODCALLTYPECInputMethod::RegisterCallback(IIMCallback*pIMCallback)
...{


//发送一条自定义消息传递回调函数的地址给输入法界面窗口
HWNDhWnd=m_pIMWnd->GetWindow();
SendMessage(hWnd,MYMSG_REGCALLBACK,(WPARAM)pIMCallback,
0);

returnS_OK;
}


//-------------------------------------------------------------------------------------------
//Description:
//Thismethodisimplementedtosenddatafromthecurrent
//inputmethod(IM)tothecurrentapplication.
//----------------------------------------------------------------------------------------------
HRESULTSTDMETHODCALLTYPECInputMethod::GetImData(DWORDdwSize,void*pvImData)
...{

returnS_OK;
}


//-------------------------------------------------------------------------------------------
//Description:
//Thismethodisimplementedtorespondtoanapplication'srequestto
//setinputmethod(IM)-specificdatawithintheIM.
//----------------------------------------------------------------------------------------------
HRESULTSTDMETHODCALLTYPECInputMethod::SetImData(DWORDdwSize,void*pvImData)
...{

returnS_OK;
}


//---------------------------------------------------------------------
//Description:
//Incrementobjectrefcount
//----------------------------------------------------------------------
STDMETHODIMPCInputMethod::QueryInterface(REFIIDriid,LPVOID*ppv)
...{

//如果当前的接口符合要求,则返回一个接口对象
if(IsEqualIID(riid,IID_IUnknown)||IsEqualIID(riid,IID_IInputMethod)||IsEqualIID(riid,IID_IInputMethod2))
...{
*ppv=(IInputMethod*)this;
AddRef();
returnNOERROR;
}

*ppv=NULL;
return(E_NOINTERFACE);

}



//---------------------------------------------------------------------
//Description:
//Incrementobjectrefcount
//----------------------------------------------------------------------
STDMETHODIMP_(ULONG)CInputMethod::AddRef()
...{

ULONGcnt;
cnt
=(ULONG)InterlockedIncrement(&m_lRef);
returncnt;
}


//---------------------------------------------------------------------
//Description:
//Incrementobjectrefcount
//----------------------------------------------------------------------
STDMETHODIMP_(ULONG)CInputMethod::Release()
...{

ULONGcnt;

cnt
=(ULONG)InterlockedDecrement(&m_lRef);
if(cnt==0)
...{
delete
this;
return0;
}

returncnt;
}



//---------------------------------------------------------------------
//Description:
//TheSIPControlPanelappletisaskingforaconfigurationdialogboxtobedisplayed.
//----------------------------------------------------------------------
HRESULTSTDMETHODCALLTYPECInputMethod::UserOptionsDlg(HWNDhwndParent)
...{
//显示设置窗口
m_pIMWnd->ShowUserOptionsDlg(hwndParent,m_hInst);
returnS_OK;
}



CInputMethod和CClassFactory的实现我们暂时就先说到这里,下一章我们将会讨论输入法界面窗口(CIMWnd)的一个简单的实现.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值