Is that possible?
I want to keep my shift pressed in an external application (such as fire fox)
and release it as I pressed it again,
I want it working just like the caps button.
to make it easier to understand,
maybe something like
shift is pressed
Keys.Shift.hold = true
and
shift is pressed again
Keys.shift.hold = false
Apologies in advance for the pseudocode; I don't know VB.net. If you're comfortable with C++, you can adapt code from this question, which I used as a reference.
You can use the SendInput Windows API. According to the function's description, it
Synthesizes keystrokes, mouse motions, and button clicks.
You will need to ensure your target program has a lower process integrity than yours - in other words, if your process isn't running as admin, don't try to feed events to an admin-level process - but since you mentioned Firefox I don't expect this to be an issue for you.
You'll want to set up a KEYBDINPUT structure like this:
wVk = VK_SHIFT
dwFlags = 0 (this will press a key. You'll want KEYEVENTF_KEYUP instead for releasing it.)
Then, set up an INPUT structure like this:
type = INPUT_KEYBOARD
ki = yourKeybdInputStruct
Now pass that whole INPUT structure to SendInput:
SendInput(1, &yourInputStruct, sizeof(yourInputStruct))
Alternately, you could try using the VB.net SendKeys class. There are some caveats that come with this class; most notably,
If your application is intended for international use with a variety of keyboards, the use of Send could yield unpredictable results and should be avoided.
Additionally, the official documentation says nothing about using a modifier key (Shift, Ctrl, Alt) by itself, nor does it appear to support holding a key down in the manner you describe, just sending a regular keystroke (keydown-keyup).
However, if you're willing to deal with those issues, this might work:
SendKeys.Send("+")
Related
I have a long running application written in VBA. Because it runs for a long time I call a sub from the main loop every iteration to check if the user has pressed the escape key. The sub is listed below. The code works great except that it is always listening, even when the VBA application does not have the focus. What's the best way to approach this? Is there an alternative to GetAsyncKeyState which only listens when the correct application is in focus, or are there system calls I can use to check that the correct window is in focus.
Private Sub checkForUserEscKeyAbort()
'Listen for escape key and exit gracefully if user aborts.
Dim abortResult As VbMsgBoxResult
If GetAsyncKeyState(vbKeyEscape) Then
abortResult = MsgBox("Escape key pressed, do you want to abort?", vbYesNo)
If abortResult = vbYes Then Call teardownSLICER
End If
End Sub
The problem is the way GetAsyncKeyState operates. It does more than just check it the key is currently down, it also checks if the key was pressed since the last time GetAsyncKeyState was called. Thus, your problem of "always listening".
You could use GetKeyState, but frankly, I'm not a fan of that option either. Your code must be well crafted to avoid a polling window that is so small that you literally have to hold the key down to ensure it isn't missed.
A viable alternative is key masking where you use a combination of keys such as Shift-Escape. There is a decent introduction to this (and many other subjects) on Chip Pearson's site. However, this is still not my preferred method.
My preference has already mentioned in the comments. Your application may best be improved with a user form. It also gives you the ability to get information in front of the user. Perhaps they wouldn't try quitting the application if a progress bar on the user form indicated 95% completion. Maybe you can add a pause button that free's some resources for a prescient need and then resumes when the user is ready. That little extra functionality on its own is enough to win me over but there is an even better reason for using a User Form - it does exactly what you asked!
User forms, and many user form controls, have Keydown, Keyup, and Keypress events that only trigger when the form (or control) have focus. This is precisely what you wanted.
I need a way to simulate keyboard keys if a certain condition is met, I also need to know if it's the simulated key that's currently pressed or the real key. This needs to work outside the main application.
This is how I would need it to work:
Dim UserDefinedKey As Keys = Keys.H
Do
If GetAsyncKeyState(UserDefinedKey) Then
Thread.Sleep(30)
'release the set key
Thread.Sleep(30)
'press/hold the set key once, continue the loop if the real key is still been held.
End If
Loop While GetAsyncKeyState(UserDefinedKey) '/ loop while real key is being held
'Real key is no longer held, release the simulated key press.
Any help would be greatly appreciated.
(This code is to automate certain things inside of a game which is why it needs to work outside the main application)
I have certain things in place to allow the user to set their own key, this was just a small example of what I need, it's just the keyboard simulating part i'm stuck with and determining if the real key is still pressed or not.
So sorry for the long wait... Simulating keyboard input via Window Messages turned out to be far much more complicated compared to simulating mouse input in the same way.
Anyway, I am finally done with it so here's a complete InputHelper class for simulating both mouse and keyboard input virtually via the mouse and keyboard input stream or via Window Messages.
Download at GitHub: https://github.com/Visual-Vincent/InputHelper/releases (source code is too long to be pasted in the answer)
Dim UserDefinedKey As Keys = Keys.H
'Using a regular While-loop is better since you won't need your If-statement then.
While InputHelper.Keyboard.IsKeyDown(UserDefinedKey)
Dim ActiveWindow As IntPtr = InputHelper.WindowMessages.GetActiveWindow()
Thread.Sleep(30)
InputHelper.WindowMessages.SendKey(ActiveWindow, UserDefinedKey, False) 'False = Key up.
Thread.Sleep(30)
InputHelper.WindowMessages.SendKey(ActiveWindow, UserDefinedKey, True) 'True = Key down.
End While
A little information about InputHelper's sub-classes:
InputHelper.Keyboard
Methods for handling and simulating physical keyboard input (i.e. input detected by GetAsyncKeyState()).
InputHelper.Mouse
Methods for handling and simulating physical mouse input.
InputHelper.WindowMessages
Methods for handling and simulating virtual keyboard and mouse input (i.e. input that is not detected by GetAsyncKeyState()).
Hope this helps!
You will need Windows API hooks for that (nothing for beginners), or third party library like MouseKeyHook
I am building a text based game, and thought of using a form instead of a console as i usually do.
So i started rebuilding a console - i created 2 text boxes, one as output and one as input.
I got the following problem while doing this:
In a console application you can use console.readline() in line.
E.g.: Dim str as String = console.readline()
now i need this effect in the form application, where i wait for the user pressing enter in the input box and getting the text he wrote.
E.g.: I ask for the character name and the user has to type it in the input box, now i need the name he typed in some way.
EDIT:
i guess i will need some way to wait for a event to raise without blocking the ui thread.
I appreciate any help solving this, Mylo.
To use the form as a console, you need to have your readLine method to wait for the event of the user hitting enter in the TextBox control, to do it without blocking the UI thread you need to use multithreading (hard) or tasks (difficult, easy with async programming), it's not an easy feat, so i think is better to use an old thrustworthy System.Console for this job.
However if you want to give it a try, there are some third party controls that may do it, like this one: http://www.codeproject.com/Articles/9621/ShellControl-A-console-emulation-control, there are others in Code Project so you may want to dig deep there and find one that you like.
Edit
This is a small async loop, note that i use also await.
do
await Task.Delay(100)
loop while (ReadingLine)
I think you're greatly overthinking this, my friend. The textbox is called TextBox1, on default.
So, to capture the data inside the text box, you say:
Dim someIdentifier As String = TextBox1.Text
And now you've captured the data in a variable, just like when you would capture it using
Console.ReadLine()
I would like to know if it's possible, and if so how, to use VB.NET to automate the input of a keyboard shortcut.
In the application i am developing, it receives email as a outlook addin and runs various checks and if those checks are positive it inserts information about the message into the database.
But i want to be able to tell it that when the subject = "Keyword" to perform Ctrl+Alt+↑ for, essentially a prank.
However I can't find anything on this anywhere, all i find is "Custom Short-cuts In VB.NET" and stuff about the KeyDown, KeyUp and KeyPress events.
Thanks
I think the easiest way to do such a thing would be to use the SendKeys method. Untested I think Ctrl+Alt+↑ would look like:
SendKeys.Send("+(^{UP})")
MSDN SendKeys
I've got a multiline textbox and a button below it.
VB.NET, WinForms, .NET 2.0
System.Windows.Forms.Textbox
Multiline = True
AcceptsReturn = True
AcceptsTab = False
CausesValidation = False
No Events explicitly coded.
I'd like the Enter key to insert line-feeds and never move the focus to the next control (the button).
I'd like the Tab key to always move the focus to the next control in the tab order (the button).
What happens instead is that the Enter key inserts one line-feed and then moves focus to the next control (the button). It also does this with Ctrl-Enter, which really baffles me!
By my reading of the help files and extensive googling, it should work the way I need it to.
But obviously I'm missing something. What am I doing wrong?
A method I often use for this sort of problem is to iteratively add and subtract code until I can narrow it down to the one thing that caused the problem.
For instance, you might start by making a very simple project with just one edit box and one other control, and see what it does. If this code behaves the way you want it to, then you can start adding code bit by bit, getting the simple project closer and closer to intended final product, until the bug appears. Then look at the last bit of code you added, and see if you can subtract bits of that until the bug goes away. Iterating this a few times might help you find the culprit.
Alternatively, you could start with your existing (misbehaving) code, and start simplifying it until the bug goes away. Then you add back part of the last thing you deleted, and iterate as above.
Lastly, in this case you could also try adding an event handler for the edit control's Leave event, and put a breakpoint in the handler. When the BP hits, check the callstack and see if you can get an idea of what code precipitated the focus change. For this to work, your debugger will probably need to be configured to display code that you don't have source for (i.e. disable the Just My Code option in the debugger). You could even paste a (trimmed) callstack into the question if you want to get the group's help in deciphering it.
p.s. Does anybody have a name for the iterative debugging method described above? If not, may I propose calling it Newton's Method (or perhaps Newtoning), since it resembles Newton's Method for iteratively finding roots of mathematical functions.
It definitely shouldn't do that. The only thing I can think is it's not got enough height to accomodate multiple lines. Try adding...
textBox1.ScrollBars = ScrollBars.Vertical
If not I don't know. Try creating a blank project and creating a form with one text box, one button set the properties and see what happens...
Turns out that I had forgotten that I had done this (below) elsewhere on the same form:
'http://duncanmackenzie.net/blog/Enter-Instead-of-Tab/default.aspx
Protected Overrides Sub OnKeyUp(ByVal e As System.Windows.Forms.KeyEventArgs)
If e.KeyCode = Keys.Enter Then
e.Handled = True
Me.ProcessTabKey(Not e.Shift)
Else
e.Handled = False
MyBase.OnKeyUp(e)
End If
End Sub