Saturday, November 18, 2006

On-screen Keyboards

Update 18/01/2011 : Check out this code project article if you're interested in an on-screen keyboard implemented in WPF; http://www.codeproject.com/KB/miscctrl/Virtual-WPF.aspx

Recently, I wanted to create an on screen keyboard for use with our POS. Actually, I wanted a full keyboard for our 'kiosk' mode, and either a full keyboard or more likely a numeric keypad for the POS mode when running with a touch screen.

So, how do you create a virtual, on screen keyboard ? Creating a form/usercontrol with buttons or some other control(s) on it to represent the keyboard is relatively simple. What's difficult is knowing where to send the key data when the control is clicked, because when you click on the virtual keyboard it tends to get focus, taking it away from the input field that needs the data.

Googling the problem I found several samples that simply raised an event from the on screen keyboard form/control, but that still leaves you with the issue of passing on the key data to some unknown edit field. Most of these samples assumed the keyboard control was either on the same form as the field receiving the key data, or that a reference to the control could be provided, which is fine if you only want to deal with forms within your own application, but sucks otherwise.

A few other samples worked by using API's to obtain the handle of the control that currently has focus before the keyboard form/control is activated. When the buttons on the virtual keyboard are clicked, the key data is sent to the 'remembered' window handle and then the original window is refocused using API's, or the window is refocused first and then SendKeys is used. This doesn't work very well though. If the virtual keyboard window overlaps the client window then you get 'flickering' as the focus changes between the windows. Also it seems some key data just gets 'lost' if you hit buttons on the virtual keyboard quickly, although I'm not sure why.

In the end, thanks to two http://www.codeproject.com/ articles and another Google search, as well as some trial and error on my part, I managed to find the 3 magic things you must do to make an on screen keyboard work. These are;

  1. Show your virtual keyboard form without 'activation', so it doesn't get focus when the keyboard is shown.
  2. Intercept the WM_MOUSEACTIVATE message and return MA_NOACTIVATE as the result.
  3. Most important of all - you must NOT use controls that can get focus to represent your buttons.
The third point is the one that I missed for quite a while. Say you place a button control on your form for every 'key' on the virtual keyboard. You've overridden the WM_MOUSEACTIVATE event so clicking on the form won't activate it - but you haven't overridden the individual button control's so they can still get focus, and when they do they will cause the parent form to be activated as well. If you use a label, picture box or some other control that can't get focus though, then the form won't get activated even when the control is clicked - which means you're free to use SendKeys to pass on the keystrokes. This works exceedingly well, there is no flickering, and none of the keystrokes seem to get lost. Best yet, the code is relatively simple.
So, how exactly do you build the virtual keyboard ?
I recommend you grab a copy of FoxholeWilly's keyboard control from CodeProject at http://www.codeproject.com/cs/miscctrl/touchscreenkeyboard.asp
This gives you a nice looking, resizable, keyboard. It also supports both alphabetical and QWERTY layouts, as well as a 'kids' version. It doesn't have the Numeric Keypad like I wanted, but with a little image editing and some tweaking of the code it's easy enough to add.
Unfortunately, this control doesn't take care of points 1 and 2 from before, or actually pass on the key data for you. To do this, place the control on a host form and connect the control's
UserKeyPressed event to an event handler. In that event handler place the following line of code;
SendKeys.Send(e.KeyboardKeyPressed);
Because FoxholeWilly's control already provides a SendKeys formatted string as an event argument, that's the only line of code needed to pass on the key data.
Now, to prevent the form receiving focus or being activated when it's shown, simply override the CreateParams property on the host form, like this;
private const int WS_EX_NOACTIVATE = 0x08000000;

