August 19, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Managing the Software Input Panel in Your Applications

  • February 8, 2006
  • By Alex Gusev
  • Send Email »
  • More Articles »

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]

Name Value
MenuBarHeight defines bottom-most position of the default SIP, defaulted to 26
DragStyle defines if SIP has a title bar, so user can drag it, defaulted to 0

If you have changed the Registry, it requires a warm boot to apply new values.

We can move even further in our investigation. Taking in mind that SIP has a window, we can use Spy++ to explore existing windows. You'll find, for example, "SipWndClass" on Windows Mobile 2003 SE among them. Thus, you may obtain a handle of such window. Once this is done, it is up to your needs or imagination what to do with it. For instance, you can change the SIP's window style:

long lStyle=GetWindowLong(hwndSIP,GWL_STYLE);
lStyle |= WS_CAPTION|WS_SYSMENU;
SetWindowLong(hwndSIP,GWL_STYLE,lStyle);

Conclusion

We have discussed here several different aspects of managing the SIP on Windows CE devices. Now, you have to be able to manipulate an input panel as easily as ever. Far East languages were left out of our discussion due to their complexity, but it is also possible to apply similar approach there. I hope that all stuff above will help you make your own application the winner in the user's eyes.

Download

Download the accompanying code's zip file here.

About the Author

Alex Gusev started to play with mainframes in the end of the 1980s, using Pascal and REXX, but soon switched to C/C++ and Java on different platforms. When mobile PDAs seriously rose their heads in the IT market, Alex did it too. Now, he works at an international retail software company as a team leader of the Mobile R department, making programmers' lives in the mobile jungles a little bit simpler.





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel