Programming an Input Panel

When a user accesses the input panel, Windows CE creates a dedicated input panel thread. The thread creates an input panel window and initializes the input panel. Then, the thread enters a message loop. Within the message loop, the thread responds to messages and user interface (UI) requests from the input panel window. The thread also calls into the IM object. This enables the IM to create child windows in the input panel window. The content of the input panel window is determined by the current IM.

The input panel thread has a special status with the OS. Any window that the input panel thread creates will not be obscured by other windows. Because some UI elements save and clear themselves when they lose focus, the input panel and its children do not receive the focus, even if a user is currently using the input panel.

The input panel queries the IM for data through the IInputMethod interface. The input panel can remove the current IM and replace it with a new IM. The following table shows the UI queries that an input panel sends to an IM, listed in the order received.

Method
Description
Deselect Destroys its window and performs IM-specific cleanup procedures
Select Creates the IM window and image list
GetInfo Requests data regarding the new IM, including property flags and the preferred IM size
ReceiveSipInfo Sends the IM data about the size, placement, and docked status that the IM should use
RegisterCallback Provides the IM with a pointer to the IIMCallback interface

After the input panel calls these methods, the IM should render the input panel window space and respond to user actions. For more information about programming the IM, see Programming Input Methods.

An application that uses the input panel should know the input panel state—whether the panel is visible, whether it is docked, or floating, and its size and position. This data is stored in the SIPINFO structure, which is accessed through the SHSipInfo function. The following code example shows how to use the SHSipInfo function to access and modify the SIPINFO structure.

BOOL LowerSip( void )
{
  BOOL fRes = FALSE;
  SIPINFO si;

  memset (&si, 0, sizeof (si));
  si.cbSize = sizeof (si);

  if (SHSipInfo (SPI_GETSIPINFO, 0, &si, 0)) 
  {
    si.fdwFlags &= ~SIPF_ON;
    fRes = SHSipInfo (SPI_SETSIPINFO, 0, &si, 0);
  }

  return fRes;
}

When the user changes the input panel state, the OS sends out a WM_SETTINGCHANGE message to all active applications. This message has SPI_SETSIPINFO in its wParam parameter. The following code example shows how you can use the SHSipInfo function to move the input panel on the screen in response to a WM_SETTINGCHANGE message.

WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    SIPINFO si;

    switch (msg) 
    {
        case WM_SETTINGCHANGE:
            switch (wParam) 
            {
                case SPI_SETSIPINFO:
                    memset (&si, 0, sizeof (si));
                    si.cbSize = sizeof (si);

                    if (SHSipInfo (SPI_GETSIPINFO, 0, &si, 0)) 
                    {
                        MoveWindow (
                  hwnd,
                  si.rcVisibleDesktop.left,
                  si.rcVisibleDesktop.top,
                  si.rcVisibleDesktop.right - si.rcVisibleDesktop.left,
                  si.rcVisibleDesktop.bottom - si.rcVisibleDesktop.top,
                  TRUE);
                    }
                    break;
            }
            break;
    }
  return 0;
}

A change in the active IM sends messages to all top-level applications that are registered to receive IM notifications. Typically, the messages go to an application that controls a display, such as a taskbar. The following table shows the messages.

Event
Windows CE message
Application action
IM size or position changes WM_IM_INFO Return 0 if the application processes the message
IM has a new icon to associate with its current state WM_IM_INFO Return 0 if the application processes the message