Creating Software Input Panel (SIP) for Windows Mobile

Download the source code

In Windows Mobile, Software Input Panel is a method to input characters like keyboard. The Windows Mobile provides several input methods by default, Keyboard, Block Recognizer, Letter Recognizer, Symbol Pad, Transcriber, etc… We can also create our own SIP. The component that provides this facility is call Input Method. It is a COM component that exposes the IInputMethod and IInputMethod2 interface. To create our own SIP, we have to create COM in-proc component and implement the IInputMethod and optionally IInputMethod2 interface.

The SIP contains two major components, Input Panel and Input Method. The Input Panel is created and maintained by the system. Input Method is the pluggable component of the SIP and is responsible for recognizing and transcribing the strokes and taps from the SIP window which will be child windows of the Input Panel.

To create out own SIP, we have to implement the IInputMethod interface. Using this interface’s methods, we have to create our input window and process the strokes and taps. The IInputMethod interface has the following methods:

    IInputMethod::Select
    IInputMethod::Deselect
    IInputMethod::Showing
    IInputMethod::Hiding
    IInputMethod::GetInfo
    IInputMethod::ReceiveSipInfo
    IInputMethod::RegisterCallback
    IInputMethod::GetImData
    IInputMethod::SetImData
    IInputMethod::UserOptionsDlg

The Select is called when the user chooses the Input Method from the list. In this function we have to create our child window and initialize any other variable. The Deselect method is called when the user chooses another Input Method, here we destroy the child window and perform cleanup.
The Showing and Hiding will be called when the Input Method is about to show and hide respectively. The GetInfo method will be called whenever the system needs the information about the SIP, here we fill the passed in IMINFO structure with the details of our SIP. The IMINFO structure is defined as:

struct _tagImInfo
{
DWORD cbSize;
HANDLE hImageNarrow;
HANDLE hImageWide;
int iNarrow;
int iWide;
DWORD fdwFlags;
RECT rcSipRect;
}

The cbSize should contain the size of the structure. The hImageNarrow and hImageNarrow variables should be filled with the handle to the image list that contains the image to be displayed on the task bar of the SIP button. The iNarrow and iWide variables should contain the index of the images in the image list. The fdwFlags variable is to specify the nature of or SIP, a combination of the flags SIPF_ON, SIPF_DOCKED, SIPF_LOCKED, and SIPF_DISABLECOMPLETION. The rcSipRect variable should be filled with the default rectangle of the SIP window. Normally we take the rectangle of the parent window.

The method ReceiveSipInfo is called when the SIP is shown and when the state of the SIP is changed. The RegisterCallback method is called only once and with one parameter, a pointer to IIMCallback interface. This interface provides methods to send characters, virtual key codes and strings to the Input Panel. The GetImData and SetImData methods is used to provide additional information about the SIP to the Input Panel. The UserOptionsDlg method is to display Options Dialog. This method is not called by the Input Panel, but by the control panel applet. This Input Method should display an Options dialog to configure the SIP.

The prototypes of the methods are:
HRESULT STDMETHODCALLTYPE Select(HWND hWndSip);
HRESULT STDMETHODCALLTYPE Deselect(void);
HRESULT STDMETHODCALLTYPE Showing(void);
HRESULT STDMETHODCALLTYPE Hiding(void);
HRESULT STDMETHODCALLTYPE GetInfo(IMINFO __RPC_FAR *pimi);
HRESULT STDMETHODCALLTYPE ReceiveSipInfo(SIPINFO __RPC_FAR *psi);
HRESULT STDMETHODCALLTYPE RegisterCallback(IIMCallback __RPC_FAR *lpIMCallback);
HRESULT STDMETHODCALLTYPE GetImData(DWORD dwSize, LPVOID pvImData);
HRESULT STDMETHODCALLTYPE SetImData(DWORD dwSize, LPVOID pvImData);
HRESULT STDMETHODCALLTYPE UserOptionsDlg(HWND hwndParent);

The IIMCallback interface has the following methods:

