When pressing the Alt key, normally the focus goes to the window's menu. I need to disable it globally. Because my application works with Alt key. When the user presses some key in combination with the Alt key, my application sends another key to active application. So I just need to ignore Alt when it opens the menu.
I'm new to programming and I'm looking for VB.Net or C# code.
My first answer is to NOT use the Alt key for your program and use Ctrl instead. Blocking "normal" things from happening usually leads to pain in the future.
But if you must use the Alt key I would check out this article which uses message filters to try and intercept it at the application level.
If that doesn't do what you're looking for, you might need to look into Global hooks, this link will get you started down the path. Global hooks are generally considered evil so you should only use this if the above two suggestions don't work. You must make sure that you uninstall your hooks otherwise you might find that you need to reboot your computer often to fix weird keyboard problems.
This works for me:
private class AltKeyFilter : IMessageFilter
{
public bool PreFilterMessage(ref Message m)
{
return m.Msg == 0x0104 && ((int)m.LParam & 0x20000000) != 0;
}
}
And then you add the message filter like so:
Application.AddMessageFilter(new AltKeyFilter());
You can try something like this:
public void HandleKeyDown(object sender, keyEventArgs e)
{
//do whatever you want with or without Alt
if (e.Modifiers == Keys.Alt)
e.SuppressKeyPress = true;
}
This should allow you to use Alt for whatever you want but keep it from activating the menustrip. Note that e.SuppressKeyPress = true also sets e.Handled = true.
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.keyeventargs.suppresskeypress?view=windowsdesktop-5.0
Related
in my C# windows form application I want the user to be able to remove a node by pressing the delete key on their keyboard and have implemented the seemingly correct code but when the delete key is pressed nothing happens.
private void treeView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys .Delete)
{
if (treeView1.SelectedNode != null)
{
treeView1.SelectedNode.Remove();
}
}
This is the code I am attempting to use to implement the desired function.
The keyboard keycode check looks fine to me, which says to me that treeView1.SelectedNode is probably returning null.
I met the problem today and have tried many ways to address it. MSDN gives the answer actually. Here are the two codes that I put in public Form1()
this.KeyPreview = true;
this.KeyDown += new KeyEventHandler(Form1_KeyDown);
I've just study C# this week, so I am trying to figure out the meaning of the codes. Just hope this approach will work for the people who needs.
If anyone can explain the code above, I will be very grateful.
I'm working on a C# project where I need to create the possibility for keyboard input.
A quiz question appears with 3 options. Two players at the same computer have each of their hand at the ASD keys and JKL keys. For the answer options, I'd like for it to be chosen by pressing keyboard keys, as using anything by mouse would be inconvenient for this purpose.
How could I do this? Do I need to use some scripts outside purely C#?
I assume that we are talking about a web application. Yes you have to use script. Let me explain to you this way: Your c# code is working on the server side. It does not have an effect on client side. Maybe some third party tools like devexpress or something else can be used for this situtaion, but i am not sure these tools can handle key press events. I always prefer developing my own script
$(document).keypress(function(event) { //handle keys });
Not enough detail here, please look at:
https://stackoverflow.com/questions/how-to-ask
This method retrieves the keys pressed by the user, For example by selecting Ctrl + O, a method called ImportFile() will run. Another useful event to use will be the KeyPressed which is particularly useful firing in textboxes for validation - checking if it's empty.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
// If user selects Ctrl + O
if (keyData == (Keys.Control | Keys.O))
{
// Call method
ImportFile();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
Take a look at Key Events: ProcessCmdKey for more details.
How do I simulate a key stroke in a window that is not my C# application ?
Right now i'm using SendKeys.Send() but it does not work. The thing is I have a global keyboard hook so I catch the input directly from the keyboard and SendKeys.Send() is not seen like a real keyboard stroke.
The best would be to simulate a real keystroke this way, no matter what is the application i'm in, my program will catch it as if someone pressed a key.
I guess I found part of the problem. This is the event called if a key is pressed :
static void KeyBoardHook_KeyPressed(object sender, KeyPressedEventArgs e)
{
// Writes the pressed key in the console (it works)
Console.WriteLine(e.KeyCode.ToString());
// Check if pressed key is Up Arrow (it works and enters the condition)
if(e.KeyCode == Keys.Up)
{
// Send the key again. (does not work)
SendKeys.Send("{UP}");
}
}
I tried it this way to :
static void KeyBoardHook_KeyPressed(object sender, KeyPressedEventArgs e)
{
// Writes the pressed key in the console (it works)
Console.WriteLine(e.KeyCode.ToString());
// Check if pressed key is Up Arrow (it works and enters the condition)
if(e.KeyCode == Keys.Up)
{
// Send the key again. (does not work)
PostMessage(proc.MainWindowHandle,WM_KEYDOWN, VK_UP,0);
}
}
but it does not work either. The thing is since I send the key inside my event, will it call itself because a key has been pressed ? In case someone needs it, the code above.
[STAThread]
static void Main(string args)
{
KeyBoardHook.CreateHook();
KeyBoardHook.KeyPressed += KeyBoardHook_KeyPressed;
Application.Run();
KeyBoardHook.Dispose();
}
if you need the KeyBoardHook class I can post it too.
My guess is that my keyboard hook is catching the low-level keyboard outputs and the SendKeys is just simulating a keystroke so my hook doesn't catch it. Anybody thinks of a work around ?
I suggest you use this very cool library that masks all the complexity for you, the Windows Input Simulator available here: http://inputsimulator.codeplex.com/
I believe it's based on the Windows' SendInput function.
You can p/invoke the keybd_event (which is much simpler and easier) or SendInput (which is newer and has more capabilities) functions, which simulate keyboard input at a much lower level.
Is there a way by which we can find out if a clip board paste event occurred in a rich text box? This event would be used in order to do certain stuff, with the pasted block of text.
thanks
Here is my code
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (m.Msg == WM_PASTE)
{
OnPasteOccurred();
MessageBox.Show("Pas");
}
if (m.Msg == 0x000F)
{
if (PaintControl)
{
base.WndProc(ref m);
}
else
{
m.Result = IntPtr.Zero;
}
}
else
{
base.WndProc(ref m);
}
}
Edit
I wish to do some syntax highlighting or indentation based on paste events, something which this particular code editor seems to be doing very efficiently. I don't know how it is doing it. Would require help in this particular direction. I am pretty sure that there must some native Win32 code or something like that can be intercepted. I have tried tracking down keys, mouse events and it is not pretty.
It's a little bit tricky to detect a paste operation in the RichTextBox.
First solution may be to detect the WM_PASTE message overriding the WndProc but unfortunately the control doesn't send that message to itself when it performs a paste operation.
Naïve detection
To detect the keyboard events may work (you have to override the OnKeyDown function) then check if the key combinations (CTRL+V and SHIFT+INS). Something like this:
protected override OnKeyDown(KeyEventArgs e)
{
bool ctrlV = e.Modifiers == Keys.Control && e.KeyCode == Keys.V;
bool shiftIns = e.Modifiers == Keys.Shift && e.KeyCode == Keys.Insert;
if (ctrlV || shiftIns)
DoSomething();
}
It works well but you can't catch the paste operation made using the mouse (right click to open the context menu) and the paste operations made via drag & drop. If you do not need them you can use this solution (at least it's simply and straightforward).
Better detection
Assumption: when user types inside the RichTextBox he inserts one character per time. How can you use this? Well, when you detect a bigger change you detected a paste operation because user can't type more than once character per time (ok, you can argue that it's not always true because of Unicode surrogates). See also VB.NET version and more details about Unicode stuff.
private int _previousLength = 0;
private void richTextBox_TextChanged(object sender, EventArgs e)
{
int currentLength = richTextBox.Text.Length;
if (Math.Abs(currentLength - _previousLength) > 1)
ProcessAllLines();
_previousLength = currentLength;
}
Please note that you can't (because of how different IMEs work) use OnKeyDown (or similar). This works well only for western languages but it has problems with Unicode stuff (because, for example, String.Length property may be increased by two Char when user typed a single character. See also this post for much more details about this (well it's a strongly suggested reading even, even if - in this case - you don't care about it). In that post you'll also find code for a better algorithm to determine string length. In short you have to replace:
int currentLength = richTextBox.Text.Length;
With this:
int currentLength = StringInfo.GetTextElementEnumerator(richTextBox.Text)
.Cast<string>()
.Count();
After all this effort you may realize that...user can even paste a single character and it may go undetected. You're right, that's why this is a better detection instead of a perfect solution.
Perfect solution
The perfect solution (if you're running on Windows 8) of course exists, the native rich edit control sends an EN_CLIPFORMAT notification message. It's intended to notify a rich edit control's parent window that a paste occurred with a particular clipboard format. You can then override the WndProc of its parent to detect the WM_NOTIFY message for this notification. Anyway it's not few lines of code, check this MSDN article for details.
Starting from .Net 3.0, there is a built-in method to detect the paste event:
DataObject.AddPastingHandler(this, OnPaste);
Just call this method in the constructor. If you want for example handle the paste event yourself as if the user entered the text manually, you can use
private void OnPaste(object sender, DataObjectPastingEventArgs e)
{
if (e.DataObject.GetDataPresent(typeof(string)))
{
var text = (string)e.DataObject.GetData(typeof(string));
var composition = new TextComposition(InputManager.Current, this, text);
TextCompositionManager.StartComposition(composition);
}
e.CancelCommand();
}
I came across this old question and I would like to share my solution (it's VB but can it be easily converted). I use it to force paste as plain text when needed:
Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
If ForcePasteAsPlainText And ((e.Control = True And e.KeyCode = Keys.V) Or (e.Shift = True And e.KeyCode = Keys.Insert)) Then
MyBase.Paste(DataFormats.GetFormat(DataFormats.Text))
e.Handled = True
Return
End If
MyBase.OnKeyDown(e)
End Sub
Shadows Sub Paste()
If ForcePasteAsPlainText Then
MyBase.Paste(DataFormats.GetFormat(DataFormats.Text))
Else
MyBase.Paste()
End If
End Sub
Shadows Sub Paste(clipFormat As DataFormats.Format)
If ForcePasteAsPlainText Then
MyBase.Paste(DataFormats.GetFormat(DataFormats.Text))
Else
MyBase.Paste(clipFormat)
End If
End Sub
whenever i am pressing key in my server system i ll send that keyevent to another system after that the correspondingaction should be happend in the client machine.. help me to get a better way to solve this problem
thanx in advance
If I understand it correctly then what you have doesn't sound too bad. Are you saying that:
You have a client server architecture.
At the server (presumably at command console or management application) you press a key.
The key corresponds to an action. The action needs to be invoked at the client.
You could implement this using asynchronous WCF. See here and here for more some more info. One way to look at this problem is as a distributed observer pattern. Your server is the subject and the client(s) are the observer(s).
Update: Handling Key Events in .Net
You could try adding a KeyDown event handler to your form:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control & e.KeyCode == Keys.C)
{
MessageBox.Show( "Ctrl + C pressed" );
// Swallow key event, i.e. indicate that it was handled.
e.Handled = true;
}
}
But if you have any controls on your form then you won't get the event. What you probably need to do is sniff windows messages using a message filter. E.g.
public class KeyDownMessageFilter : IMessageFilter
{
public const int WM_KEYDOWN = 0x0100;
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == WM_KEYDOWN)
{
// Key Down
return true; // Event handled
}
return false;
}
}
Add this message filter to the application using the AddMessageFilter method. If you want to check if the CTRL key is pressed for the key down message then check the lparam.
If any of this isn't clear then let me know.
please give us more details on what you're trying to do.
To simulate key presses in Windows Forms, I'd use SendKeys class.