很多公司要求智能设备如手持终端等一开机就必须进入自己的程序登陆页面,不得进行其他操作,为此需要隐藏系统任务栏。系统任务栏隐藏后,不能调用系统的输入法,则需要在程序中调用系统输入法。
以下是程序中调用系统输入法的具体方法
全局变量,存储系统输入法
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);
return 1;
}
定义一字符串数组,存储各输入法名字
CStringArray m_sTypeWriting;
SipEnumIM(SipEnumIMProc);
CString sSipName;
CLSID *pCLSID = NULL;
for(POSITION pos = g_SipMap.GetStartPosition();pos;)
{
g_SipMap.GetNextAssoc(pos,sSipName,pCLSID);
m_sTypeWriting.Add(sSipName);
}
当点击按钮时,输入法选择菜单在相应位置显示。
为菜单预定义ID
#define ID_POPUP_TYPEWRITINGHIDE 32778
#define ID_POPUP_TYPEWRITINGONE 32779
#define ID_POPUP_TYPEWRITINGTWO 32780
#define ID_POPUP_TYPEWRITINGTHREE 32781
#define ID_POPUP_TYPEWRITINGFOUR 32782
#define ID_POPUP_TYPEWRITINGFIVE 32783
#define ID_POPUP_TYPEWRITING 32784
void CTestingDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
//新建菜单
CMenu menu;
menu.CreatePopupMenu();
menu.AppendMenuW(MF_STRING,ID_POPUP_TYPEWRITING,_T("TWPopUp"));
CMenu submenu;
submenu.CreatePopupMenu();
menu.AppendMenuW(MF_POPUP,(UINT_PTR)(submenu.m_hMenu));
for(int i=0;i<m_sTypeWriting.GetCount();i++)
{
//设计最多种输入法
if(i>=5)
{
break;
}
submenu.AppendMenuW(MF_STRING,ID_POPUP_TYPEWRITINGHIDE+i+1,m_sTypeWriting.GetAt(i));
}
submenu.AppendMenuW(MF_STRING,ID_POPUP_TYPEWRITINGHIDE,_T("隐藏输入法"));
//取出按钮所在位置
CButton *pBtn = (CButton *)GetDlgItem(IDC_BUTTON1);
CRect rect;
pBtn->GetWindowRect(&rect);
//显示菜单
int x = rect.right;
int y = rect.top;
submenu.TrackPopupMenu(TPM_BOTTOMALIGN | TPM_RIGHTALIGN,x,y,this);
}
为新添加的菜单添加响应函数
BOOL CStateBarDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
// TODO: 在此添加专用代码和/或调用基类
int nMenuID = LOWORD(wParam);
CString sSipName;
CLSID *pCLSID = NULL;
switch(nMenuID)
{
case ID_POPUP_TYPEWRITINGHIDE:
//隐藏输入面板
SipShowIM(SIPF_OFF);
break;
case ID_POPUP_TYPEWRITINGONE:
ShowPanel(0);
break;
case ID_POPUP_TYPEWRITINGTWO:
ShowPanel(1);
break;
case ID_POPUP_TYPEWRITINGTHREE:
ShowPanel(2);
break;
case ID_POPUP_TYPEWRITINGFOUR:
ShowPanel(3);
break;
case ID_POPUP_TYPEWRITINGFIVE:
ShowPanel(4);
break;
default:
break;
}
return CDialog::OnCommand(wParam, lParam);
}
//显示相应的输入面板
int CStateBarDlg::ShowPanel(int pos)
{
CString sSipName;
CLSID *pCLSID = NULL;
sSipName = m_sTypeWriting.GetAt(pos);
if(!g_SipMap.Lookup(sSipName,pCLSID))
{
return 1;
}
SipSetCurrentIM(pCLSID);
SipShowIM(SIPF_ON);
return 0;
}
补充说明:在WInCE5.0的标准SDK中会提示SipEnumIM SipShowIM SipSetCurrentIM是无法解析的外部函数
解决方法:
typedef int (* sipenumim)(IMENUMPROC pEnumIMProc);
typedef bool (* sipshowim)(DWORD dwFlag);
typedef bool (* sipsetcurrentim)(CLSID* pClsid);
定义成员函数变量:
sipenumim m_funSipEnumIM;
sipshowim m_funSipShowIM;
sipsetcurrentim m_funSipSetCurrentIM;
HINSTANCE m_hLibrary;
m_hLibrary = LoadLibrary(_T("Coredll.dll"));
if(m_hLibrary == NULL)
{
CUserMessageBox::ErrorMessageBoxOK(NULL,_T("装入动态链接库Coredll.dll失败,将 会输入面板不能使用"));
return false;
}
m_funSipEnumIM= (sipenumim)GetProcAddress(m_hLibrary,_T("SipEnumIM"));
if(m_funSipEnumIM == NULL)
{
CUserMessageBox::ErrorMessageBoxOK(NULL,_T("未找到函数SipEnumIM"));
return false;
}
m_funSipShowIM = (sipshowim)GetProcAddress(m_hLibrary,_T("SipShowIM"));
if(m_funSipShowIM == NULL)
{
CUserMessageBox::ErrorMessageBoxOK(NULL,_T("未找到函数SipShowIM"));
return false;
}
m_funSipSetCurrentIM = (sipsetcurrentim)GetProcAddress(m_hLibrary,_T("SipSetCurrentIM"));
if(m_funSipSetCurrentIM == NULL)
{
CUserMessageBox::ErrorMessageBoxOK(NULL,_T("未找到函数SipSetCurrentIM"));
return false;
}
然后再代码中用m_funSipEnumIM m_funSipShowIM m_funSipSetCurrentIM
分别替换SipEnumIM SipShowIM SipSetCurrentIM即可