漫谈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)的一个简单的实现.
posted @ 2007-02-13 09:32  我的一天  阅读(238)  评论(0编辑  收藏  举报