//========================================================================
//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)的一个简单的实现.