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

    技术2022-05-11  57

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

    最新回复(0)