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

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

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

        
CClassFactory::CClassFactory(
long   * plDllCnt,HINSTANCE hInst)
{
    
//初始化设置为1次
    m_lRef = 1;     
    
    
//Dll的引用次数,该指针指向的是一个外部的变量
    m_plDllCnt = plDllCnt;
    
    
//保存句柄
    m_hInst = hInst;
}


CClassFactory::
~ CClassFactory()
{

}



// ---------------------------------------------------------------------
// Description:
//     Increment object ref count
// ----------------------------------------------------------------------
STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, LPVOID  * ppv)
{
    
//返回IUnknown或IClassFactory对象
    
    
if (IsEqualIID (riid, IID_IUnknown) || IsEqualIID (riid, IID_IClassFactory)) 
    
{   
        
//返回指向对象的指针
        *ppv = (LPVOID)this;     
        
        
//增加计数,以避免返回的时候卸载该对象.
        AddRef();                // Increment ref to prevent delete on return.

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

    
*ppv = NULL;


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

}



// ---------------------------------------------------------------------
// Description:
//     Increment object ref count
// ----------------------------------------------------------------------
STDMETHODIMP_(ULONG) CClassFactory::AddRef()
{
    ULONG cnt;
   
    cnt 
= (ULONG)InterlockedIncrement (&m_lRef);
    
return cnt;
}



// ---------------------------------------------------------------------
// Description:
//     Increment object ref count
// ----------------------------------------------------------------------
STDMETHODIMP_(ULONG) CClassFactory::Release()
{
    ULONG cnt;
   
    cnt 
= (ULONG)InterlockedDecrement (&m_lRef);
    
if (cnt == 0)
    
{
        delete 
this;
    }

    
return cnt;
}



// ---------------------------------------------------------------------
// Description:
//     CreateInstance - Called to have class factory object create other objects
// ----------------------------------------------------------------------
STDMETHODIMP CClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID  * ppv)
{
    
    
//创建一个指向CInputMethod对象的指针.
    CInputMethod *pInputMethod;
    
    HRESULT hr;
   
    
if (pUnkOuter)
    
{
        
return (CLASS_E_NOAGGREGATION);
    }

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


        
//查看该输入法对象的接口是否支持是我们所需要的
        hr = pInputMethod->QueryInterface (riid, ppv);
        
   
        
//如果不是我们所需的接口方法,那么下面这个函数将会删除刚刚创建的对象
        pInputMethod->Release ();
        
        
return hr;
                
    }
 
    

    
return E_NOINTERFACE;
}


// ---------------------------------------------------------------------
// Description:
//     Increment object ref count
// ----------------------------------------------------------------------
STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
{
    
    
if (fLock)
    
{
        InterlockedIncrement (m_plDllCnt);
    }

    
else
    
{
        InterlockedDecrement (m_plDllCnt);
    }

    
    
return NOERROR;
}


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

        
CInputMethod::CInputMethod(
long   * plDllCnt, HINSTANCE hInst)
{
    
//获取输入法窗口的实例
    m_pIMWnd = CIMWnd::GetInstance();
    
    m_hInst 
= hInst;
    m_plDllCnt 
= plDllCnt;
    
    
//增加一次计数
    (*m_plDllCnt)++;
    
    m_lRef 
= 1;     // Set ref count to 1 on create.
}


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



// -------------------------------------------------------------------------------------------
// Description:
//     This method is implemented to create the windows and image list for the input method (IM).
// ----------------------------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CInputMethod::Select(HWND hWndSip)
{
    
    
//初始化输入法界面窗口
    if(m_pIMWnd->Initialize(m_hInst,hWndSip) == FALSE)
    
{

        
return E_FAIL;
    }

    
    
return S_OK;
}


// -------------------------------------------------------------------------------------------
// Description:
//     This method is implemented to select the input method (IM) out of the software-based 
// input panel window and to destroy the IM windows. 
// ----------------------------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CInputMethod::Deselect()
{
    
//销毁输入法界面窗口
    m_pIMWnd->DestroyWindow();
    
    
return S_OK;
}


// -------------------------------------------------------------------------------------------
// Description:
//     This method is implemented to perform any initialization before the software-based 
// input panel window is displayed
// ----------------------------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CInputMethod::Showing()
{
    
//显示输入法界面窗口
    m_pIMWnd->ShowWindow(TRUE);
    
    
return S_OK;
}


// -------------------------------------------------------------------------------------------
// Description:
//     This method is implemented to perform any saving routines before the software-based 
// input panel is hidden.
// ----------------------------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CInputMethod::Hiding()
{
    
//隐藏输入法界面窗口
    m_pIMWnd->ShowWindow(FALSE);

    
return S_OK;
}



// -------------------------------------------------------------------------------------------
// Description:
//     This method is implemented to return information about the current input 
// method (IM) to the operating system.
// ----------------------------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CInputMethod::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;
    
return S_OK;
}


// -------------------------------------------------------------------------------------------
// Description:
//     This method is implemented for the IM to receive information about the size,
// placement, and docked status of the software-based input panel.
// ----------------------------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CInputMethod::ReceiveSipInfo(SIPINFO  * psi)
{
    
    
return S_OK;
}


// -------------------------------------------------------------------------------------------
// Description:
//     This method is implemented to receive a pointer to an IIMCallback interface. 
// An input method (IM) uses the IIMCallback interface to send keystrokes to applications 
// and to change the icons on the Input Panel button.
// ----------------------------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CInputMethod::RegisterCallback(IIMCallback  * pIMCallback)
{
    
    
    
//发送一条自定义消息传递回调函数的地址给输入法界面窗口
    HWND hWnd = m_pIMWnd->GetWindow();
    SendMessage(hWnd,MYMSG_REGCALLBACK,(WPARAM)pIMCallback,
0);
    
    
return S_OK;
}


// -------------------------------------------------------------------------------------------
// Description:
//     This method is implemented to send data from the current 
// input method (IM) to the current application.
// ----------------------------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CInputMethod::GetImData(DWORD dwSize,  void   * pvImData)
{

    
return S_OK;
}


// -------------------------------------------------------------------------------------------
// Description:
//     This method is implemented to respond to an application's request to 
// set input method (IM)-specific data within the IM.
// ----------------------------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CInputMethod::SetImData(DWORD dwSize,  void   * pvImData)
{

    
return S_OK;
}


// ---------------------------------------------------------------------
// Description:
//     Increment object ref count
// ----------------------------------------------------------------------
STDMETHODIMP CInputMethod::QueryInterface(REFIID riid, LPVOID  * ppv)
{

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

    
*ppv = NULL;
    
return (E_NOINTERFACE);

}



// ---------------------------------------------------------------------
// Description:
//     Increment object ref count
// ----------------------------------------------------------------------
STDMETHODIMP_(ULONG) CInputMethod::AddRef()
{
   
    ULONG cnt;   
    cnt 
= (ULONG)InterlockedIncrement (&m_lRef);
    
return cnt;
}


// ---------------------------------------------------------------------
// Description:
//     Increment object ref count
// ----------------------------------------------------------------------
STDMETHODIMP_(ULONG) CInputMethod::Release()
{

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

    
return cnt;
}



// ---------------------------------------------------------------------
// Description:
//     The SIP Control Panel applet is asking for a configuration dialog box to be displayed.
// ----------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CInputMethod::UserOptionsDlg(HWND hwndParent)
{
    
//显示设置窗口
    m_pIMWnd->ShowUserOptionsDlg(hwndParent,m_hInst);
    
return S_OK;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值