在应用中使用输入面板的注意
2008-01-23 17:08
253 查看
简介
软件输入面板(Software Input Panel,简称SIP)是每个装备了WinCE系统的移动平台的一个基本功能。它提供给用户在PDA上进行数据输入的一种手段。当谈及SIP的时候,我们一般会想到两点:一是SIP本身,二是如何在程序中使用SIP。
SIP是一个实现了IInputMethod或者IInputMethod2接口的COM对象。它应该被系统调入使用,所以你不能在[color=#3366cc]C#[/color]中进行SIP开发。C或者[color=#3366cc]C++[/color]是很好的[color=#3366cc]开发语言[/color]。因为SIP本身也只是另外一个COM对象,ATL使得开发过程变得极为简单。这里我不想讨论SIP开发,SDK包里包含了一个很好的例程ATLDvoraksip,所以你可以去学习这个例程以获取更多的信息。 这里我想讨论的是如何在你自己的程序里管理SIP。这看起来很琐碎简单,但是如果因为屏幕不太够用,而你又想使得你的程序更加聪明更加方便用户使用,那SIP的管理就变成很重要的一个方面了。另外,如果你开发了很多用于不同场合的SIP(比如多语言,数字或者其他等等),你可能想在某个场合使用某个特定的SIP。这种能力使得你可以完成很多不同的任务:当用户只需要进行数字输入的时候,你可以展示一个大的数字[color=#3366cc]键盘[/color],这样他不用笔而只需要用手指就可以输入了。当然你也可以有自己的想法,这就看程序员该作些什么了。
Win32 API
SIP的API函数很简单,从sipapi.h中只可以看到只有极少几个函数:
我把这些放在开始,是因为它同时支持[color=#3366cc]Windows[/color] Mobile和CE[color=#3366cc].net[/color]平台。如果你对[color=#3366cc]Windows[/color] Mobile设备编程,那么aygshell.h文件提供给你更多的和SIP有关的函数供使用。当然选择哪个来使用就依赖于你自己的需求了,使用[color=#3366cc]Windows Mobile[/color]上的SIP会使得工作更加完美一些。如果你使用了相同的OS版本,但是不同的build版本的时候,你可能会获得稍微不同的SIP行为。所以,一种方法并不一定像你所想的那样在所有的PDA上都会适用。
列举可用的SIP
第一步就是了解如何列举所有可用的SIP。可以使用如下的代码:
代码所作的就是填充一个全局的map,它包含了"SIP名"/CLSID对。这个例子和其他的都用到了MFC,当然你也可以使用熟悉的Win32 API或者其他的框架。以下是我的Dell Axim x50上的显示效果:
[table=90%][align=center][/align] 如何选择,显示和隐藏特定的SIP
当你知道某个SIP的CLSID,你可以选择它。同时,当前选择的SIP也可以被获得:
这里,你可以看到修改的例子(CSIPDemoDlg::OnButtonEnum()),它检测哪个SIP是被激活的并且选择listbox里相应的行。其他例子的对话框方法选择SIP并且显示或者隐藏它。注意,为了使得SipGetInfo或者SipSetInfo工作,你必须用sizeof(SIPINFO)的值初始化SIPINFO.cbSize,这样[color=#3366cc]操作系统[/color]才能正常反应。这是一个很常用的Win32的解决方式。
SipGetInfo给你可视的桌面和SIP大小,这样你可以在需要的时候重新定制SIP的位置。而SipSetInfo不会改变SIP的位置。如果你需要移动SIP,使用SipSetDefaultRect。下面会给出一些例子来说明的。
软件输入面板(Software Input Panel,简称SIP)是每个装备了WinCE系统的移动平台的一个基本功能。它提供给用户在PDA上进行数据输入的一种手段。当谈及SIP的时候,我们一般会想到两点:一是SIP本身,二是如何在程序中使用SIP。
SIP是一个实现了IInputMethod或者IInputMethod2接口的COM对象。它应该被系统调入使用,所以你不能在[color=#3366cc]C#[/color]中进行SIP开发。C或者[color=#3366cc]C++[/color]是很好的[color=#3366cc]开发语言[/color]。因为SIP本身也只是另外一个COM对象,ATL使得开发过程变得极为简单。这里我不想讨论SIP开发,SDK包里包含了一个很好的例程ATLDvoraksip,所以你可以去学习这个例程以获取更多的信息。 这里我想讨论的是如何在你自己的程序里管理SIP。这看起来很琐碎简单,但是如果因为屏幕不太够用,而你又想使得你的程序更加聪明更加方便用户使用,那SIP的管理就变成很重要的一个方面了。另外,如果你开发了很多用于不同场合的SIP(比如多语言,数字或者其他等等),你可能想在某个场合使用某个特定的SIP。这种能力使得你可以完成很多不同的任务:当用户只需要进行数字输入的时候,你可以展示一个大的数字[color=#3366cc]键盘[/color],这样他不用笔而只需要用手指就可以输入了。当然你也可以有自己的想法,这就看程序员该作些什么了。
Win32 API
SIP的API函数很简单,从sipapi.h中只可以看到只有极少几个函数:
D[color=#3366cc]Word[/color] WINAPI SipStatus(); BOOL WINAPI SipSetDefaultRect(RECT *); BOOL WINAPI SipRe[color=#3366cc]GIS[/color]terNotification(HWND); BOOL WINAPI SipShowIM(D[color=#3366cc]Word[/color]); BOOL WINAPI SipGetInfo(SIPINFO *); BOOL WINAPI SipSetInfo(SIPINFO *); int WINAPI SipEnumIM(IMENUMPROC); BOOL WINAPI SipGetCurrentIM(CLSID *); BOOL WINAPI SipSetCurrentIM(CLSID *); |
列举可用的SIP
第一步就是了解如何列举所有可用的SIP。可以使用如下的代码:
CTypedPtrMap<CMapStringToPtr,CString,CLSID*> g_SipMap; int SipEnumIMProc(IMENUMINFO *pIMInfo) { CLSID* pCLSID = new CLSID; memcpy(pCLSID,&pIMInfo->clsid,sizeof(CLSID)); g_SipMap.SetAt(CString(pIMInfo->szName),pCLSID); TRACE(_T("%sn"),CString(pIMInfo->szName)); return 1; } void CSIPDemoDlg::OnButtonEnum() { SipEnumIM(SipEnumIMProc); CString sSipName; CLSID *pCLSID = NULL; for (POSITION pos = g_SipMap.GetStartPosition(); pos; ) { g_SipMap.GetNextAssoc(pos,sSipName,pCLSID); m_SipList.AddString(sSipName); } } |
[table=90%]
当你知道某个SIP的CLSID,你可以选择它。同时,当前选择的SIP也可以被获得:
void CSIPDemoDlg::OnButtonEnum() { SipEnumIM(SipEnumIMProc); CLSID CurrSip; SipGetCurrentIM(&CurrSip); int nCurrSip = LB_ERR, nSipCount = 0; CString sSipName, sCurrSipName; CLSID *pCLSID = NULL; for (POSITION pos = g_SipMap.GetStartPosition(); pos; ) { g_SipMap.GetNextAssoc(pos,sSipName,pCLSID); m_SipList.AddString(sSipName); if ( memcmp(&CurrSip,pCLSID,sizeof(CLSID)) == 0 ) { nCurrSip = nSipCount; sCurrSipName = sSipName; } nSipCount++; } m_SipList.SelectString(0,sCurrSipName); } void CSIPDemoDlg::OnButtonSelect() { int nSel = m_SipList.GetCurSel(); if ( LB_ERR == nSel ) return; CString sSipName; m_SipList.GetText(nSel,sSipName); CLSID *pCLSID = NULL; if ( !g_SipMap.Lookup(sSipName,pCLSID) ) return; BOOL bRes = SipSetCurrentIM(pCLSID); if ( !bRes ) TRACE(L"SipSetCurrentIM returned %lun",GetLastError()); } void CSIPDemoDlg::OnButtonShowHide() { if ( !g_bShow ) { SipShowIM(SIPF_ON); g_bShow = TRUE; } else { SipShowIM(SIPF_OFF); g_bShow = FALSE; } } void CSIPDemoDlg::OnButtonShowHide2() { SIPINFO SipInfo; memset(&SipInfo,0,sizeof(SipInfo)); SipInfo.cbSize=sizeof(SIPINFO); BOOL bRes = SipGetInfo(&SipInfo); if ( bRes ) { if ( !g_bShow ) { SipInfo.fdwFlags |= SIPF_ON; g_bShow = TRUE; } else { SipInfo.fdwFlags = SIPF_OFF; g_bShow = FALSE; } bRes = SipSetInfo(&SipInfo); } else { TRACE(L"SipGetInfo returned %lun",GetLastError()); } } |
SipGetInfo给你可视的桌面和SIP大小,这样你可以在需要的时候重新定制SIP的位置。而SipSetInfo不会改变SIP的位置。如果你需要移动SIP,使用SipSetDefaultRect。下面会给出一些例子来说明的。
相关文章推荐
- 64位系统使用VS2010开发32位ASP.NET应用--注意事项
- jsf中使用js获得输入项值的注意事项
- web应用的MVC模型中使用bean的注意事项
- 在WinCE程序开发中使用软件输入面板
- C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码
- 开发中使用临时表的应用场景以及注意事项
- 关于使用while(!filePCloud.eof())判断文件结尾进行数据输入装换时注意事项
- 在Win CE程序开发中使用软件输入面板
- 使用nextInt()等接受输入时必须注意换行符的输入
- switch语句的应用注意break的配合使用
- 使用.net框架应用C#语言开发窗口程序的一些注意事项
- WINCE开发数据库应用如何直接使用SqlClient的注意事项
- websphere 不使用httpServer 来实在 输入IP地址,自动转向应用
- iOS 11开发教程(十七)iOS11应用视图之使用按钮接收用户输入
- 使用Kinect2作为Oculus游戏应用的输入设备
- UIDocumentInterRactionController 使用时的注意事项(其它应用打开)
- EL使用例子(与输入有关的隐含对象:param,paramValues)(注意:引入的标签)
- 使用nextInt()等接受输入时必须注意换行符的输入
- Android应用内多进程的使用及注意事项
- Vue使用高德地图搭建实时公交应用功能(地图 + 附近站点+线路详情 + 输入提示+换乘详情)