More info on click event in VB - vb.net

I would like to create a bot that repeats the same action many times. Is there any way I can get more info about a click event. Lets say I click somewhere on the opened file explorer window. Can the program tell that I clicked on a specific area or button in that window? Can I make the program click or type on a specific(opened) window?
Thanks

Yes the program can tell when you click on a specific button. Whatever button it is that you clicked on will have its click event fired, if it exists. In order to manually tell the program to perform this action, you can implement the phrase..
btn.PerformClick()
where "btn" is the name of whatever button you are needing to click. Whenever this phrase is called, the btn_Click event handler will be fired just the same as if you yourself actually clicked the button.
To do the same thing with an actual window or form in your program is trickier because there are no built in methods you can call to trigger a windows form click event. But it is possible. The code that will define a window's event handler and trigger it will be..
Private Sub myWindow_Click() Handles MyBase.Click
'code you want to run on click event here
End Sub
myWindow_Click() 'where you want the click to be triggered
The above would be much simpler to simulate in a method call however.
And lastly to simulate the typing of text into a window, you could simply access the text property of the control you are wanting to alter, and then change that text property to the desired text. But judging from your question, you are wanting this to be done in a similar fashion to how a human would.
This can also be accomplished with some work, using a timer interval that appends to the text of the control.
Lets say for example, you wanted "hello world" to be typed into a text box on screen as a person would. Add a timer control to your form and set its interval to 250 or however fast you want the word to be type and in a method..
Dim str as String = ""
Dim pos as Integer = 0
Public Sub humanType(word as String)
str = word
Timer1.enabled = true
End Sub
public Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
myTextBox.Text = myTextBox.Text + str[pos]
pos = pos + 1
If pos = str.length Then
Timer1.enabled = false
End If
End Sub
If you have never worked with timer intervals before, this tutorial has some good info on them for VB.Net. http://www.techrepublic.com/article/perform-actions-at-set-intervals-with-vbnets-timer-control/
Hope it helps!

Related

Pressing Enter is not the same as clicking the Windows Form's AcceptButton

I have a simple VB.Net Windows Forms application with two TextBoxes and a Button which is the form's AcceptButton. The only code is on the ButtonClick, and validation for each TextBox using the Leave event. (I tried the LostFocus event also, and it seems to work the same). My problem is that if I click the Button with the mouse, then the proper Leave (or LostFocus) event happens for the TextBox that the user was in, but If I press Enter, focus is not lost and so the code for that TextBox does not run.
How can I make the Enter Key behave the same way as clicking the form's AcceptButton?
When you click directly on the button there is a chain of events including TextBox.LostFocus, TextBox.Leave, Button.MouseEnter, Button.Click
But when you press Enter it's the Form which intercept the keypress and if it's Enter and there is an AcceptButton then launch it's PerformClick method without raising most of those events.
You could easily verify that ; set your Button's DialogResult on one value via designer and handle your Button's GotFocus event when you change that DialogResult for another value.
Then test your code (store the result of Form.ShowDialog) ; with direct click you'll get the value set on GotFocus because it's during the Click the form set it's DialogResult on the button's DialogResult value ; with a press to Enter you'll get the initial Dialogresult (the designer one) effectively proving that GotFocus wasn't entered.
Back to the current problem ; to solve it you need to handle your validation in Validating (or Validated) event ; be sure that your Textbox CauseValidation is set to true [the default value] otherwise those event aren't raised. You could inside them set e.Cancel (with e the CancelEventArgs argument) to true to stop validation (and the chain of events) effectively sticking focus inside the "invalidated" control (and which also prevents the button's click whatever way was used to reach it)
one example : this form has two Textboxes and one Button as the Form's AcceptButton and "validate" it's input so that no empty TextBox.Text are allowed
Public Class NonEmptyTextBoxesForm
Private Sub TextBoxes_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating, TextBox2.Validating
Dim tb = DirectCast(sender, TextBox)
e.Cancel = tb.Text = "" ' e.Cancel = (tb.Text = "") ' if that's make this clearer
End Sub
End Class
So you are losing focus from textbox to the button when you click Enter Key?!
If this is that, you can try out this:
Protected Overrides Function ProcessCmdKey(ByRef sMessage As Message, ByVal oKeyData As Keys) As Boolean
If oKeyData = Keys.Enter Then
Me.Textbox1.Focus()
AcceptButton.PerformClick()
Return True
ElseIf oKeyData = Keys.Escape Then
Application.Exit()
Return True
Else
Return MyBase.ProcessCmdKey(sMessage, oKeyData)
End If
End Function
I hope this helped you ;)
I agree with Plutonix - why not just put the validation for both text boxes in the click event? (unless this is for education purposes?)
If you really want to validate on the text boxes' leave events, and you need the validation on the current text box to run before whatever the button does when you hit enter, then you need a key press event to handle key press for both text boxes. In that, check if the key pressed was enter, and if so then you could just get the text box that has focus...call it's leave event, and then call the button's click event.
Does that make sense?
How can I make the Enter Key behave the same way as clicking the form's AcceptButton?
To make the ENTER key behave the same as clicking the ACCEPT button you can use the ACCEPTBUTTON property of the form and assign the button you wish to be clicked when the ENTER key is pressed.
Although this will cause the code in the button's click event to execute,
I do not know if the code in the TEXTBOX-LOSTFOCUS event will execute or not!
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'
' Assign default button for ENTER key (Okay Button)
Me.AcceptButton = Me.MyOkayButton
'
' Assign default button for ESCAPE key (Cancel Button)
Me.CancelButton = Me.MyCancelButton
'
End Sub