HRESULT STDMETHODCALLTYPE SetImInfo(IMINFO __RPC_FAR *pimi)
HRESULT STDMETHODCALLTYPE SendVirtualKey(BYTE bVK,DWORD dwFlags)
HRESULT STDMETHODCALLTYPE SendCharEvents(UINT uVK,UINT uKeyFlags,UINT uChars,UINT RPC_FAR *puShift,UINT __RPC_FAR *puChars)
HRESULT STDMETHODCALLTYPE SendString(BSTR ptszStr,DWORD dwChars)

The SetImInfo method is used to set the bitmap, screen location and visibility state of the IM. The SendVirtualKey is used to send a virtual key code to the current window. The SendCharEvents method is used to send Unicode characters to the current window. The SendString is used to send strings to the current window.

The sample presented here is a simple SIP that can be used to input only numbers. The SIP looks like this:

Numerickeypad

This is created using Microsoft Visual Studio 2008. This is simple example just to demonstrate the SIP, a real SIP will be more complicated that this.

Tool to register/unregister COM DLL files in Windows Mobile

Download the source code

During the development of a custom Software Input Panel (SIP) for Windows Mobile, I searched a lot for a tool to register and unregister COM DLL files just like Regsvr32.exe in Desktop environment. But I didn’t find any GUI based tool so I decided to create one. This is a simple dialog application to load and register/unregister the DLL file. This tool is created in Microsoft Visual Studio 2008.

TAPI Programming on Windows Mobile

Download the source code

TAPI stands for Telephony Application Programming Interface. TAPI is the Microsoft implementation of CTI (Computer Telephony Interface). TAPI provides a common interface to communicate and control a telephony device. TAPI simplifies the telephony programming since the programmer does not require detailed information about the hardware he/she is using.

Windows Mobile 5 support TAPI version 2.0. The version 2.0 brings telephony support to any Windows CE applications. The TAPI.DLL file exposes all the TAPI functions. The header file TAPI.H contains the all the function definitions, typedefs, #defines, etc… The application links to COREDLL.DLL file which redirects the calls to TAPI.DLL. The TAPI.DLL uses the TAPI Service Provider DLLs to communicate with the hardware. The TAPI Service Provider (TSP) is the driver for the hardware. Microsoft supplies default Unimodem TSP. The Unimodem TSP supports all the common telephony hardware. If your telephony hardware is not a common one, then you should have the vendor supplied TSP in order to work with TAPI.

All the application that uses TAPI should load and initialize the required DLL file. This is done through the API lineInitialize or lineInitializeEx. When initializing you have to give a callback function. This function will be called whenever a telephony event occurs such as incoming call, call connected, when the user presses a digit after the call is connected, etc… After initializing we need to negotiate the API. This is to ensure that the current TAPI system version and the version that the application is using overlaps. If the application version and the current TAPI versions are incompatible, then we will not be able to use the TAPI.

After the version is negotiated, we do different tasks like monitor a telephone line; initiate a call, etc… The sample presented here is a simple application to monitor the cellular telephone line. The application opens the cellular line and monitor for events and preset it to the use. The events along with other parameters will be displayed in a list box. Yes, I agree that no one will use this application for any serious purpose but for demonstrating TAPI application modal, I suppose this example is enough.

The application is created using Microsoft Visual Studio 2008 and only tested on Windows Mobile 6.1. I am sorry to say that I didn’t get time to comment the application. I will try to create a useful application and post it here when I get time.

Introduction to Plug-in Architecture

Download the source code

A plug-in is a software component to extent the functionality of an application. A Media player is a typical example of applications which make use of the plug-in architecture. All most all Media Players available now uses plug-in modal to deal with different input file formats and output device. Winamp, a popular media player, heavily uses plugging for input, output, visualization, DSP, etc… This is same in the case of Microsoft Media Player also.

As I already stated, a plug-in is a software component to extent an application. In Microsoft Windows, a plug-in is normally a DLL or a COM component. An application which consumes or uses the plug-in is called plug-in host. The host application loads the plug-in at start or when it is really needed to load the plug-in. Typically the host application scans a particular folder for the plug-in and loads all Plug-ins or it looks a number of predefined folders which is specified is a configuration file of registry. The host application collects the details of all the Plug-ins and gives the user the freedom to choose which plug-in to use or automatically choose the plug-in to use according to the user input. For example in case of media players, the user can choose which visualization plug-in should be active at a time. In case of which file to play, the host determine which plug-in to use as per the user’s selection.