protected override CreateParams CreateParams
{
get
{
CreateParams createParams = base.CreateParams;
createParams.ExStyle = createParams.ExStyle | WS_EX_NOACTIVATE;
return createParams;
}
}
Finally, you need to prevent the form getting focus or being activated when it or the keyboard control are clicked on. This is as easy as adding the following code to the host form;
private const int WM_MOUSEACTIVATE = 0x0021;
private const int MA_NOACTIVATE = 0x0003;
protected override void WndProc(ref Message m)
{
//If we're being activated because the mouse clicked on us...if (m.Msg == WM_MOUSEACTIVATE)
{
//Then refuse to be activated, but allow the click event to pass through (don't use MA_NOACTIVATEEAT)
m.Result = (IntPtr)MA_NOACTIVATE;
}
else
base.WndProc(ref m);
}
This code actually came from a comment posted by Dirk Moshage, on Randy More's CodeProject article (http://www.codeproject.com/samples/onscreenkeyboard.asp) about creating an on screen keyboard. However, because Randy's keyboard project uses button controls to represent the buttons on screen, most people found the above code didn't work properly because the child windows (buttons) still got activated, and then activated the parent anyway. In our case, neither FoxholeWilly's keyboard control or the picturebox it uses to show the keyboard can get focus, which means the WM_MOUSEACTIVATE code actually works the way it's intended.
That's all there is to it. Once you have your host form and control configured, you can run the project. Simply put keyboard focus in any control on any window, and use the mouse (or your touch screen) to click on your virtual keyboard. As you click each virtual button, the appropriate key stroke is sent to the control that currently has focus, and the focus remains where it is.
Of course there's a lot more you can do to improve your keyboard, such as adding a sound when keys are clicked on or implementing 'type rate' so keystrokes are sent repeatedly while the mouse button is held down over a particular key. For a basic keyboard though, you should have all you need.

