views:

66

answers:

6

I have a form with a rich text box control. Is there a way to have caps lock turn on whenever the rich textbox control has focus? And turn it off if the rich text box loses focus? I am using C#

+4  A: 

I would suggest instead capturing the key input and replacing it with the associated uppercase version. Otherwise, imagine a situation where the user clicks in the textbox, switches to another app, realizes Caps Lock is on, throws a brick at their computer out of frustration and then switches back to your app where the cursor is sitting in a textbox expecting uppercase letters but Caps Lock is now off.

John Sheehan
+1 Also it may be obvious, but you can use the KeyDown event to have the text capitalised as you type (or textchanged, but this might create flicker). You could, I suppose, use caps lock but capture the Leave event to turn caps lock off, but I don't favour this.
Christopher Edwards
That's what I meant by capturing the key input. Whatever event works best.
John Sheehan
The only problem with this, is that sometimes the user will actually want to type lowercase letters. 95% of the input should be uppercase, but there is a 5% chance for lowercase.
icemanind
@icemanind: Well you could turn capital letters into lowercase as well.
musicfreak
@John: That is a good argument. Ideally, I'd like to be able to force caps lock on whenever my RichTextBox receives focus, but if it loses focus, including switching to another program entirely, I'd like to restore the state that the CAPS lock was in prior to my RichTextBox receiving focus. So that way the whole caps lock thing becomes almost transparent to the user.
icemanind
I would argue more that you should transform the input after they've moved away from the field, otherwise they're getting an unexpected result. "I'm typing in one case, but it's showing in another, is my Caps Lock key on?" Maybe not a long-term usability issue, but a confusing first experience.
John Sheehan
A: 

Well there are a number of ways to look at this, if you want client-side capitalization then something like the Jquery capitalizer would automatically convert text into uppercase during typing if hooked into, say, the keyup event.

Or if you wanted server side capitalization then you could use C# to String.ToUpper() method in a round-trip.

amelvin
his tag for richtextbox makes me think this is either winforms or WPF
John Sheehan
Sounds likely now you mention it
amelvin
This is for WinForms
icemanind
A: 

I don't think that turning caps lock on is the best solution.. you might be better off subscribing to events like textchanged and converting the input to upper case.

This should cover the case that something was pasted into the box as well..

markt
+1  A: 

You can't do it even with using the Win32 API.

The following code will tell you if the CAPS LOCK is On but the API does not have an equivalent SetKeyState function

[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true, CallingConvention=CallingConvention.Winapi)] 
public static extern short GetKeyState(int keyCode); 

public void getCapsLockState() {
    bool CapsLock = (((ushort) GetKeyState(0x14 /*VK_CAPITAL*/)) & 0xffff) != 0;
}
Lorenzo
A: 

I would use the KeyUp event, get the last character in .Text and use ToUpper(). Simple and efficient.

Ed.C
You're assuming that people never edit what they have already typed.
Douglas
You have a point Douglas. A sure hit would be to use ToUpper for the whole String.
Ed.C
Then there's icemanind's comment above: "95% of the input should be uppercase, but there is a 5% chance for lowercase."
Douglas
+2  A: 

This scenario is usually solved by capturing one of the key events and changing the data. Toggling the CAPS LOCK key isn't optimal because many users would still be using SHIFT (automatically) which would give you lower case letters. Also, it might feel weird to some users (e.g. me). I would suggest KeyPress rather than KeyUp as Ed.C suggested, as it gives you the actual character right there in the event:

public partial class Form1 : Form
{        
    public Form1()
    {
        InitializeComponent();
        richTextBox1.KeyPress += new KeyPressEventHandler(richTextBox1_KeyPress);            
    }

    void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        e.KeyChar = Char.ToUpper(e.KeyChar);            
    }
}
steinar