The host application uses a well defined protocol to communicate with the plug-in. The protocol defines which functions we have to export in case the plug-in is a DLL or which interface we have to implement in case of a COM component. The host can make use of any component which confirms this protocol. So the host does not depend on a particular plug-in but all Plug-ins depends on the host.

The sample application presented here is a simple Image Viewer application. It will display three different image files, JPEG and PNG files. For JPEG and PNG images we use LIGJPEG and LIBPNG external libraries since these are very complex formats. Our Plug-ins will be simple DLL files. The host will load these DLL files and communicate with them as per the defined protocol. The format of the JPG and PNG files are complex and out of the scope of this article.

Now the communication protocol has to be defined. We have only one type of plug-in: input plug-in, whenever we need to read data from the file we use these plug-in. We can define the functions to be exported as:

IInputPlugin* GetPluginInterface();

This is the only function that needs to be exported. This function returns a pointer to the IInputPlugin. The IInputPlugin is defined as


class CInputPlugin
{
public:
virtual const char* GetFileName() = 0;
virtual const char* GetPluginName() = 0;
virtual const char* GetDescription() = 0;
virtual unsigned long GetVersion() = 0;
virtual const char* GetFilterString() = 0;
virtual const char* GetExtension() = 0;
virtual DWORD GetWidth() = 0;
virtual DWORD GetHeight() = 0;
virtual BYTE GetBitCount() = 0;
virtual BYTE GetColorType() = 0;
virtual BYTE GetPlanes() = 0;
virtual BYTE GetCompression() = 0;
virtual DWORD GetScanLineWidth() = 0;
virtual DWORD GetPasses() = 0;
virtual int OpenImage(const char* lpszFile) = 0;
virtual int ReadScanLine(unsigned char* lpBuffer,unsigned long dwSize,unsigned int uLine) = 0;
virtual int CloseImage() = 0;
virtual void Release() = 0;
};

typedef CInputPlugin IInputPlugin;

As you can see the IInputPlugin is an ABC(Abstract Base class). The input plug-in needs to implement this interface and return the pointer to the implementation class. The host application will use this pointer to manipulate he image

The host application is a normal MFC application. When the application loads it scans a folder for plug-in DLLs and loads all the Plug-ins found. The host application stores all the information about the plug-in for future use. When the user opens an image file, the host application searches this information to find which plug-in to use. The host then loads the corresponding plug-in and calls the OpenImage function. If the function returns 1, the get the information about the image and create a DIB Section based on the information. Then the host reads all the scan lines and displays the image.

There are many ways to extend this application. One way is to implement output Plug-ins. The output Plug-ins converts the given image data to some other formats and saves this to a file. We can define the protocol just like the input Plug-ins and create different output Plug-ins. This will give the user the ability to convert from one image format to another. One another way is to support image processing Plug-ins. The image processing Plug-ins accepts the image data and processes it and gives the processed image back to the host. There are many possibilities; I left this to your imagination.

Although I use C++/MFC to create this, we can extend this to any other languages or platforms. Plug-in Architecture is very powerful and using this we can create easily extensible application.

This is a very simple introduction, to better understand this architecture just search for Plug-in Architecture; you will find a lot of information.

The sample application is only tested in Windows 2003.

Programming GPS on Windows Mobile 5 or above

Download the source code

Windows Mobile 5 introduce the GPS Intermediate Driver. As the name implies, it is an intermediate driver between client application and the actual GPS device. The client application sees this driver as an actual GPS device. The device sees this driver as a client application. The GPS Intermediate driver interacts with the actual device driver provided with the GPS hardware and gives this data to the application. We can access either the parsed or raw GPS data using this driver.

The parsed data API has 4 functions:

    GPSOpenDevice
    GPSGetPosition
    GPSGetDeviceState
    GPSCloseDevice

GPSOpenDevice opens the device for accessing the data and returns a handle to the device. GPSGetPosition retrieves the parsed data. GPSGetDeviceState retrieves the device information. GPSCloseDevice closes the device. It is important the GPSCloseDevice should be called for each GPSOpenDevice. Whenever we open the device, the driver increment the reference count and when we close the device the reference count is decremented. When the device is no longer used by any client application, the device is closed. So it very important to close the device after use, otherwise it will stay opened and lot of power will be consumed. The GPS hardware is one of the components that use lot of power.