DataGridViewLinkColumn formatting

My Application is a windows form application in VB.
I have DataGridView in my Application. The seventh column is defined as DataGridViewLinkColumn when i designed the DataGridView. My Application reads the link from a table and Grid properly displays it.
I don't want my user to see the link, i want them to see a sentence like "Click here to visit" but i couldn't manage to do.
Second, when i click the link nothing happens. I know that i have to handle this in CellContentClick event but i don't know how to call the default browser directed to the link.
Thanks in advance.
There is no direct property in DataGridViewLinkColumn which separates the display text and url.
To achieve your goal, you need to handle two events CellFormatting and CellContentClick. Subscribe to these events.
In CellFormatting event handler, change the formatted value to Click here to visit. The flag FormattingApplied must be set True as this prevents further formatting of the value.
Private Sub dataGridView1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs)
If e.ColumnIndex = 'link column index Then
e.Value = "Click here to visit";
e.FormattingApplied = True;
End If
End Sub
To open the link in the default browser, use the Process class and pass the url as argument to the Start method. Put the code in the CellContentClick event handler.
Private Sub dataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs)
If e.ColumnIndex = 'link column index Then
Process.Start(dataGridView1(e.ColumnIndex, e.RowIndex).Value.ToString());
End If
End Sub

Find Timers by Name

Okay I'm working with visual studio and I've hit a bit of a snag. The basic situation is I have a bunch of buttons and timers that correspond to each other. For example when button1 is clicked Timer1 should start.
Currently I'm using one method to handle all of the button clicks. Which identifies the CR (1, 2, 3, etc...) and constructs a string for the name of the correct Timer that goes along with it, dim timername as string = "timer" & cr.ToString. Then when I use Me.Controls(cr).Enabled = True it returns an a null pointer error.
I know the issue has to do with the identification of the timer, suggestions?
You can't identify a control using a string (well, not easily). Try this.
Private Sub ButtonX_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click ' etc.
Dim vButton = DirectCast(sender, Button)
Select Case vButton.Name
Case "Button1"
Timer1.Start ' Or stop, or whatever
Case "Button2"
Timer2.Start
End Select
End Sub
You can also compare the button object itself using If vButton Is Button1, but that gets messy in VB (I remember having to use GetType and stuff like that).
However, if your code is as simple as my example, why not just use separate handlers for each button?!!
A Timer is a Component not a Control so it will not be located in the Control Collection. This is a case where it is probably better to not use a common button click handler since it is not simplifying anything.
However, everything which inherits from Object, such as a Button, has a Tag property which you can use to associate things with that object. In form load:
Button1.Tag = Timer1
Button2.Tag = Timer2
Button3.Tag = Timer3
Then the click event:
Private Sub ButtonX_Click(... etc ) Handles Button1.Click, Button2.Click ...
Dim thisBtn As Button = CType(sender, Button)
Dim thisTmr As Timer = Ctype(thisBtn.Tag, Timer)
thisTmr.Start
End Sub

vb.net how to solve 2 issues with single and double click on notify icon

