//========================================================================
//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)
...{
deletethis;
}
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)
...{
deletethis;
return0;
}
returncnt;
}

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

CInputMethod和CClassFactory的实现我们暂时就先说到这里,下一章我们将会讨论输入法界面窗口(CIMWnd)的一个简单的实现.
本文详细介绍了在WinCE环境下如何实现输入法的编写过程,包括CClassFactory和CInputMethod类的具体实现细节,以及输入法界面窗口的简单实现。
3948

被折叠的 条评论
为什么被折叠?