To receive the raw data, application uses CreateFile to open the device, ReadFile to read the raw data and CloseHandle to the close the device. The filename parameter of the CreateFile will be the COM port. This COM port is configured in the registry key HKEY_LOCAL_MACHINESystemCurrentControlSetGPS Intermediate DriverDrivers. Under this key there will an entry CurrentDriver. The value of this key will be a subkey of the above registry key. For example if the current GPS driver is “GPSOneDevice” then the key will be HKEY_LOCAL_MACHINESystemCurrentControlSetGPS Intermediate DriverDriversGPSOneDevice. Under this key, the entry “InterfaceType” and “CommPort” determines the COM port and the type. If CommPort entry has the value COM4, the filename for the CreateFile will be “$deviceCOM4:”. The ReadFile returns the string data in the NMEA format. For more information, visit this NMEA Web Site.

The syntax of the GPSOpenDevice function is
HANDLE GPSOpenDevice(HANDLE hNewLocationData,HANDLE hDeviceStateChange,const WCHAR szDeviceName,DWORD dwFlags);. The first and second parameters are handle to and event object created by CreateEvent API. The event hNewLocationData will be set when the location data is available and the hDeviceStateChange event will be set when the device state is changed. we can use WaitForMultipleObject for wait for the events. Whenever an event occurs we could retrieve the GPS position or device information. This gives us very convenient way to read the data from the device.

The sample application created here is a simple dialog based application. The Longitude, Latitude, Speed and Satellite count is displayed. The application will also display the device information if available. The application is created by Visual Studio 2008. The application creates a thread when the device is started and waits for any event occurs. Whenever the event occurs the main application will be notified about the event. When the main application is notified the data is displayed on the screen.

Writing a Windows Mobile Today Screen Plugin

Download Sample Source Code

Today Screen is a place to display critical information in Windows Mobile. Windows Mobile by default displays appointments, tasks, messages, calendar, owner information etc… We can create plugin to display our own information. A sample Today Screen looks like:

Sample Today Screen

Sample Today Screen

Today screen plugins are DLL which exports the one required function and one optional function. InitializeCustomItem is the required function and CustomItemOptionsDlgProc is the optional one. The DLL should export the InitializeCustomItem as ordinal 240. This function is called by the Shell process when the Today Screen item is initialized. In this function we can create window to be displayed and initialize whatever variables we are using. This is the only function in which we can set the height of the today item’s window. If the Plugin supports the options dialog, then it should export the CustomItemOptionsDlgProc also. In this function we can create options dialog and present the user whatever options are available. The .def file of the DLL should contain the following EXPORTS section

EXPORTS
InitializeCustomItem @ 240 NONAME
CustomItemOptionsDlgProc @ 241 NONAME

After creating the Today item’s window, the system will send the WM_TODAYCUSTOM_REFRESHCACHE message to the window. The WPARAM parameter will contains a pointer to the TODAYLISTITEM structure. This structure and all Today Screen related structures are defined in todaycmn.h header file. The TODAYLISTITEM structure is defined as:

struct _TODAYLISTITEM
{
CHAR szName[MAX_ITEMNAME];
TODAYLISTITEMTYPE tlit;
WORD dwOrder;
DWORD cyp;
OOL fEnabled;
BOOL fOptions;
WORD grfFlags;
TCHAR szDLLPath[MAX_PATH];
INSTANCE hinstDLL;
HWND hwndCustom;
OOL fSizeOnDraw;
BYTE * prgbCachedData;
WORD cbCachedData;
};

The fEnabled member of the structure will be TRUE if the Today item is enabled, otherwise it will be FALSE. The cyp member should contain the height of the windows, if this member is set to 0, the system will not send the WM_TODAYCUSTOM_REFRESHCACHE message.

The syntax of the InitializeCustomItem is:

HWND APIENTRY InitializeCustomItem(TODAYLISTITEM *pItem,HWND hWndParent);

The hWndParent parameter will be the handle of the Today Item’s parent window. If the Today item is not enabled we should immediately return NULL.

