|
Using Shell Functions If you have decided to use aygshell-based functions, SHSipPreference will do similar job for you. Like SipShowIM, this API shows and hides input panel. Its last parameter defines what to do, and there you may request rise or lower input panel, lower it immediately (because the OS sets a timer before hiding SIP in a regular case) or disregard all pending down requests. SHSipInfo allows you to perform the same operations as SipXXX functions. Usually, you will use all above APIs in respond to WM_SETTINGCHANGE or WM_ACTIVATE messages. According to the documentation, you have to be careful when using SHSipInfo around WM_SETTINGCHANGE processing due to several reasons. First, SIP changes may cause WM_SETTINGCHANGE messages to be sent by shell, so beware of infinite loops there when you're calling it in your handler. Next, SHSipInfo interacts with Device.exe and input panel thread, which takes up to 100 ms. This results in that WM_SETTINGCHANGE is sent to all running applications, so the system can be freezed for some time. Passing lParam value coming along with WM_SETTINGCHANGE allows you avoiding such delays. Speaking about shell functions, there are a number of them on Windows Mobile platform that can either help you or deliver you an additional headache. Under the "help" section, I mean SHInputDialog, SHFullScreen, and similar calls. On the other hand, SHHandleWMActivate and SHHandleWMSettingChange may get you a lot of fun time enjoying a keyboard popping up in MFC application, because they are used in CDialog and CFrameWnd classes in appropriate message handlers. If you don't want the default behavior, you have to override the OnActivate or OnSettingChange handlers. Custom Controls Let me say a couple of words regarding handling SIP in custom controls. Suppose you want to implement a 'smart behavior' in our editbox-related classes; in other words, every time the user taps inside such an edit, a keyboard will automatically pop up and then hide upon removing the focus from the editbox. Adding WM_SETFOCUS and WM_KIILLFOCUS handlers will do to achieve this goal. You can decorate it even more, setting up the specific SIPs or input panel position on the screen. The next snippet gives you a clue: void CSipEdit::OnSetFocus(CWnd* pOldWnd) { CEdit::OnSetFocus(pOldWnd); SHSipPreference(m_hWnd,SIP_UP); } void CSipEdit::OnKillFocus(CWnd* pNewWnd) { CEdit::OnKillFocus(pNewWnd); SHSipPreference(m_hWnd,SIP_FORCEDOWN); } Put Your Hands On SIP Well, let me finally discuss how to move the SIP to the desired position on the screen. SipSetDefaultRect will change a default rectangle of the SIP, but this new value won't be taken until you re-select IM: void CSIPDemoDlg::OnButtonMove() { SIPINFO SipInfo; memset(&SipInfo,0,sizeof(SipInfo)); SipInfo.cbSize=sizeof(SIPINFO); BOOL bRes = SipGetInfo(&SipInfo); if ( bRes ) { CRect rc(SipInfo.rcSipRect); rc.OffsetRect(0,-20); SipSetDefaultRect(&rc); CLSID clsid; if ( SipGetCurrentIM(&clsid) ) { SipSetCurrentIM(&clsid); } SipShowIM(SIPF_ON); } } The above sample sequentially moves SIP up the screen. Repositioning the SIP may be useful when you have to place some controls at the bottom of the screen. This is quite out of Microsoft's standards of Pocket PC GUI style, but sometimes you have just no other choice. Now, turn your sights to the Registry keys. There are a couple of them that allow you dig deeper into SIP's waters: [HKEY_CURRENT_USERControlPanelSip] |