/* * * Daniel Moth - http://www.danielmoth.com/Blog/ * Credit for the trick goes to Alex Feinman [http://www.alexfeinman.com/download.asp?doc=IMSwitch.zip] * Minor modifications made for non-PPC devices, wrapping in its own class * */ using System; using System.Drawing; using System.Runtime.InteropServices; namespace Microsoft.WindowsCE.Forms { /// /// InputPanel replacement for showing SIP in numeric mode for *WindowsCE devices only* /// For PocketPCs see the original implementation or reverse the changes as described /// here: /// public class InputPanelEx : InputPanel { private const int X = 2; private const int Y = 77; public InputPanelEx():base(){} public void Show(bool isNumeric){ // Show panel if it is not shown yet if ( !this.Enabled ) { this.Enabled = true; System.Windows.Forms.Application.DoEvents(); } // Ensure that keyboard and not some of the other IMs is active // Guid clsidKbdIM = new Guid("{42429667-ae04-11d0-a4f8-00aa00a749b9}"); // SipSetCurrentIM(clsidKbdIM.ToByteArray()); // Find the SIP window IntPtr hWnd = FindWindow("SipWndClass", null); // Go one level below as the actual SIP window is a child hWnd = GetWindow(hWnd, GW_CHILD); // hWnd = GetWindow(hWnd, GW_HWNDPREV); // Obtain its context and get a color sample // The premise here is that the numeric mode is controlled by a virtual button in the top left corner // Whenever the numeric mode is active, the button background will be of COLOR_WINDOW_TEXT IntPtr hDC = GetDC(hWnd); int pixel = GetPixel(hDC, X, Y); // Notice that we cannot simply compare the color to the system color as the system color is 24 bit (or palette) // and the real color is dithered to 15-16 bits for most devices, so white (0xff, 0xff, 0xff) becomes // almost white (oxf8, 0xfc, 0xf8) int clrText = (SystemColors.Window.R) | (SystemColors.Window.G << 8) | (SystemColors.Window.B << 16); SetPixel(hDC, X, Y, clrText); int pixelNew = GetPixel(hDC, X, Y); // Restore the original pixel SetPixel(hDC, X, Y, pixel); if ( ( pixel == pixelNew && isNumeric ) || (pixel==0 && !isNumeric) ){ // Simulate stylus click Message msg = Message.Create(hWnd, WM_LBUTTONDOWN, new IntPtr(1), new IntPtr(0x00490009)); MessageWindow.SendMessage(ref msg); msg = Message.Create(hWnd, WM_LBUTTONUP, new IntPtr(0), new IntPtr(0x00490009)); MessageWindow.SendMessage(ref msg); } // Free resources ReleaseDC(hWnd, hDC); } #region pinvokes [DllImport("coredll")] extern static IntPtr FindWindow(string wndClass, string caption); [DllImport("coredll")] extern static IntPtr GetWindow(IntPtr hWnd, int nType); [DllImport("coredll")] extern static int GetPixel(IntPtr hdc, int nXPos, int nYPos ); [DllImport("coredll")] extern static void SetPixel(IntPtr hdc, int nXPos, int nYPos, int clr); [DllImport("coredll")] extern static IntPtr GetDC(IntPtr hWnd); [DllImport("coredll")] extern static void ReleaseDC(IntPtr hWnd, IntPtr hDC); const int WM_LBUTTONDOWN = 0x0201; const int WM_LBUTTONUP = 0x0202; const int GW_CHILD = 5; #endregion } }