I have a vb.net (.NET 3.0) app which has a NotifyIcon in the system tray. I would like the single left-click and double left-click events to do different things; .Click should open the app's context menu, and .DoubleClick should take some default action. So this is my code at the moment:
Private Sub showMenu(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles Tray.Click
Debug.Print("click")
If e.Button = MouseButtons.Left Then
Dim mi As MethodInfo = GetType(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance Or BindingFlags.NonPublic)
mi.Invoke(Tray, Nothing)
End If
End Sub
Private Sub defaultAction(ByVal sender As System.Windows.Forms.NotifyIcon, ByVal e As System.EventArgs) _
Handles Tray.DoubleClick
Debug.Print("double click")
doDefaultAction()
End Sub
The first problem is that the .Click handler is fired even for a double-click - it responds to the first click rather than waiting to see if it was actually a double-click. Maybe this is normal behaviour, but is there a 'best practice' way of trapping that occurrence without horrible kludges involving timers? From what I've read on SO, I suspect not. However, that's not the most serious problem...
The second, bigger, problem is that the doDefaultAction() code does various things, one of which is to download an xml file from a specific URL. I'm doing this with this line of code (note not the actual URL:):
Dim reader = XmlReader.Create("http://server.com/genxml.php")
As soon as execution reaches that line, another .Click event is fired, so the debug output looks like this:
click
double click
click
That second click event re-opens the context menu, and because doDefaultAction() goes on to show a modal MessageBox, the menu gets stuck open. I've stepped through in the debugger, and if I 'Step Into' that Dim reader line, I get taken straight to Sub showMenu() above. Very odd. Any ideas what could cause that?

Right click: menu options

there is a feature I'd like to implement in my application:
The user right clicks on my picturebox object. Good.
When that happens, some code of mine executes and will generate a list of options.
Then a menu appears where the mouse right-clicked, made up of these options.
When the user clicks on one of these options, the menu is deleted and some code is run given the option index as parameter.
My two problems:
How can I tell when the user right clicks? I can see an event handler for "click", but that includes left clicks....
How do I create one of these menus? I mean, go ahead and right click something. That's the kind of menu I'm looking for.
You need to implement the picturebox' MouseUp event. Check if the right button was clicked, then create a ContextMenuStrip with the menu items you want. You can use, say, the Tag property of the items you add to help identify them so you can give them a common Click event handler. Like this:
Private Sub PictureBox1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
If e.Button <> Windows.Forms.MouseButtons.Right Then Return
Dim cms = New ContextMenuStrip
Dim item1 = cms.Items.Add("foo")
item1.Tag = 1
AddHandler item1.Click, AddressOf menuChoice
Dim item2 = cms.Items.Add("bar")
item2.Tag = 2
AddHandler item2.Click, AddressOf menuChoice
'-- etc
'..
cms.Show(PictureBox1, e.Location)
End Sub
Private Sub menuChoice(ByVal sender As Object, ByVal e As EventArgs)
Dim item = CType(sender, ToolStripMenuItem)
Dim selection = CInt(item.Tag)
'-- etc
End Sub
To your first question: you actually handle just the "click" event, there is no separate event for right-click. But look at the EventArgs object you get passed for the event: it includes information of which button was pressed (and would give you more info if a mouse click had anything beyond that). So you check the button within an if block, and you're good to go.
To your second question: http://msdn.microsoft.com/en-us/library/system.windows.forms.contextmenustrip.aspx. If your menu is pre-defined, just look for that component on the Designer and prepare the menu from there and call its Show() method from the click handler. If you need to decide the menu entries on the fly, the linked documentation page actually includes an example on that ;)
PS: oops, I just noticed Jon's comment on the question. The answer I gave you is for Windows Forms. If you are on WPF let us know and I'll update with the details (although the concepts ain't too different).
There is actually an easier way to do this. Double-click on the control you wish to be able to right click. Now go to the top of the page and it should say in comboboxes; 'Control' and 'Click' Click on the 'click' combobox and look for: Right-Click. Use a ContextMenuStrip for your right click menu.
Now you can choose which function you want.
Private Sub PictureBox1_RightClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.RightClick
ContextMenuStrip1.Show()
MsgBox("Content Activated.", MsgBoxStyle.Information, "Success!")
End Sub
Hope I could help. :)
Coridex73