The system sends WM_TODAYCUSTOM_CLEARCACHE message to the Today item’s window when it is about to be unloaded. The WPARAM parameter contains a pointer to the TODAYLISTITEM structure. Upon receiving this message we can clear and cached data or any allocated memory we are using and return.

Whenever the Options button is clicked the system will call the CustomItemOptionsDlgProc function. One more requirement is that you should provide the resource for the dialog to be displayed and its resource id should be 500.

In our simple example we just display the battery status and internal memory status. If the battery is charging it will display the string “Charging…” otherwise displays the battery percentage. We will also display percentage of how much memory is used.

The today screen looks like this.

Our Today Screen

Our Today Screen

Many modifications can be done to this sample. One simple modification is to avoid flickering. To do this we can use double buffering or something else. I left this to your imagination.

In this example, to get the battery and memory status we use GetSystemPowerStatusEx and GlobalMemoryStatus functions.

The plugin has to be registered in the registry for the Today Screen to find and locate the custom items. The Registry key is [HKEY_LOCAL_MACHINE]SoftwareMicrosoftTodayItems]. Each Today Screen items should create a subkey with its name under this key. It should contain the following values:

Name Containing the name of the item.
DLL Contains the full path name of the DLL implementing the item.
Flags User-defined DWORD value returned in the grfFlags field of TODAYLISTITEM.
Options DWORD value set to 1 if the item supports an Options dialog box.
Enabled DWORD value set to 1 if the item is enabled.
Type Custom items must set this DWORD value to 4.

We can use Windows CE Remote Registry Editor to edit the key or we can use the CabWiz.exe file to create installation CAB file and specify these key in the .INF file.

Hope this article will give you an introduction to the Today Screen plugins. There are many resources available on the Internet. Just search for the Today Screen API and you will find many examples.

The example is only tested on I-Mate K-JAM, but may work in any other platforms.

Retrieving GPS data from Internal GPS receiver using Python for Series 60

Using PyS60 we can retrieve GPS data either from Bluetooth receiver or Internal GPS receiver. There are many examples describing how to receive data from Bluetooth receiver. But there are only little information about using the Internal GPS receiver which in present in some of the Nokia handsets (N95, N82, etc…). I wrote a small PyS60 script to retrieve GPS data using internal receiver.

To receive the GPS data we use the positioning module. The position module has many methods to select the receiver module, request the service, retrieve the GPS data, etc… Here is the script to retrieve the data. Copy this script to a file and upload to Python folder of your phone and use the Python Shell to run the script. Please note that you should have a signed version of the Python Shell with Location capability in order to run this script, otherwise you will receive and error.

import positioning

print "Sample script to display GPS data, by Krishnaraj Varma"
print ""
print "Default Module:"
print positioning.default_module()
print ""
positioning.select_module(positioning.default_module())
print "Detailed Module Info:"
print ""
print positioning.module_info(positioning.default_module())
print "GPS Data:"
print ""
positioning.set_requestors([{"type":"service","format":"application","data":"test_app"}])
print positioning.position(course=1,satellites=1)
print ""
print ""

On my Nokia N82 phone the output is:

Sample script to display GPS data, by Krishnaraj Varma

Default Module:
270526858

Detailed Module Info:

{‘available’: 1, ‘status’: {‘data_quality’: 0, ‘device_status’: 3}, ‘version’: u’1.00(0)’, ‘name’: u’Integrated GPS’, ‘position_quality’: {‘vertical_accuracy’: 10.0, ‘time_to_first_fix’: 1000000L, ‘cost’: 1, ‘time_to_next_fix’: 1000000L, ‘horizontal_accuracy’: 10.0, ‘power_consumption’: 3}, ‘technology’: 1, ‘id’: 270526858, ‘capabilities’: 127, ‘location’: 1}

GPS Data:
{‘satellites’: {‘horizontal_dop’: 4.59999990463257, ‘used_satellites’: 6, ‘vertical_dop’: 5.23999977111816, ‘time’: 1217662454.07, ‘satellites’: 9, ‘time_dop’: 4.28999996185303}, ‘position’: {‘latitude’: 9.761066878452, ‘altitude’: NaN, ‘vertical_accuracy’: NaN, ‘longitude’: 76.326954522858, ‘horizontal_accuracy’: 70.6172790527344}, ‘course’: {‘speed’: 0.5, ‘heading’: 242.5, ‘heading_accuracy’: 359.989990234375, ‘speed_accuracy’: 1.11000001430511}}

