Use the software Input Panel in wince Program Development

Source: Internet
Author: User

 

Introduction

The software Input Panel (SIP) is a basic function of every mobile platform equipped with the wince system. It provides a means for users to input data on PDA. When talking about sip, we generally think of two points: one is the SIP itself, and the other is how to use sip in the program.

SIP is a COM object that implements the iinputmethod or iinputmethod2 interface. It should be transferred to use by the system, so you cannot perform sip development in C. C or C ++ is a good development language. Because SIP itself is just another COM Object, ATL makes the development process extremely simple. I don't want to discuss sip development here. The SDK contains a good routine atldvoraksip, so you can learn this routine to get more information. Here I want to discuss how to manage the SIP in your own program. This seems trivial and simple, but if you want to make your program smarter and more convenient for users because the screen is not enough, the management of SIP becomes an important aspect. In addition, if you develop a lot of SIP for different occasions (such as multiple languages, numbers, and others), you may want to use a specific sip in a certain situation. This capability allows you to complete many different tasks: when users only need to input numbers, you can display a large numeric keyboard, in this way, he does not need to write a pen and just needs to input it with his fingers. Of course, you can also have your own ideas, which depends on what the programmer should do.

Win32 API

The sip api function is very simple. Only a few functions can be seen from sipapi. h:

DWORD winapi sipstatus ();
Bool winapi sipsetdefaultrect (rect *);
Bool winapi sipregisternotification (hwnd );
Bool winapi sipshowim (DWORD );
Bool winapi sipgetinfo (sipinfo *);
Bool winapi sipsetinfo (sipinfo *);
Int winapi sipenumim (imenumproc );
Bool winapi sipgetcurrentim (CLSID *);
Bool winapi sipsetcurrentim (CLSID *);

I started with this because it supports both Windows Mobile and ce.net platforms. If you program Windows Mobile devices, aygshell. H provides you with more sip-related functions. Of course, which one you choose to use depends on your own needs. Using the sip on Windows Mobile will make your work more perfect. If you use the same OS version but different build versions, you may get a slightly different SIP behavior. Therefore, a method does not necessarily apply to all PDAs as you think.

List available sip instances

The first step is to understand how to list all available sip instances. You can use the following code:

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 );
}
}

The Code fills in a Global Map that contains the "sip name"/CLSID pair. This example and others use MFC. Of course you can also use the familiar Win32 API or other frameworks. The following are the Display Results On My Dell Axim x50:


  

How to select, display, and hide a specific sip

When you know the CLSID of a sip, you can select it. At the same time, the selected SIP can also be obtained:

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;
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 ());
}
}

Here, you can see the modified example (csipdemodlg: onbuttonenum (), which detects which SIP is activated and selects the corresponding row in The ListBox. For other examples, select sip and show or hide it. Note: To make sipgetinfo or sipsetinfo work, you must use the sizeof (sipinfo) value to initialize sipinfo. cbsize so that the operating system can respond normally. This is a common Win32 solution.

Sipgetinfo gives you the visible desktop and Sip size, so that you can re-customize the SIP location as needed. Sipsetinfo does not change the location of the SIP. If you need to move the SIP, use sipsetdefaultrect. Some examples are provided below.

Use Shell functions

If you decide to use aygshell-based functions, shsippreference will also complete similar tasks for you. Like sipshowim, this API will display and hide the Input Panel. Its last parameter defines what to do. You can request to display or hide the Input Panel and immediately hide it (because the operating system will set a timer in a common case) or discard all pending requests. Shsipinfo allows you to perform the same operations as the sipxxx function.

Generally, you can use all the above APIs to respond to wm_settingchaange or wm_create messages. According to the document, be careful when using shsipinfo to process the wm_settingchange message. There are several reasons: the interaction between the worker and the Input Panel thread will take about Ms. This will cause the wm_settingchange message to be sent to all running programs, so the system will lose response for a period of time. Passing the lparam value and wm_settingchange at the same time will avoid such latency.

When talking about Shell functions, some functions on Windows Mobile Platforms are very useful and may cause headaches. These include shinputdialog, shfullscreen, or similar calls. In addition, shhandlewmactivate and shhandlewmsettingchange allow you to fully enjoy the fun of the keyboard pop-up in the MFC program, because they are used in the cdialog and cframewnd classes of the appropriate message handle. If you do not want to have the default behavior, you can reload the onactivate or onsettingchange handle.
 
 Custom Control

If you want to support an intelligent input box-the keyboard automatically pops up each time you enter the box, and the keyboard is hidden when the input focus is removed from the input box, then wm_setfocus and wm_killfocus must be processed. The following code helps you:

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 );
}

Set the SIP location

Next we will talk about how to move the SIP to a certain position on the screen. Sipsetdefaultrect will change the holding of the default sip, but it will not take effect immediately, unless you re-select the input method:

Void csipdemodlg: onbuttonmove ()
{
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;
If (sipgetcurrentim (& CLSID ))
{
Sipsetcurrentim (& CLSID );
}
Sipshowim (sipf_on );
}
}

;

The above code shows you how to move the SIP location on the screen. This is useful when you want to place some controls at the lower end of the screen. Of course, this is not in line with Microsoft's Pocket pc gui Design Standards, but sometimes you have no other choice.

If you can obtain the window handle to control the window style, for example:

Long lstyle = getwindowlong (hwndsip, gwl_style );
Lstyle | = ws_caption | ws_sysmenu;
Setwindowlong (hwndsip, gwl_style, lstyle );

Conclusion

We have discussed several aspects of sip management in the WindowsCE operating system. We hope these will help your program become a winner in the eyes of users.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.