//========================================================================
//TITLE:
// 漫谈WinCE输入法的编写(三)
//AUTHOR:
// norains
//DATE:
// Friday 2-March -2007
//Environment:
// EVC4.0 + Standard SDK
//========================================================================
这次就让我们来看看一个简单的输入法界面窗口的实现.如果以类的观点来看,输入法界面窗口和普通的应用程序的窗口没有什么不同,可能也是唯一最大的差异就是输入法窗口不能也不应该发送PostQuiteMessage,否则将导致输入法管理器的退出.
闲话不表,直接来看看一个最简单的输入法窗口架构:
//**************************************************************
//IMWnd.h
//*************************************************************
//Theinputmethodwindowclass
classCIMWnd

...{
public:
//获取对象实例
staticCIMWnd*GetInstance();
//显示输入法的设置窗口
voidShowUserOptionsDlg(HWNDhWndParent,HINSTANCEhInst=NULL);
//显示输入法界面
voidShowWindow(BOOLbShow);
//销毁输入法界面
voidDestroyWindow();
//初始化窗口,hWndSip是输入法管理器的句柄
BOOLInitialize(HINSTANCEhInst,HWNDhWndSip);
//析构函数
virtual~CIMWnd();

protected:
//构造函数
CIMWnd();
//注册回调函数
voidOnRegCallback(HWNDhWnd,UINTwMsg,WPARAMwParam,LPARAMlParam);
//窗口过程
staticLRESULTWndProc(HWNDhWnd,UINTwMsg,WPARAMwParam,LPARAMlParam);
//指向对象的指针
staticCIMWnd*m_pInstance;
//输入法窗口句柄
HWNDm_hWnd;
//DLL实例
HINSTANCEm_hInst;
//输入法管理器窗口句柄
HWNDm_hWndSip;
//保存对外回调函数的指针
IIMCallback*m_pIMCallback;//Pointertothecallbackfunction


};
//**************************************************************
//IMWnd.cpp
//*************************************************************

//Initialize
CIMWnd*CIMWnd::m_pInstance=NULL;

//----------------------------------------------------------------------
//Description:
//Gettheobjectinstance
//----------------------------------------------------------------------
CIMWnd*CIMWnd::GetInstance()

...{
if(m_pInstance==NULL)

...{
m_pInstance=newCIMWnd();
}
returnm_pInstance;
}


//----------------------------------------------------------------------------
//Decription:
//OnmessageMSG_USEROPTIONSDLG
//-----------------------------------------------------------------------------
voidCIMWnd::ShowUserOptionsDlg(HWNDhWndParent,HINSTANCEhInst)

...{

CSettingDlg*pSettingDlg;
pSettingDlg=CSettingDlg::GetInstance();

if(hInst==NULL)

...{
pSettingDlg->ShowDlg(m_hInst,hWndParent,&m_iTimeFresh);
}
else

...{
pSettingDlg->ShowDlg(hInst,hWndParent,&m_iTimeFresh);
}

}


//----------------------------------------------------------------------
//Description:
//Showthewindow
//----------------------------------------------------------------------
voidCIMWnd::ShowWindow(BOOLbShow)

...{
if(bShow==TRUE)

...{
::ShowWindow(m_hWnd,SW_SHOW);
}
else

...{
::ShowWindow(m_hWnd,SW_HIDE);
}
}

//----------------------------------------------------------------------
//Description:
//Destroythewindow
//----------------------------------------------------------------------
voidCIMWnd::DestroyWindow()

...{
::DestroyWindow(m_hWnd);
UnregisterClass(WINDOW_CLASS,m_hInst);
}



//----------------------------------------------------------------------
//Description:
//Initialize
//----------------------------------------------------------------------
BOOLCIMWnd::Initialize(HINSTANCEhInst,HWNDhWndSip)

...{
m_hInst=hInst;
m_hWndSip=hWndSip;


WNDCLASSwc;
wc.style=CS_VREDRAW|CS_HREDRAW;;
wc.lpfnWndProc=WndProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInst;
wc.hIcon=NULL;
wc.hCursor=NULL;
wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName=NULL;
wc.lpszClassName=WINDOW_CLASS;
if(RegisterClass(&wc)==0)

...{
returnFALSE;
}

//CreateSIPwindow.
m_hWnd=CreateWindowEx(0,
WINDOW_CLASS,
WINDOW_TITLE,
WS_CHILD|WS_BORDER,
CW_USERDEFAULT,
CW_USERDEFAULT,
CW_USERDEFAULT,
CW_USERDEFAULT,
hWndSip,
NULL,
m_hInst,
NULL
);


if(IsWindow(m_hWnd)==FALSE)

...{
returnFALSE;
}

returnTRUE;
}


CIMWnd::~CIMWnd()

...{
DeleteCriticalSection(&m_CriticalForWaitFresh);
if(m_pInstance!=NULL)

...{
deletem_pInstance;
m_pInstance=NULL;
}
}


CIMWnd::CIMWnd()

...{

m_pIMCallback=NULL;
m_hWnd=NULL;
m_hInst=NULL;
m_hWndSip=NULL;
}


//----------------------------------------------------------------------------
//Decription:
//OnmessageMYMSG_REGCALLBACK
//-----------------------------------------------------------------------------
voidCIMWnd::OnRegCallback(HWNDhWnd,UINTwMsg,WPARAMwParam,LPARAMlParam)

...{
m_pIMCallback=(IIMCallback*)wParam;
}



//----------------------------------------------------------------------
//Description:
//Windowprocess
//----------------------------------------------------------------------
LRESULTCIMWnd::WndProc(HWNDhWnd,UINTwMsg,WPARAMwParam,LPARAMlParam)

...{
switch(wMsg)

...{
...

caseMYMSG_REGCALLBACK:
m_pInstance->OnRegCallback(hWnd,wMsg,wParam,lParam);
return0;

...
}
returnDefWindowProc(hWnd,wMsg,wParam,lParam);
}
这里需要注意的是m_pIMCallback指针,它保存的是输入法管理器传回来的函数地址,我们可以通过这个回调函数来像外发送字符.例如:m_pIMCallback->SendString(TEXT(","),1);
MYMSG_REGCALLBACK是自定义的消息,用来通知输入法窗口来保存函数地址.该消息的发送是在CInputMethod类的RegisterCallback()函数中.
一个简单的输入法架构基本上已经完成,在下一章中将介绍一些输入法的调试技巧和需要注意的问题.
//TITLE:
// 漫谈WinCE输入法的编写(三)
//AUTHOR:
// norains
//DATE:
// Friday 2-March -2007
//Environment:
// EVC4.0 + Standard SDK
//========================================================================
这次就让我们来看看一个简单的输入法界面窗口的实现.如果以类的观点来看,输入法界面窗口和普通的应用程序的窗口没有什么不同,可能也是唯一最大的差异就是输入法窗口不能也不应该发送PostQuiteMessage,否则将导致输入法管理器的退出.
闲话不表,直接来看看一个最简单的输入法窗口架构:







































































































































































































































这里需要注意的是m_pIMCallback指针,它保存的是输入法管理器传回来的函数地址,我们可以通过这个回调函数来像外发送字符.例如:m_pIMCallback->SendString(TEXT(","),1);
MYMSG_REGCALLBACK是自定义的消息,用来通知输入法窗口来保存函数地址.该消息的发送是在CInputMethod类的RegisterCallback()函数中.
一个简单的输入法架构基本上已经完成,在下一章中将介绍一些输入法的调试技巧和需要注意的问题.