65 comments:

  1. I found today this post. THANKSSSSSS. You are saving my life ;)

    ReplyDelete
  2. No problem... glad it helped. I get so few readers I've been thinking of tearing the blog down, but if it actually helped someone, maybe I'll keep it.

    Thanks for the comment.

    ReplyDelete
    Replies
    1. So glad its still here after all these years! This is exactly what I've been looking for!

      Delete
  3. Thank you very much for this information! I was about to make a numeric keypad for the company I work for and you saved me lots of trouble.

    ReplyDelete
  4. Your very welcome, I'm glad it helped !

    ReplyDelete
  5. Thank you very much Sir. It is very helpful for my POS application.

    Thanks a lot...

    :)

    by
    Pavan kumar.

    ReplyDelete
  6. Great Post! This was just the solution that I needed for a kiosk project I am working on. Thanks for taking the time to post this solution and for keeping the blog up. Thanks also for linking to FoxholeWilly's post, his keyboard gave my project the finished look I needed.

    ReplyDelete
  7. Thanks for the comment, it's always nice to know when you've helped somebody.

    ReplyDelete
  8. This seems to be my most popular page :) Glad to know it's helped someone else !

    ReplyDelete
  9. This is great help, but not sure how to do this using WPF? I have a WPF keyboard and want to make it do the same thing as your Forms keyboard. There is no 'CreateParams' in WPF... ideas??

    ReplyDelete
  10. This is a great post and has helped me understand some of the mechanic's behind creating a on screen Keyboard. The problem I am having is that the on screen keyboard that I created is made using WPF. How do you set the WS_EX_NOACTIVATE flag on an WPF window? Ideas?? Thanks in advance!

    ReplyDelete
  11. Hi Oregon Ted,

    That's an interesting point. Unfortunately I haven't done a lot of work in WPF and so I don't know the answer, but I'll do some research and if I figure it out I'll let you know.

    ReplyDelete
  12. Hi Oregon Ted,

    Try this link;

    http://rhizohm.net/irhetoric/blog/9/default.aspx

    It has information on how to show a WPF window without it 'activating'.

    ReplyDelete
  13. This is a great post and it saved me a lot of time. Here is the equivalent for use in VB.NET.

    Thank you so much....

    Private Const WS_EX_NOACTIVATE As Integer = &H8000000

    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
    Get
    'Dim SecPerm As New SecurityPermission(SecurityPermissionFlag.UnmanagedCode)
    'SecPerm.Demand()

    ' Extend the CreateParams property of the Button class.
    Dim cp As System.Windows.Forms.CreateParams = MyBase.CreateParams
    cp.ExStyle = cp.ExStyle Or WS_EX_NOACTIVATE ' BS_ICON value

    Return cp
    End Get
    End Property

    Private Const WM_MOUSEACTIVATE As Integer = &H21
    Private Const MA_NOACTIVATE As Integer = &H3
    Dim maNoactivate As IntPtr = New IntPtr(MA_NOACTIVATE)

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    If (m.Msg = WM_MOUSEACTIVATE) Then
    m.Result = maNoactivate
    Else
    MyBase.WndProc(m)
    End If

    End Sub

    ReplyDelete
    Replies
    1. This is brilliant, thank you for producing the VB.NET version, I have been looking for this for a long time. I have copied this into my NumericKeypad Class and it works perfectly. Once again, many thanks.

      Delete
  14. Thanks for that Jeremey, and I'm glad the post helped you out.

    ReplyDelete
  15. Good afternoon Yort,

    I need a Numerical Keypad on a touch screen exactly like you needed. I have spent a few hours fooling around with the c# source but cannot have it to work. Any chance you would have such a keyboard you would be willing to share the source ?

    ReplyDelete
  16. Hi Jean-Pierre,

    At the moment the code I have is woven into the device struture for the POS system I work on (since that's the only place we needed it), and has some unnecessary code from your point of view. I could try to seperate it and post a working version, but it might be quicker to help you with your problem(s).

    Where exactly are you getting stuck ?

    ReplyDelete
  17. Thanx Yort,
    I hadn't notice an error in my source. I copiedfor lines from the article but there is an error in the line "createParams.ExStyle = createParams.ExStyle WS_EX_NOACTIVATE;"; an equal sign is missing. It should read "createParams.ExStyle = createParams.ExStyle = WS_EX_NOACTIVATE;"
    Now my problem is that it refuse to runs on Windows XP imbedded on a thin client because it only has framework 1.1 and can't compile lower then 2.0
    I need an XP machine in order to compile.
    Thanx again
    J.P.

    ReplyDelete
  18. Hi Jean-Pierre,

    Thanks for that... I believe the missing character is actually an & (must have been stripped out by the posting tool) as the code is supposed to be setting a particular bit in the ExStyle property value. I have updated the post now.

    It's a shame you're having problems with Windows XP Embedded. I believe it is possible to build your own image that contains .Net 2.0 using (Win XP Embedded) Platform builder, but I'm not very familiar with doing so and I don't know if you're building your own images or using one provided by your IHV.

    Good luck.

    ReplyDelete
  19. thanx very much for your contribution article.
    i am trying to do a software component wich shows up a touch screen keyboard.
    i would like to iterate all keys in the currently attached(configured) keyboard, but all solutions i found on this site and on the internet use fixed layouts or a renge of fixed layouts
    i would like to know wich keys-keycodes are available on the current locale keyboard.
    could you adress me to some point ?

    thank you

    ReplyDelete
  20. Hi Yort,
    sure that,You don't know me and I also don't know you. But today your discussion about On-screen keyboards is very useful for me.
    Thank you very very much!!!

    ReplyDelete
  21. Dear Yort,
    My name is Hien - vietnamese
    I'm coding on-screen keyboard.
    My keyboard have TopMost's property is true.
    when program show new modal dialog.
    I can't click on my keyboard.
    How to click on key button when program is showing different dialog.
    Plz help me!!! Thank for your read.

    ReplyDelete
  22. Dear Yort,
    My name is sugia-vietnamese
    I'm coding on-screen keyboard.
    My keyboard have TopMost's property is true.
    When i show new modal dialog.
    I can't click on my keyboard.
    How to click on key of my keyboard when program is showing modal dialog.
    Plz help me!!!

    ReplyDelete
  23. Hi Hien,

    Unfortunately, what you describe makes sense. A 'modal' dialog prevents accesing any other windows in the same process, so you won't be able to use the keyboard.

    The only solutions I know of are;

    1. Do not use a modal dialog.

    2. Put your keyboard in a seperate exe/application, so it can still be accessed while the rest of your application is showing a modal dialog.

    ReplyDelete
  24. Hi,

    Unfortunately I do not know how to detect which keys are available on the current keyboard. There may be something in the Win32 API to do with locale, but possibly not.

    If you can figure out which keys exist, then it should be simple enough to just draw the keys using GDI instructions (DrawRectable or FillRectangle of the Graphics class will help here), and then the mouse handling is just a matter of catching the click event and checking where the pointer was on screen when the button was pressed. When you draw your buttons, keep a track of the location and size of each one, and then when you get a click you can enumerate them all until you find one that 'contains' the point where the mouse was clicked.

    ReplyDelete
  25. Hi! After reading your post you made me wonder how the Label is set to not receive focus. I dug into Reflector and found that I could create my own Button control with the only difference being that in the constructor I call:

    this.SetStyle(ControlStyles.Selectable, false);

    That prevents the button from receiving focus. I was then able to create my keyboard using real buttons, which presented a much better user response than clicking an image. I hope this helps!

    ReplyDelete
  26. Hi Mark,

    Thanks for your comment. Yes, any non-focusable control will do, and you can build your own using the (protected) SetStyle method of a control.

    An excellent tip, thanks.

    ReplyDelete
  27. Hi Yort thanks for the great info.

    I followed all your instrutions to a T and everything seems to have went well till I actually tried to use the keyboard.

    For some reason the only keys that do work are the caps lock and the shift keys.

    Any ideas?

    ReplyDelete
  28. Hi,

    I'm sorry you're having trouble, but that's not a symptom I've seen or that I can think of a cause for. Perhaps if I could see your code I could help more.

    Have you had any luck trying to debug the code with a debugger ? What actually gets executed and what is the result ?

    ReplyDelete
  29. Hello, Yort.
    Right niw i'm doing a reseach on developing self serving kiosks applications.
    What happens if a windows(system) message appears or a ballon appears(usually as an informational massage). In this case does the mane app in kiosk mode stay on top, or the end user will be able to see the windows message and interract with it?
    And if u had such issues please give me a clue how to intercept such messages and process them via my application.

    ReplyDelete
  30. Hi,

    I'm not familiar with IE or Windows' kiosk mode so I can't really comment. My guess would be that if a system dialog or balloon was shown then yes it would appear over your UI, although the on screen keyboard in this article should allow you to click ok using the on screen enter key or keyboard.

    I also assume that Windows and IE would raise fewer of these types of messages and dialogs when in kiosk mode, but like I said I've never used kiosk mode so I don't really know.

    ReplyDelete
  31. Hi Yort,

    i have a client who just bought a multi-touch (Surface style) computer. He wants to be able to have multiple on screen keyboards open at the same time, and have each keyboard associated with a program. Of course, there will be conflicts with the focusing. Is there any way to implement on screen keyboards (or manipulate existing open source ones) that direct input to specific windows instead of the one with focus?

    Please help...

    Thanks,
    ZiggY.

    ReplyDelete
  32. Hi Yort,

    i have a client who just bought a multi-touch (Surface style) computer. He wants to be able to have multiple on screen keyboards open at the same time, and have each keyboard associated with a program. Of course, there will be conflicts with the focusing. Is there any way to implement on screen keyboards (or manipulate existing open source ones) that direct input to specific windows instead of the one with focus?

    Please help...

    Thanks,
    ZiggY.

    ReplyDelete
  33. Hi,

    I haven't tried to do this myself, but it *should* be possible.

    What you'd want to do is have some way of linking each keyboard to an application, perhaps finding the application window handle via it's title bar caption (there are win32 api's to do that).

    Once you have the hwnd of the window stored inside the keyboard, it's just a matter of using sendmessage to send keystroke messages to that window handle instead of using sendkeys etc.

    The actual code for finding the windows by title bar text (if that's what you choose to do) and sending them key strokes shouldn't be that hard to do. What you need to figure out is a configuration mechanism that lets you start multiple keyboards, associate each keyboard with an application some how, and positions the keyboards in the right places on screen etc.

    A config file that has a list of applications with their title bar text would probably work ok - just create a keyboard for each one and pass it the configured text.

    Could get messy though if the title bar text is not consistent or there are multiple copies of the same application open at once.

    Good luck !

    ReplyDelete
  34. Dear Yort,

    Thanks a lot dear, it saves my time to develop a keyboard.

    have a happy & healthy life ahead.

    Laxman Singh

    ReplyDelete
  35. Just less than perfection, the VB code is a little bit slow.

    ReplyDelete
  36. Hi Anonymous,

    Sorry you're having a performance problem. Not sure why it would be any different in VB.Net than C# since it's the the same framework/api calls etc. under the hood.

    Specifically which bit is slow, and what VB code are you referring to (my samples are all C# and I haven't written any VB that I'm aware of). The VB code posted by Jeremey in the previous comments doesn't look like it should cause any significant performance hit.

    ReplyDelete
  37. Hello!
    Thats a fabulous keyboard,Kudos!
    Well,i edited some parts in the demo keyboard,where i put animation effect of sliding when opening or closing the keyboard,and its working fine.
    The problem i am facing is in removing the border of the keyboard(border and title bar), i have tried removing it by making the FormBorderStyle to None(of Form1 in demo keyboard),but still the border appears!
    Am using Windows XP and Visual Studio 2005.
    Can you please help me out! Thanks in advance. :)

    ReplyDelete
  38. Hi,

    Setting the form border style to none should do it, but also try the following;

    1. Remove the title text for the form.
    2. Set the properties for min/max buttons and the 'controlbox' to false.

    I think if you do that and set the form border style to none, there should be no 'chrome' at all for the window.

    ReplyDelete
  39. This is great help. It saved my job and therefore my life!
    Thanks!

    ReplyDelete
  40. Hi Yort,
    Great post! I followed the steps and was able to send key from a on-screen keyboard to a notepad!

    I noticed that the notepad then was always on top of and cover up the keyboard.

    Since I have to run my program on a small screen, I need the keyboard to be on top of the notepad so that I can press the key (just like the on-screen keyboard of an ipad). Is there a way to do that? I really appreciate your times and helps.

    Thanks,
    Chi

    ReplyDelete
  41. Hi Chi,

    Thanks for the comment, I'm glad the post helped you.

    If you're working in WinForms (2.0 or later) then the form the keyboard is on should have a property called 'TopMost'.

    Simply set that to true in either the designer, or the constructor of your form, and that window should stay on top of other windows.

    If you're in WPF then I'm not sure of the exact method to do this, but there should be a way (probably a similar mechnaism, perhaps just a property with a different name). A Google search should help figure it out.

    - Yort

    ReplyDelete
  42. Hi Yort,
    Thanks again for the tip. I'm so new to vb .net (3 weeks learning till now). That's why I need helps from the professional like you. Thanks!

    One more question if you don't mind. Since I have to use touch screen for all applications, my notepad has all buttons laid at the bottom instead of using menu strip. How can I make the notepad back to the top when I need to use its buttons to save, exit etc (since now those buttons covered by the keyboard)? I also set the notepad to topmost, but it wasn't back to topmost when I click on it.

    Thanks for all your helps, Yort.

    Chi

    ReplyDelete
  43. Hi Chi,

    You could try setting TopMost to true on the notepad too, and calling the BringToFront method on the window inside it's Activate event, that might work but I'm not sure.

    What I really suggest you do is revisit your design. Perhaps the notepad should be docked to the top two thirds of the screen and the keyboard shown at the bottom third (like most modern smart phones do), and the user can't move them, that whay they never overlap. Or alternatively, you could put a button on the keyboard to hide it, and then show it whenever the notepad edit field gets focus, and/or put a button on the notepad to show the keyboard too.

    ReplyDelete
  44. Hi Yort,
    Thanks for the great tips. I'm doing the hide and show like you suggested. That should do it. Thanks for all your helps.
    Chi

    ReplyDelete
  45. Glad I could help, good luck with your project.

    ReplyDelete
  46. Hi Yort,
    Great post! My on-screen keyboard now works with any active input file! However, when I test the keyboard by itself without clicked to focus on an active window (e.g. notepad), pressing the "Carriage Enter" or "Space" then makes the keyboard hang (problem doesn't exist with other keys though. I use sendkeys.SendWait to send a key.) Have you seen this kind of problem? Any idea to make the keyboard not to hang? Please help. Thanks a lot.

    Bon

    ReplyDelete
  47. Hi Bon,

    That is an odd symptom, no I haven't seen it before and nor do I have any idea how to fix it.

    My only suggestion would be to try using the Send method of SendKeys rather than SendWait. I haven't found SendWait to be necessary myself, and you should get better performance using just Send.

    ReplyDelete
  48. Hi Yort,
    Thanks a lot for your response and suggestion. I did try the send method too, but the key is still blinking and make the keyboard hang. I put these two keys in the try catch block but doesn't work since they are valid key codes. I only hope that my boss doesn't find out this deadly bug or I'll be in very big trouble since I don't know how to fix it :( He told me not to use sendkeys at the beginning, but I told him that sendkeys is the way to go for an on-screen keyboard...
    Thanks again for your helps.
    Bon

    ReplyDelete
  49. SendKeys is often used in situations where it really shouldn't be, so I can understand why your boss wants to avoid it, but all it really does is post window messages to a given window saying a key was pressed. For an on screen keyboard, that's exactly what you want it to do.

    I really don't understand why the enter key would be causing an issue though. I haven't seen that on any of my own systems.

    Do you perhaps have some code (or a button a 'default button') on the keyboard window that handles enter ? If that was the case then you might be sending enter to yourself, which might then act as if enter was pressed again, which would call sendkeys again and put you into a sort of recursive loop with no end. That's really the only issue I can think of.

    ReplyDelete
  50. Hi Yort,
    Thanks for your helps. I believe I send the "Carriage Enter" and "Space" keys the same as I send other keys. But I will look into more as your suggestion if I've done anything odd.

    In my notepad program, I set the focus on it (using txtNotepad.focus()), but when I launch the keyboard, the focus is taken away from the notepad and put on the keyboard instead, and then the problem begins when I send one of the two keys above. Could you tell me how to set the focus always on the Notepad even after launching the keyboard so that the notepad is always the active window, therefore the keys can always send to the notepad?

    I really appreciate your times helping me. Thanks.
    Bon

    ReplyDelete
  51. That's really weird, Bon. If you've followed the instructions in my article your keyboard shouldn't be getting focus ever.

    You intercept the wm_mouseactivate message to prevent the keyboard getting focus when clicked, and you either set the ShowWithoutActivation property to false in the keyboard form's constructor or override CreateParams property and return a value including the WS_EX_NOACTIVATE bit as shown in my post.

    You also need to make sure whatever control you are using for buttons is NOT focusable, i.e use a label.

    Have you done these things ?

    If you have, then the form should NOT get focus either when shown, or when clicked.

    ReplyDelete
  52. Yes, you're right. My bad. I should state it clearly. I meant neither the Notepad nor Keyboard got focus. The way I did is I launch the keyboard inside the notepad Load function (It's part of the requirement to launch both applications together). So I saw the notepad was up first with cursor blinking in text field. Then when the keyboard came up, the cursor on text field was disappeard and the notepad wasn't focused anymore (the keyboard isn't focus either), until I clicked on the notepad to make it active again.

    If I don't click on the notepad to make it active window, sending the "return" or "space" keys from keyboard will make the keyboard hang.

    So may be when I run the notepad, I need to bring up the keyboard first before launching the notepad. I set to load the keyboard at the first line of the notepad Load function, but the notepad still gets loaded first before the keyboard.

    Inside the Notepad program, how do I bring up the keyboard first before bringing up the notepad?

    Thanks,
    Bon

    ReplyDelete
  53. Hi Bon,

    I'm sorry, but I'm really confused and unsure how to help you. If the keyboard isn't getting focus (and it shouldn't be), then the notepad should remain focused (the keyboard cursor should remain in the notepad text field, blinking). I don't know why that isn't working for you.

    I doubt just trying to launch the keyboard first is a good plan, but if it works I guess it could at least be a short term solution for you. I'm not sure how you're launching the two windows, you make it sound like they are seperate applications that you are starting using System.Diagnostics.Process.Start. If that's the case you could try calling WaitForInputIdle on the Process object returned by the start method, before starting the notepad. I'm not sure if that will work, but it's the only thing I can think of short of writing code to check for the notepad window and looping until it turns up (and that will be very ugly to do, and not a good plan).

    ReplyDelete
  54. Hi Yort,
    I really appreciate your helps. I use the process.start to start up the keyboard appl inside the notepad appl. I gonna try out your suggestion.
    Thanks again for your times and helps.
    Bon

    ReplyDelete
  55. Hi Yort,

    I am following exactly the same method as you specified for my windows form application. I have my Keyboard in a host form. And I am using notepad to give input to. But the problem is I am getting focus to keyboard form while pressing keys. I am unable to give input to notepad for any key. I am using http://www.codeproject.com/KB/miscctrl/touchscreenkeyboard.aspx

    Waiting for your reply, thank you.

    ReplyDelete
  56. Hi Arjit,

    To prevent the keyboard getting focus when clicked, the two key points are;

    1. Override the forms wndproc event and ignore the WM_MouseActivate message (as shown in the article).

    2. DO NOT use a control that can receive focus for the keyboard or indivudal buttons on the keyboard. For example, you can't use a normal .Net button control to represent a keyboard button, because when it's clicked it will receive focus which will also cause the form to become focused. Instead, use a label, picturebox or other control that can never receive keyboard focus.

    Can you confirm you've followed that advice ? If you have, then I have no idea why it would not work. Which OS are you using ?

    ReplyDelete
  57. Hi Anonymous,

    That control does look very cool, especially if you are looking for a Metro styled keyboard.

    ReplyDelete
  58. Change the '&' for a '|' in
    createParams.ExStyle = createParams.ExStyle & WS_EX_NOACTIVATE;

    and everything will go smooth...

    Great Solution indeed, Thanks!

    ReplyDelete
  59. Thanks for pointing that out, Nino !

    ReplyDelete
  60. Foxholewilly says: Thanks for the props. I just ran across your blog post from a google search. The keyboard was back when I first started learning C#. I was asked to create a touchscreen display by my company as an in-kind donation to a local museum. A few weeks before this, a coworker suggested that C# would be a good language to learn. Prior to this I worked with Oracle Forms development. Anyway, when my supervisor asked me to do this, she handed me some documentation on some horrible touch-screen development software that looked like it was designed for non developers to make office building "which cube is Bob in" type stuff. It was like limiting a web developer to using Myspace to build web pages.

    Anyway, without telling her I never even touched C# before or knew anything about it, I suggested that C# would be a much better tool to develop the application. One of the things I needed was a keyboard, I couldn't find any decent examples, so I made my own and stuck it on CodeProject since that was a source of much needed help at the time. Just a side note, I did make a numeric keypad version of this for my kiosk.

    ReplyDelete