Question Sendkey

rickydalley

Member
Joined
Aug 28, 2009
Messages
24
Programming Experience
10+
Hi all.

I'm writing an app for work and have created a usercontrol that will pop up an alpha keyboard or a numeric.

It returns a keypress via its KeyPressed event a char and boolean to indicate whether shift was pressed.

That works fine.

My problem now is to "poke" the char onto whatever field has focus - just as if was using an input panel.
The reason I have created this control is because I don't know how to tell an inputpanel to show the 123 numeric.

Searching the net I found SendKeys.Send but in .net compact this doesn't exist.

I have found vague references to doing it with Sendmessage in coredll.dll but haven't seen any example of how to achieve what I want.

Any ideas?

regards, Ricky
 

InertiaM

Well-known member
Joined
Nov 3, 2007
Messages
663
Location
Kent, UK
Programming Experience
10+
The reason I have created this control is because I don't know how to tell an inputpanel to show the 123 numeric.
I cant remember which Imports the following requires, so if it doesnt compile, check the Imports first.

Code:
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports Microsoft.WindowsCE.Forms


    Private Declare Function FindWindow Lib "coredll" (ByVal wndClass As String, ByVal caption As String) As IntPtr
    Private Declare Function GetWindow Lib "coredll" (ByVal hWnd As IntPtr, ByVal nType As Integer) As IntPtr
    Private Declare Function GetPixel Lib "coredll" (ByVal hdc As IntPtr, ByVal nXPos As Integer, ByVal nYPos As Integer) As Integer
    Private Declare Sub SetPixel Lib "coredll" (ByVal hdc As IntPtr, ByVal nXPos As Integer, ByVal nYPos As Integer, ByVal clr As Integer)
    Private Declare Function GetDC Lib "coredll" (ByVal hWnd As IntPtr) As IntPtr
    Private Declare Sub ReleaseDC Lib "coredll" (ByVal hWnd As IntPtr, ByVal hDC As IntPtr)
    Private Declare Function SipSetCurrentIM Lib "coredll" (ByVal clsid As Byte()) As Boolean

    Const WM_LBUTTONDOWN As Integer = 513
    Const WM_LBUTTONUP As Integer = 514
    Const GW_CHILD As Integer = 5


    Public Shared Sub SetSIPNumericPad(Optional ByVal blnShowNumeric As Boolean = True)
        Dim clsidKbdIM As New Guid("{42429667-ae04-11d0-a4f8-00aa00a749b9}")
        SipSetCurrentIM(clsidKbdIM.ToByteArray())

        ' Find the SIP window 
        Dim hWnd As IntPtr = FindWindow("SipWndClass", Nothing)
        ' Go one level below as the actual SIP window is a child 
        hWnd = GetWindow(hWnd, GW_CHILD)
        ' 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 
        Dim hDC As IntPtr = GetDC(hWnd)
        Dim pixel As Integer = GetPixel(hDC, 2, 2)
        ' 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) 
        Dim clrText As Integer = (SystemColors.Window.R) Or (SystemColors.Window.G << 8) Or (SystemColors.Window.B << 16)
        SetPixel(hDC, 2, 2, clrText)
        Dim pixelNew As Integer = GetPixel(hDC, 2, 2)
        ' Restore the original pixel 
        SetPixel(hDC, 2, 2, pixel)

        If pixel = pixelNew OrElse pixel <> pixelNew Then 'orelse added
            ' Simulate stylus click 
            Dim msg As Message = Message.Create(hWnd, WM_LBUTTONDOWN, New IntPtr(1), New IntPtr(589833))
            MessageWindow.SendMessage(msg)
            msg = Message.Create(hWnd, WM_LBUTTONUP, New IntPtr(0), New IntPtr(589833))
            MessageWindow.SendMessage(msg)
        End If
        ' Free resources 
        ReleaseDC(hWnd, hDC)
    End Sub
 

rickydalley

Member
Joined
Aug 28, 2009
Messages
24
Programming Experience
10+
many thanks

That works fantastic.

I also needed to be able to get the alpha keyboard back but I just copied the 1st 2 lines of your SetSIPNumericPad sub into a different sub and it switches it back.

Mind you I don't understand how it works but it does :D

regards, Ricky
 

InertiaM

Well-known member
Joined
Nov 3, 2007
Messages
663
Location
Kent, UK
Programming Experience
10+
To get the alphanumeric version, just use SetSIPNumericPad(False).

It works by checking the colour of the 123 Numeric button on the keypad, and either setting or unsetting the numeric option as required.
 

rickydalley

Member
Joined
Aug 28, 2009
Messages
24
Programming Experience
10+
ummm that won't work

that won't work because the optional boolean parameter blnShowNumeric
doesn't get used in the code.

to make it work I have put this line

Code:
If blnShowNumeric = False Then Return
just after the
Code:
SipSetCurrentIM(clsidKbdIM.ToByteArray())
line at the top of the sub.

regards, Ricky
 

InertiaM

Well-known member
Joined
Nov 3, 2007
Messages
663
Location
Kent, UK
Programming Experience
10+
Sorry, only ever used that code for showing numeric :eek:

Will go and look at the code again for you :)
 
Top Bottom