I have a Silverlight application in which I catch certain key presses such as Tab or Ctrl to perform some action. However, I want to be able to handle multiple keys pressed at the same time such as Ctrl + R or something like that. Is there any way to do that in Silverlight, and if so, how?
Take a look at the ModifierKeys Enumeration to check for multiple key press combinations. See Silverlight Keyboard Support for code samples and more information.
void Canvas_KeyUp(object sender, KeyEventArgs e)
{
//check for the specific 'v' key, then check modifiers
if (e.Key==Key.V) {
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) {
//specific Ctrl+V action here
}
} // else ignore the keystroke
}
Handling key combinations like Cntrl+X is very problematic with Silverlight as your running in a browser which will, probably, use most Cntrl combinations itself. Then given that you probably need to support multiple browsers such as IE, Firefox, etc I recommend you give up.
Hence I limit Silverlight key combinations to shift only.
Related
I am trying to page up/down the contents of a simple textbox control in a simple Windows Form on NET 6.0, but something is wrong. Textbox shortcuts are enabled (probably why SendKeys.SendWait("^a"); works) and readonly is false.
I have a method (not on the UI thread) that I call to SendKeys.SendWait("{PgUp}"); to the foreground app (which is both the key sender and textbox (with focus) receiver.
If I type PgUp on the keyboard, the textbox pages up as expected.
If I SendKeys.SendWait("^a");, the textbox selects all text as expected.
If I Sendkeys.SendWait("{PgUp}");, the textbox adds a blank line to the bottom of the text.
From this I conclude that my code is working because it sends "^a" and the textbox receives it and selects all text. But somehow the textbox does not handle the "{PgUp}" key, even though it does when the PgUp key is sent by the keyboard.
I've read easily a dozen articles and posts on the web and SO that talk about paging using scrolling events, positioning the caret and then scrolling to the caret, and so on. But none of them say anything about why SendKeys(^a) and keyboard PgUp would work but SendKeys.SendWait("{PgUp}") would fail.
Can anyone tell me what I'm doing wrong and maybe what I need to do (or read) to fix it? Thank you
UPDATE: Jimi asked for some code, so here is the code that I use to send the ^a and the {PgUp} keys. I know this is not on the UI thread because it is executed from a voice-driven recognizer thread. The app is a voice-driven app that displays content in the textbox by textbox.AppendLines calls. I was trying to PgUp and PgDn the multi-line textbox by voice as well.
When I tried to use Send (I normally use .SendWait for everything in other programs), I received the following error message:
System.InvalidOperationException: 'SendKeys cannot run inside this
application because the application is not handling Windows messages.
Either change the application to handle messages, or use the
SendKeys.SendWait method.'
It is true that my app does not intercept Windows messages. I can't figure out why the app can receive and properly process my keyboard keys, and my "^a' shortcut keys, but not the SendWait("{PgUp}") key.
internal static void
HelperPageUp() {
var keys = "{PgUp}";
keys = "^a";
SendKeys.SendWait(keys);
}
I'm starting to think that {PgUp} is never handled by a textbox or control. Instead, probably {PgUp} must be handled by logic in a case statement that converts PgUp "orders" into sets of actions that implement whatever PgUp means to the app that receives the PgUp key. So maybe I will have to add a keystroke handler to the form. Maybe something like this:
textBox1_KeyUp(object sender, KeyEventArgs e) {
// identify the special key and implement what it means
if (e.KeyCode == Keys.PageDown) {
...
e.Handled = true;
}
Yes, my thought at the end of the question was correct. The ^a was handled by the textbox because I had textbox.EnableShortcuts=true;, so the textbox handled the popular ^a shortcut. But keys like {PgUp} are a different matter; they are not included in shortcuts.
The solution was to write code to handle the {PgUp} key explicitly in the form. Here is my code that worked.
void
textBox1_KeyUp(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.PageUp) {
// page the viewport up; watch for end of content
var charIndex = textBox1.SelectionStart;
var lineIndex = textBox1.GetLineFromCharIndex(charIndex);
// move 20 lines up, but not past zero
var newLine = lineIndex - 20;
var newIndex = Math.Max(0, newLine);
// set the new anchor and scroll to it
var newAnchor = textBox1.GetFirstCharIndexFromLine(newIndex);
textBox1.Select(newAnchor,0);
textBox1.ScrollToCaret();
e.Handled = true;
}
I would like to be able to allow users of my application to press Ctrl+Shift+numeric keypad keys to act as a navigational shortcut in an application I am developing. To my surprise it appears to be impossible to recognise this key combination.
Pressing Shift+keypad activates the extended functions displayed on most keyboards, such as cursor keys (on 2, 4, 6 and 8), page down/up (on 3 and 9), end/home (on 1 and 7), etc.
The various key events in WinForms report these exactly as if they were the actual cursor keys etc. being pressed. I'm therefore unable to distinguish between e.g. Shift+KeyPad4 and CursorLeft. I can't simply look for Ctrl+CursorLeft instead of Ctrl+Shift+KeyPad4, as people may be using Ctrl+CursorLeft for text editing purposes.
Is there any way I can properly detect these shifted numeric keypad keyboard combinations?
Thanks!
Use a class to keep track of what keys are pressed.
When you receive an OnKeyDown event, store that key as down and then when you come to When you receive an OnKeyUp event, remove that key from the store.
Then on the same OnKeyDown event, after storing the key press, do a check to see if all three keys that you expect are down.
It would look something like so:
public void OnKeyDown(EventArgs ...) {
_keyStore.KeyDown(eventArgs.keyPress);
if(_keyStore.AltCtrlKeyPad4IsDown()) { //Abstract this so you can perform multiple checks.
//Do shortcut.
}
}
public void OnKeyUp(EventArgs ...) {
_keyStore.KeyUp(eventArgs.keyPress);
}
Note that this is sudo code and will not compile.
I am Working with C# and Windows Forms and want to use Ctrl+"Oemplus" as a function key for my application. I use a German keyboard and this key is located 2 keys right of the letter P (that ist then "+"). Whenever I press this key in combination with Ctrl and the focus is on a TextBox I get a beep.
This also happens when I switch to an US keyboard layout (still using my German keyboard). This is then the ] key.
The same happens when pressing this key while in Internet Explorers address bar.
My question is:
Why does this key combination produce a beep in a TextBox.
How can I avoid the beep?
Thanks for any efforts you put on this.
Update:
I tried it on an US/Thai keyboard and get the beep as well. This happens no matter what logical keyboard layout I use (German, US, Thai).
The beep also happens in Windows Explorer in the address bar but not in the search box.
It is very unclear what you hope to happen when you press that keystroke. TextBox leaves no doubt about it, it BEEPs! because it can see that the user is trying to do something special but it doesn't know exactly what. Good reason to beep you. Solution is to implement magic, in the //.. comment in this next snippet. With the extra code to stop the beep at the end:
private void textBox1_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyData == (Keys.Control | Keys.Oemplus)) {
// Invoke magic
//...
// Magic is done now:
e.Handled = e.SuppressKeyPress = true;
}
}
What I believe is happening is that the key combination is not allowed for the Textbox, therefore you are getting the error. You can test for the Key Combination by this code( using the right bracket key in EN Windows) it is using SuppressKeyPress to prevent the Key Combination from being passed to the underlying control to prevent the beep.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (ModifierKeys == Keys.Control)
if (e.KeyValue == 221) // You may need to determine this value for your keyboard layout.
{
textBox1.Text += " + "; // Handle the Key combination.
e.SuppressKeyPress = true; // Prevents key from being passed to underlying control
}
}
After some time I came back on this. What I found unsatisfying with the previous solution was that every TextBox would need that handling for every 'beeping' key I use for something else. Sure I could subclass the TextBox but still I would have two places to change for every key with this behavior (the handling and the beep suppression).
Actually I use Ctrl+'+' as a command key. I did this with a global keyboard hook because the action should be available on and impact all forms.
Instead I handle this now in a base form using the following code:
// Avoid beep on Ctrl+'+' in TextBox.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
Keys key = keyData & Keys.KeyCode;
bool alt = keyData.HasFlag(Keys.Alt);
bool shift = keyData.HasFlag(Keys.Shift);
bool control = keyData.HasFlag(Keys.Control);
if (key == Keys.Oemplus && !shift && control && !alt)
{
// Perform the action for Ctrl+'+'
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
For me this seems the "correct" Position and way to handle a command key. The beep is gone without any additional handling and I don't have to worry if additional command keys produce a beep or not.
When the form had a menu or toolbar this would be handled automatically by the shortcut defined for the menu item. But my forms don't have a menu or toolbar.
I'm making my own multiple clipboard copy/paste tool which runs in background, and I've finally achieved it, it's working.
this is how it works,
when Capslock it's pressed, if I press CTRL+1 I make a CTRL+C programmatically ( with SendKeys) and save the clipboard on my list with correct position
when capslock it's not pressed, if I press CTRL+1 I make a CTRL+V programmatically ( with send keys) by using the latest data in clipboard on the correct list position.
Now it's fine, but I want to make a little change, I don't want to use capslock, but I want to press another key, like ALT or SHIFT, but if you keep pressing a key which is not the CTRL and then you do a CTRL+C, it does not work.
Anyone have any advice to this dumb thing?
Thanks guy
If you don't mind using WinApi functions, you can use RegisterHotKey and UnregisterHotKey functions.
They allow you to register and unregister global shortcuts of your choice. This way you'll get notified about a shortcut being pressed even if your application is running in background and doesn't have the focus on itself.
You can find more information about both functions on pinvoke here and here. There is even some sample application code so you can see how to use them.
NOTE: Remember to unregister all the shortcuts that you've registered on application exit.
You can use a flag for the select key. When you check to see what keys are pressed then:
something like the following pseudo code should do the trick:
if(select key)
{
this.selectKey = true;
}
else
{
if(ctrl key)
{
//do whatever you would normally do here
}
this.selectKey = false;
}
I have found a few textboxes here and there in my program that accepts Control+A shortcut to select the entire text "by default" with "no coding".
I don't know what additional information I have to give here to enable it for all of them, as I find absolutely no difference between these textboxes. They are all simple dragged and dropped textboxes.
Note: I'm not talking about this piece of code:
if (e.Control && e.KeyCode == Keys.A)
{
textBox1.SelectAll();
}
I want selection by default... or is there anyway to change textbox property so that textboxes accept all default windows shortcuts?
Everything else (Control + Z, Control + X, Control + C, Control + V) works by default! Why not Control + A?
Update: The text boxes that accepted Ctrl+A by default were masked textboxes, not the regular one. And at that point I was with .NET 2.0. But I guess the original problem was something else, as I can see Ctrl+A working fine by default in .NET 2.0 code.
You might be looking for the ShortcutsEnabled property. Setting it to true would allow your text boxes to implement the Ctrl+A shortcut (among others). From the documentation:
Use the ShortcutsEnabled property to
enable or disable the following
shortcut key combinations:
CTRL+Z
CTRL+E
CTRL+C
CTRL+Y
CTRL+X
CTRL+BACKSPACE
CTRL+V
CTRL+DELETE
CTRL+A
SHIFT+DELETE
CTRL+L
SHIFT+INSERT
CTRL+R
However, the documentation states:
The TextBox control does not support the CTRL+A shortcut key when the Multiline property value is true.
You will probably have to use another subclass of TextBoxBase, such as RichTextBox, for that to work.
Indeed CTRL + A will not work unless you add something like this:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && (e.KeyCode == Keys.A))
{
if (sender != null)
((TextBox)sender).SelectAll();
e.Handled = true;
}
}
This answer worked for me in a similar question (which isn't marked as accepted)
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
const int WM_KEYDOWN = 0x100;
var keyCode = (Keys) (msg.WParam.ToInt32() &
Convert.ToInt32(Keys.KeyCode));
if ((msg.Msg == WM_KEYDOWN && keyCode == Keys.A)
&& (ModifierKeys == Keys.Control)
&& txtYourTextBox.Focused)
{
txtYourTextBox.SelectAll();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
Original Post: How can I allow ctrl+a with TextBox in winform?
Make sure that
Application.EnableVisualStyles();
is not commented out in
static void Main()
That can disable Ctrl+A
This question wants an answer that cannot be given in the form of code avoidance, as the Win32 API at the core of the other methods doesn't allow it. If other methods DO allow it, they are just writing the code for you. :)
So the real question is: What is the smallest, neatest way to do it? This worked for me:
First, there is no need to handle WM_KEYDOWN! And no need to test for the Ctrl key already down either. I know that most examples here (and CodeProject and many other places) all say there is, but it does not cure the beep that results whenever a WM_CHAR arises that is not handled.
Instead, try handling WM_CHAR and doing the Ctrl+A selection there:
LRESULT CALLBACK Edit_Prc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam){
if(msg==WM_CHAR&&wParam==1){SendMessage(hwnd,EM_SETSEL,0,-1); return 1;}
else return CallWindowProc((void*)WPA,hwnd,msg,wParam,lParam);
}
Remember to subclass the EDIT control to this Edit_Prc() using WPA=SetWindowLong(...) where WPA is the window procedure address for CallWindowProc(...)