הערה
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות להיכנס או לשנות מדריכי כתובות.
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות לשנות מדריכי כתובות.
Question
Thursday, October 31, 2013 1:07 AM
I am trying to make the down arrow/right arrow act like tab. I am trying to make up arrow/left arrow act like shift tab.
any advice?
newbie
All replies (34)
Thursday, October 31, 2013 1:19 AM
I am trying to make the down arrow/right arrow act like tab. I am trying to make up arrow/left arrow act like shift tab.
any advice?
newbie
Capture the KeyPress event and then call the key you want.
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
Select Case thekeycode
Case 27 '&H1B 'esc
MasterControl(True)
'cancel any following keys like tabcontrol right arrow
e.Handled = True
Case 33 'page up 'zoom out
ToolBarCommands(7)
e.Handled = True
Case 34 'page down 'zoom in
ToolBarCommands(6)
e.Handled = True
Case Else
End Select
End Sub
Thursday, October 31, 2013 1:36 AM | 1 vote
First you have to tell the form to process the arrow keys otherwise it won't. Then you have to be sure to have the form preview the keys otherwise it won't handle keystrokes when a child control is selected. With those two things in place you can then use the SelectNextControl method to do what the tab key does:
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
KeyPreview = True
End Sub
Protected Overrides Function IsInputKey(keyData As System.Windows.Forms.Keys) As Boolean
Select Case keyData
Case Keys.Left, Keys.Right, Keys.Up, Keys.Down
Return True
Case Else
Return MyBase.IsInputKey(keyData)
End Select
End Function
Protected Overrides Sub OnKeyDown(e As System.Windows.Forms.KeyEventArgs)
Select Case e.KeyCode
Case Keys.Left, Keys.Up
SelectNextControl(ActiveControl, False, True, False, True)
Case Keys.Right, Keys.Down
SelectNextControl(ActiveControl, True, True, False, True)
End Select
MyBase.OnKeyDown(e)
End Sub
End Class
Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
Thursday, October 31, 2013 1:59 PM
I tried this code, but nothing happens at all.
Thursday, October 31, 2013 2:13 PM | 1 vote
Which code? Reed Kimbles code or tommytwotrains code. BTW tommy I'm in Elephant Butte.
When you respond it's better if you reference you you're responding to so everybody can tell which code you had an issue with.
And you can display your code using the Insert Code Block function (the little square button that looks like a sheet of paper with a left and right facing arrow on it in a posts forms header while a post is being created) so we can see what you tried also.
Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.
Thursday, October 31, 2013 2:20 PM
I'm still getting used to these forums. Thank you for the pointers.
I was referring to Reed's code. After I add his code to my project the arrow keys still behave exactly the same as before.
I also want to clarify after a little more thought. I want the behavior as follows.
up arrow to act like "shift+tab"
down arrow to act like "tab"
newbie
Thursday, October 31, 2013 2:24 PM
I tried this code, but nothing happens at all.
Yes, click the quote button and you get the little gray box like above. You will actually have to think about what you are doing to use mine as I just grabbed it, it does not do anything except show an example. Guess I should have done better. Reeds code looks like it will run.
Hi Reed! Hows the lake?
Tom
Thursday, October 31, 2013 2:51 PM
Why can't something simple like the following on the forms keydown? Why won't this work? I get an error that Keys.tab is not a method. I could have sworn I did this much easier in VB6 about 15 years ago.
If Keys.Down Then
Keys.Tab()
End If
Thursday, October 31, 2013 2:56 PM
I'm still getting used to these forums. Thank you for the pointers.
I was referring to Reed's code. After I add his code to my project the arrow keys still behave exactly the same as before.
I also want to clarify after a little more thought. I want the behavior as follows.
up arrow to act like "shift+tab"
down arrow to act like "tab"
newbie
Did you put the code in a Form? Did you remember to turn on the Form's KeyPreview?
Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
Thursday, October 31, 2013 2:59 PM
Why can't something simple like the following on the forms keydown? Why won't this work? I get an error that Keys.tab is not a method. I could have sworn I did this much easier in VB6 about 15 years ago.
If Keys.Down Then
Keys.Tab()
End If
Because Keys.Tab is just a value not a method; it doesn't actually "do" anything, it just represents a particular key value. -EDIT- oh and Keys.Down is not Boolean so it would need to be compared to something.
I suppose you could use SendKeys instead but what would be the point? The tab key cycles through the active control on the form and that is also what SelectNextControl does so it would be much more efficient than SendKeys.
Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
Thursday, October 31, 2013 3:56 PM
Hi,
Reed`s code seems to work fine for me in a new form project so i would guess that you have something in your code or perhaps a property setting somewhere that is causing it not to work. Anyways, here is another example using the Forms KeyDown event to do it.
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
KeyPreview = True
End Sub
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Up Then
e.Handled = True
SelectNextControl(ActiveControl, False, True, False, True)
ElseIf e.KeyCode = Keys.Down Then
e.Handled = True
SelectNextControl(ActiveControl, True, True, False, True)
End If
End Sub
End Class
Thursday, October 31, 2013 8:19 PM
absolutely nothing happens when I press the down or up arrow key.
Thursday, October 31, 2013 8:42 PM
absolutely nothing happens when I press the down or up arrow key.
Hi,
If you where replying to me and none of Reeds or my code is doing anything then i have to ask, did you try it by creating a new Windows Forms Application project and placing some controls on it and then pasting the code i gave into the forms code? I just want to make sure your not using WPF application or something and also i want to make sure it is not something else in your current project that is causing this.
Thursday, October 31, 2013 8:48 PM
if I try the following
If e.KeyCode = Keys.Up Then
SendKeys.Send(Keys.Tab)
End If
Then press the up arrow key the number "9" is displayed in the text box instead of tabbing to the next text box. Why?
Thursday, October 31, 2013 9:18 PM
You are correct. I started a completely new project and added the code and it works perfectly.
what could be happening with my app?
James
Thursday, October 31, 2013 9:24 PM
I do have my text boxes within a group box. Also, could the tab index or tab stop of the text boxes be affecting this?
James
Thursday, October 31, 2013 9:26 PM
If I put the text boxes inside of a group box the code stops working. Any work around for this?
James
Friday, November 1, 2013 1:45 AM | 1 vote
If I put the text boxes inside of a group box the code stops working. Any work around for this?
James
There's always a work around it just depends if anybody wants to apply themselves to the level necessary to figure out the answer which was not part of the original question. Also if you already received an answer to your original question please propose whoever answered your original question as the answerer.
Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.
Friday, November 1, 2013 2:43 AM
Wait, I meant to say HI MonkeyBoy! Hows the lake?
Friday, November 1, 2013 3:52 AM
Wait, I meant to say HI MonkeyBoy! Hows the lake?
Well. It looks more like a pond than a lake nowadays. I think you could drive a 4X4 across most of it if you had tall enough tires!
Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.
Friday, November 1, 2013 12:15 PM
Wait, I meant to say HI MonkeyBoy! Hows the lake?
Well. It looks more like a pond than a lake nowadays. I think you could drive a 4X4 across most of it if you had tall enough tires!
Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.
Yes, that is what I was wondering. I was hoping the water level went up some as we had good rain in Albuquerque over the summer. Well, my email is on the How to Order page of my web site if you want to chat. I have been impressed with your expertise in your answers here.
Tom
Friday, November 1, 2013 1:18 PM
If I put the text boxes inside of a group box the code stops working. Any work around for this?
James
Hi,
After doing some experimenting i have found that the Up, Down, Left, and Right arrow keys are already set up to work similar to the Tab and Shft+Tab and there does not seem to be a way to get the app to ignore them whether you use the KeyDown event, the Protected Overrides OnKeyDown, or the Protected Overrides WndProc. I tried using the (e.cancel and e.Handled) in the KeyDown and OnKeyDown. I also tried detecting the WM_KEYDOWN in the WndProc and just returning without processing the key press if it detected the Up or Down arrow keys and even that did not seem to stop the arrow keys from selecting the next or last control on the form. There may be a way but, i guess i have not figured it out yet. I kind of had it working by using SendKeys to send a Tab or Shft+Tab but, in the reverse direction it stops at every control even in a groupbox and then going forward threw them it seemed to skip rite over the whole goroupbox. It is strange that it does this. Of coarse maybe i am overlooking something and someone else might know how to make the form ignore the Up or Down keys. If i find an answer i will be back. :)
Friday, November 1, 2013 3:06 PM
Wait, I meant to say HI MonkeyBoy! Hows the lake?
Well. It looks more like a pond than a lake nowadays. I think you could drive a 4X4 across most of it if you had tall enough tires!
Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.
Yes, that is what I was wondering. I was hoping the water level went up some as we had good rain in Albuquerque over the summer. Well, my email is on the How to Order page of my web site if you want to chat. I have been impressed with your expertise in your answers here.
Tom
All right. Sounds good. I'll get hold of you in a day or two. Thanks!
Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.
Friday, November 1, 2013 3:27 PM
I do have my text boxes within a group box. Also, could the tab index or tab stop of the text boxes be affecting this?
James
Look at the documentation for SelectNextControl. You can see the example code is passing four boolean parameters after the starting control; what do you think they might do?
If you change the "nested" parameter to True, then controls inside of controls will also be selected. This can affect the overall tab order and you may need to exclude certain controls (set their TabStop to false) before things flow just the way you want (hence this parameter being set to False in the example code).
Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
Friday, November 1, 2013 5:03 PM
Look at the documentation for SelectNextControl. You can see the example code is passing four boolean parameters after the starting control; what do you think they might do?
If you change the "nested" parameter to True, then controls inside of controls will also be selected. This can affect the overall tab order and you may need to exclude certain controls (set their TabStop to false) before things flow just the way you want (hence this parameter being set to False in the example code).
Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
Hey Reed,
I tested your code in a new form project and set the "nested" parameter to True last night and it does the same thing as the test i did using SendKeys. As you go threw the controls in reverse it will select every control even in the groupbox but, if you go forward it skips past the groupbox. I have all tabstops set to true and are all in the correct tabindex order and used the code below. I even tried with the e.handled and e.suppressKeyPress set true. I am starting to think its a bug or something because i have tried all kinds of different approaches with no success so far. Then again maybe i am overlooking something. :)
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
KeyPreview = True
End Sub
Protected Overrides Function IsInputKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
Select Case keyData
Case Keys.Up, Keys.Down
Return True
Case Else
Return MyBase.IsInputKey(keyData)
End Select
End Function
Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs)
Select Case e.KeyCode
Case Keys.Up
e.Handled = True
e.SuppressKeyPress = True
SelectNextControl(ActiveControl, False, True, True, True)
Case Keys.Down
e.Handled = True
e.SuppressKeyPress = True
SelectNextControl(ActiveControl, True, True, True, True)
End Select
MyBase.OnKeyDown(e)
End Sub
End Class
Friday, November 1, 2013 8:35 PM | 1 vote
There does seem to be something buggy with the first container on a form... and using SendKeys has the exact same buggy behavior as calling SelectNextControl directly. I'm not quite sure what is causing it...
-EDIT-
Actually it appears to be caused by the default arrow key behavior so a control which does not accept key input cannot precede a container control or the focus will shift twice, skipping over the contents of the container. So I guess it's going to depend on the control layout.
There might be another way to go about this by manipulating Windows messages, but I'm not sure.
Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
Friday, November 1, 2013 10:09 PM
There does seem to be something buggy with the first container on a form... and using SendKeys has the exact same buggy behavior as calling SelectNextControl directly. I'm not quite sure what is causing it...
-EDIT-
Actually it appears to be caused by the default arrow key behavior so a control which does not accept key input cannot precede a container control or the focus will shift twice, skipping over the contents of the container. So I guess it's going to depend on the control layout.
There might be another way to go about this by manipulating Windows messages, but I'm not sure.
Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
I looked into System messages and actually got the tab, not shift tab, but tab working. However you actually have to designate the control that the tab is to be used on that will cause focus to skip to the next control. Unfortunately textboxes have IntPtrs/hWnds or handles or whatever but the same name as far as system messages and SPY++ showed. Therefore you need the actual IntPtr/hWnd of the control that you want the message sent to perform it's action on. The problem with that is you can get all the IntPtrs for the child controls but you have no idea which one you are sending the tab message to so they would be out of sequence at best. I looked into it fairly thoroughly although I'm no expert in that area. But SPY++ would only show the hWnd or Class but not the controls Caption which I assume would be the controls name like TextBox1 or whatever. As it did show Form1 for the caption for a Form. And the messages themselves that I was capturing would have the x, y coordinates of the control the message was being sent to or received from. So after about 6 hours of that I gave up. Although system messages are pretty neat to work with except I could see how they could be pretty dangerous just by accidentally entering valid fields that mean something way different than what you want and cause something to perform something that would be very regrettable real quick.
Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.
Saturday, November 2, 2013 5:26 AM
It will definitely be an at least somewhat involved process, and you've certain noted the potential downsides.
Every control should expose its handle as a property so that would give you the IntPtr you need for a specific control. Or it may do to use Win32 API calls to get the focused control's handle (pretty sure there's a call for that... a form of FindWindowEx or something, I'd have to go look).
I kind of think that at then end of the day though it all comes down to a form design and layout which will work for this logic. Depending on the controls involved the form may already cycle through everything using the arrow keys without any extra code; it just depends on whether we are talking about a bunch of buttons or a bunch of textboxes. If its both then the whole thing probably isn't the best idea (imagine the frustration of trying to arrow back a character in a textbox).
Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
Monday, November 4, 2013 9:22 PM
I just got back in from out of the office.
I don't want to manipulate the left or right arrows. I only want to manipulate the up/down arrows to act like a shift+tab/tab since the up/down arrow keys do not do anything right now. It's just not very user friendly so I want to change that.
I have text boxes within frames (group box). I cannot get any recommended solutions to work if the text controls are within a frame.
As mentioned above it seems buggy. This really shouldn't be that difficult even for a newbie like me.
Monday, November 4, 2013 9:35 PM
I am seeing some strange behavior now. I inserted the following code again. Now the arrow keys will move between text controls. But when I get to a particular frame it gets caught in a loop in that frame. In other works when I get to that frame and press arrow down it will go to the next text control until it gets to the last text control in that frame. then if I press arrow down again it will go back to the first text control within that frame instead of going to the text box within the next frame. There are other weird behaviors when the focus seems to set on an option button with in a frame. Any ideas?
Protected Overrides Function IsInputKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
Select Case keyData
Case Keys.Up, Keys.Down
Return True
Case Else
Return MyBase.IsInputKey(keyData)
End Select
End Function
Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs)
Select Case e.KeyCode
Case Keys.Up
e.Handled = True
e.SuppressKeyPress = True
SelectNextControl(ActiveControl, False, True, True, True)
Case Keys.Down
e.Handled = True
e.SuppressKeyPress = True
SelectNextControl(ActiveControl, True, True, True, True)
End Select
MyBase.OnKeyDown(e)
End Sub
Monday, November 4, 2013 9:48 PM
What is a frame? The only frames I know about are for holding things on a wall or for a house or a segment of video or something.
Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.
Monday, November 4, 2013 9:51 PM
lol...good one! If I recall properly, VB6 referred to what is now called "group boxes" as "frames"
Tuesday, November 5, 2013 4:55 PM
Part of the issue is ensuring the TabIndex values of each textbox are incremental. Note that when you add a textbox to a container (like a groupbox) the TabIndex restarts at 0 for controls within the container.
If you are only interested in navigating between textboxes then it might be best to just gather all of them into a single list and manually switch over them yourself. Here's an example (again, make sure you've explicitly set the TabIndex of each textbox in the order desired).
Public Class Form1
Private _AllTextBoxes As New List(Of TextBox)
Private _FocusIndex As Integer
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
KeyPreview = True
FindAllTextBoxes(Me)
_AllTextBoxes.Sort(New Comparison(Of TextBox)(Function(tb1 As TextBox, tb2 As TextBox) tb1.TabIndex.CompareTo(tb2.TabIndex)))
_AllTextBoxes(0).Focus()
End Sub
Private Sub FindAllTextBoxes(container As Control)
For Each c As Control In container.Controls
If TypeOf c Is TextBox Then
AddHandler c.GotFocus, AddressOf TextBox_GotFocus
_AllTextBoxes.Add(c)
Else
FindAllTextBoxes(c)
End If
Next
End Sub
Private Sub SelectNextTextBox(forward As Boolean)
If forward Then
_FocusIndex += 1
Else
_FocusIndex -= 1
End If
If _FocusIndex < 0 Then _FocusIndex = _AllTextBoxes.Count - 1
If _FocusIndex = _AllTextBoxes.Count Then _FocusIndex = 0
_AllTextBoxes(_FocusIndex).Focus()
End Sub
Private Sub TextBox_GotFocus(sender As Object, e As System.EventArgs)
_FocusIndex = _AllTextBoxes.IndexOf(CType(sender, TextBox))
End Sub
Protected Overrides Function IsInputKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
Select Case keyData
Case Keys.Up, Keys.Down
Return True
Case Else
Return MyBase.IsInputKey(keyData)
End Select
End Function
Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs)
Select Case e.KeyCode
Case Keys.Up
e.Handled = True
e.SuppressKeyPress = True
SelectNextTextBox(False)
Case Keys.Down
e.Handled = True
e.SuppressKeyPress = True
SelectNextTextBox(True)
End Select
MyBase.OnKeyDown(e)
End Sub
End Class
Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
Wednesday, November 6, 2013 4:59 AM
Hi,
The only way i found so far to actually get the result you want is by using a low level keyboard hook. I made a Class Library using one that will stop the up/down keys from being processed by your form and then use Sendkeys to simulate the Tab keys being pressed. I made it so that when you start it you have to give it a handle to the form you want the keys to be changed for. This way it does not effect other apps that use the arrow keys. If your interested then you can download the Class Library project named ArrowKeys from here on SkyDrive. Being it is a dll you may want to open the project and rebuild it if you want to be on the safe side. After that you can test it out by creating a new Form project and adding Reference to it by going to the VB menu and clicking (Project) and then (Add Reference...). Then select the (Browse) tab and browse to the dll file in the (ArrowKey\ArrowKey\bin\Release) folder and select it. Now you can add a few controls on the form including a groupbox with a few controls in it and use the code below to create the new class and start/stop it.
Public Class Form1
Dim ak As New ArrowKey.UpDownTabs
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ak.StartKeySwap(MyBase.Handle) 'Start sending Tab Keys instead of using the Up/Down keys for this form
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
ak.StopKeySwap() 'Stop sending the Tab Keys for this form. DONT FORGET TO STOP IT WHEN THE FORM IS CLOSING
End Sub
End Class
Wednesday, November 6, 2013 12:58 PM
After thinking about it, it may be easier for you to just add a module to your program and use the code below in the module. You can add a module by going to the VB menu and clicking (Project) and then (Add Module...). This way you don`t need to add a reference to a class library and it is not cluttering up your forms code.
Imports System.Runtime.InteropServices
Module Module1
Private Const WM_KEYDOWN As Integer = &H100
Private Const WH_KEYBOARD_LL As Integer = 13
Private hKeyboard As IntPtr = IntPtr.Zero
Private hExe As IntPtr = IntPtr.Zero
<DllImport("user32.dll", EntryPoint:="SetWindowsHookExW")> _
Private Function SetWindowsHookExW(ByVal idHook As Integer, ByVal lpfn As KeyboardHookDelegate, ByVal hMod As System.IntPtr, ByVal dwThreadId As UInteger) As System.IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="UnhookWindowsHookEx")> _
Private Function UnhookWindowsHookEx(ByVal hhk As System.IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("user32.dll", EntryPoint:="CallNextHookEx")> _
Private Function CallNextHookEx(ByVal hhk As System.IntPtr, ByVal nCode As Integer, ByVal wParam As System.IntPtr, ByVal lParam As KBDLLHOOKSTRUCT) As Integer
End Function
<DllImport("user32.dll", EntryPoint:="GetForegroundWindow")> Private Function GetForegroundWindow() As System.IntPtr
End Function
<DllImport("kernel32.dll", EntryPoint:="GetModuleHandleW")> _
Private Function GetModuleHandleW(<InAttribute(), MarshalAs(UnmanagedType.LPTStr)> ByVal lpModuleName As String) As System.IntPtr
End Function
<StructLayout(LayoutKind.Sequential)> _
Private Structure KBDLLHOOKSTRUCT
Public vkCode As UInteger
Public scanCode As UInteger
Public flags As UInteger
Public time As UInteger
Public dwExtraInfo As UInteger
End Structure
<MarshalAs(UnmanagedType.FunctionPtr)> Private callback As New KeyboardHookDelegate(AddressOf KeyboardCallback)
Private Delegate Function KeyboardHookDelegate(ByVal nCode As Integer, ByVal wParam As System.IntPtr, ByRef lParam As KBDLLHOOKSTRUCT) As Integer
Private Function KeyboardCallback(ByVal nCode As Integer, ByVal wParam As System.IntPtr, ByRef lParam As KBDLLHOOKSTRUCT) As Integer
If nCode = 0 Then
If wParam.ToInt32 = WM_KEYDOWN AndAlso GetForegroundWindow().Equals(hExe) Then
Dim e As New KeyEventArgs(CType(lParam.vkCode, Keys))
If e.KeyCode = Keys.Up Then
SendKeys.Send("+{TAB}")
Return 1
ElseIf e.KeyCode = Keys.Down Then
SendKeys.Send("{TAB}")
Return 1
End If
End If
End If
Return CallNextHookEx(hKeyboard, nCode, wParam, lParam)
End Function
Public Function StartKeySwap(ByVal FormHandle As IntPtr) As Boolean
hExe = FormHandle
hKeyboard = SetWindowsHookExW(WH_KEYBOARD_LL, callback, GetModuleHandleW(Nothing), 0)
If Not hKeyboard.Equals(IntPtr.Zero) Then Return True
End Function
Public Function StopKeySwap() As Boolean
Return UnhookWindowsHookEx(hKeyboard)
End Function
End Module
Then you can use this code in the Forms code to start and stop the Arrow keys from being used like Tab and Shft+Tab for your program.
Public Class Form1
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Module1.StopKeySwap() 'Make sure you stop it when the form is closing
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Module1.StartKeySwap(MyBase.Handle)
End Sub
End Class