For more information about positioning module, visit this discussion about the module. This script is only tested on my Nokia N82 handset

One application I am working on is to display the real time GPS position using Google Map. The idea is to retrieve the data at specified interval and send the longitude and latitude information to this site and display it using Google Map API. I will update when it is finished.

Lambda Expressions in C++0x

Lambda expressions are coming to C++. In the next version of C++ standard, C++0x, lambda expressions will be included.

In C++0x a lambda expressions is in the form of [...](…}{…} where

1. [...] indicates it is a lambda expression
2. (…) declares the parameters
3. {…} defines the expressions ie. the code of the lambda expression

example:
// vector to store some integer values
std::vector<int> v;

// Add some values
v.push_back(1);
v.push_back(2);
v.push_back(3);

// print the values
std::for_each(v.begin(); v.end(), [&]( const int& n ) { cout << n << " "; });

int nTotal = 0;

// find the total
std::for_each(v.begin(); v.end(); [&total](int n){ total+=n; });

This document describes the lambda expression proposal. For a detailed explanation visit Herb Sutter's post.

Introduction to OpenMP using Visual C++ 2005

OpenMP is an application programming interface (API) for shared memory multiprocessing programming on multiprocessor/multicore systems. OpenMP consists of a set of compiler directives and a set of support functions. OpenMP works in conjunction with Fortran, C and C++. It is tailored for Shared Memory environments. The Shared Memory model is an abstraction of centralized multiprocessor system consisting of a collection of processors with access to the same shared memory. Processors can interact and synchronize with each other through shared variables.

In shared memory model, the standard model of parallelism is Fork/Join parallelism. In Fork/Join parallelism, there will be only one thread is active at the start and end and is which is called master thread. Master thread executes the sequential portion and at some points where the parallelism is needed, master thread forks (creates or awakens) additional threads. The master thread and child threads executes in parallel through the parallel sections. At the end the created threads die or are suspended. The flow of controls returns to the master threads.

In OpenMP, the directives are expressed as pragmas (pragmatic informations). Following are the compiler directives & functions:

    parallel which preceeds a block to be executed in parallel
    for which preceeds a for block to be executed in parallel
    sections which preceeds section of blocks to be executed in parallel
    critical which preceeds critical section
    single which preceeds block of code that is to be executed by a single thread
      omp_get_num_procs() which returns the number of processors
      omp_get_num_threads() which returns the number of threads
      omp_get_thread_num() which returns the number of thread within group of threads
      omp_set_num_threads() which sets the number of threads for the parallel region

    Visual Studio Professional and above supports OpenMP. The Following program demonstrates a very simple use of OpenMP in Visual C++ 2005.
    #define _USE_MATH_DEFINES // for math defines in math.h

    #include
    #include
    #include

    #define ANGLE_MAX 360

    void main(int argc, char* argv[])
    {
    int nDegree = 0;
    double dSins[ANGLE_MAX];

    #pragma omp parallel for
    for(nDegree=0; nDegree {
    // Initialize the table with sin values
    dSins[nDegree] = sin((double)nDegree * (M_PI / 180.0));
    }
    }

    In order to compile it properly you have the use the /openmp compiler switch. You can set it from Project Properties->Configuration Properties->C/C++->Language:

    Ompoptions 150x150

    For a detailed list of OpenMP directives and support function please refer to this MSDN Documentation. In next few days I will try to update this post with more examples.

    Ubuntu 8.04 LTS Desktop Edition

    Ubuntu 8.04 LTS Desktop Edition is released on Thursday 24 April. You can download it for free from here. Ubuntu 8.04 is nick-named “Hardy Heron”.

    One of the interesting feature is Wubi. Wubi is Ubuntu’s single click installer for Windows. It allows you to install and uninstall Ubuntu just like any other Windows application.

    Other features are GNOME 2.22, GVFS (Virtual File System), new version of PulseAudio and many new GNOME applications. For a complete feature list refer to Ubuntu 8.04 Features.