VB.net findwindow/findwindowex - vb.net

Hey all, i am trying to figure out how to go about finding this window's label when the control name is the same as all the other labels on the program.
WindowsForms10.STATIC.app.0.378734a
WindowsForms10.STATIC.app.0.378734a
WindowsForms10.STATIC.app.0.378734a
All 3 labels are named the same. The one i am most interested in is a progress % counter (1%, 2%, 3%, etc..)
How can i get the value (using a timer of course) from that label without knowing the caption of it at any given time??
Any help would be great! :o)
David

The obvious answer would be to get the text from all three labels and check which one looks like "1%", "55%" etc.
If strText Like "#%" Or strText Like "##%" Or strText = "100%" Then
' ...
The less obvious answer (if the Windows API is too cumbersome for your requirements) would be to use the Microsoft UI Automation API.

Not sure if you're just looking for a more complete code sample, but here you go.
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
'This block of code creates a list of all the labels on my form.
'Replace this with code to get a list of labels on the form you are scraping
Dim LblList As New List(Of Label)
For Each ctrl As Control In Me.Controls
If TypeOf ctrl Is Label Then
LblList.Add(CType(ctrl, Label))
End If
Next
'End
Dim ProgressLblTxt As String = String.Empty
For Each lbl As Label In LblList
If lbl.Text.Contains("%") Then 'You could use several different criteria here as mentioned in the previous answer
ProgressLblTxt = lbl.Text
End If
If ProgressLblTxt <> String.Empty Then Exit For
Next
'Do something with ProgressLblTxt
MsgBox(ProgressLblTxt)
End Sub

Related

Storing text box input into an array and displaying it on to a list box in visual basic

What i need to do is take input 10 times from a text box, store it in an array and then display the array onto a list box.
I came up with this for loop but it doesn't work, all it does is display the first input and then the rest are just blank:
For i As Integer = 0 To 9
ArrNames(i) = txtUserInput.Text
txtUserInput.Clear()
Next i
and i have a different button to display the array and i used this:
lstDisplay.DataSource = ArrNames
can anyone help me? iv'e looked everywhere and nothing worked for me
Edit 1:
So i changed it a lot and came up with this:
Dim I As Integer
If sender Is btnEnter Then
I = I + 1
End If
ArrNames(I) = txtUserInput.Text
txtUserInput.Clear()
is what it does is if the button is pressed it increases I by one which makes it so the input goes to the right index right?
but now that i make this it stopped displaying anything at all so this:
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
lstDisplay.DataSource = ArrNames
stopped working
Hopefully that I variable is declared at class level in the same place as the array.
To force the ListBox to refresh you have to set the .DataSource to Nothing and then back to your array again:
Public Class Form1
Private I As Integer
Private ArrNames(9) As String
Private Sub btnAddName_Click(sender As Object, e As EventArgs) Handles btnAddName.Click
If I < ArrNames.Length Then
If txtUserInput.Text.Trim.Length > 0 Then
ArrNames(I) = txtUserInput.Text
I = I + 1
lstDisplay.DataSource = Nothing
lstDisplay.DataSource = ArrNames
txtUserInput.Clear()
txtUserInput.Focus()
Else
MessageBox.Show("Enter a name first!")
End If
Else
MessageBox.Show("The array is full!")
End If
End Sub
End Class
I would first recommend you to use typed Lists instead of using the old fashioned array (discussions incoming.. but..).
You can also make use of the nice feature of Enumerable.Range().
I don't have my editor right now but it should look like:
Dim list = new List(Of string)
For i In Enumerable.Range(1, 10)
list.Add(txtUserInput.Text)
Next
txtUserInput.Clear()
lstDisplay.DataSource = list
If you plan to modify your list afterwards and e.g. keep it on class scope, then you should use a BindingList(Of String) which supports notifying about changes.
Edit 1:
You are calling txtUserInput.Clear() inside the loop after the first time your input has been received from the textbox. That means in each following iteration the textbox is cleared.

How can I use a variable to reference a textbox?

I'm new to visual basic and programming in general, but I'm trying to make a statistic counter sort of program. I'm trying to use a variable to reference a textbox, for example, k_kills(i) = txtKills(i).Text. This doesn't work, however, so I then tried the following:
For i = 0 To 8
Dim tempBox As TextBox
Dim tempName As String = "txtKills" & i.ToString
tempBox = Me.Controls.Item(tempName)
k_kills(i) = tempBox.Text
Next
This also doesn't work and spits out an error each time saying that 'tempBox was Nothing'.
Can anyone tell me if I can make this work?
Thanks.
You will need to find the control in some collection. By default the control would exist in its parent's Controls property and since you're trying to get the control by its name then you could use ControlCollection's Find method. If you can guarantee that the control's parent is the Form then you'd call:
Dim tempBox As TextBox = DirectCast(Me.Controls.Find(tempName, False), TextBox)
But if there is the possibility that the control's parent is something other than the Form then you'd call:
Dim tempBox As TextBox = DirectCast(Me.Controls.Find(tempName, True), TextBox)
The first would execute slightly quicker because it only iterates over the current ControlCollection whereas the second could take longer because if it cannot find the control in the current ControlCollection then it starts to iterate over the child controls as well.
Assuming the controls are all in Form as parent and they all start with txtKills...
If you are going to use these text boxes as a group for several actions you may want to build an array or list of TextBox.
Dim Kills(7) As TextBox
Private Sub CreateTextBoxArray()
Dim index As Integer
For Each ctrl As Control In Controls
If ctrl.Name.StartsWith("txtKills") Then
Kills(index) = DirectCast(ctrl, TextBox)
index += 1
End If
Next
End Sub
Private Sub ClearKillTextBoxes()
For Each t In Kills
t.Clear()
Next
End Sub
Private Function GetTextFromKillBoxes() As List(Of String)
Dim lst As New List(Of String)
For Each t In Kills
lst.Add(t.Text)
Next
Return lst
End Function
After Mary's comment I edit my answer to add this line --> My code does not work if Option Strict is On and 'For' starting in 0 or 1 or any number and txtKills[X] exists.
This was my previous answer and I don't know if I have to delete or not:
Your code works fine but I think you have an error because your For starts in 0 and you don't have any "txtKills0". I've tested it now:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim k_kills(10) As String '<< Ignore the length
For i = 1 To 7
Dim tempBox As TextBox
Dim tempName As String = "txtKills" & i.ToString
tempBox = Me.Controls.Item(tempName)
k_kills(i) = tempBox.Text
MsgBox(k_kills(i))
Next
End Sub

Can I use variables to control which PictureBox I am using?

Is there a way that I can use a variable to control which PictureBox I am using in Visual Basic?
I.e.:
CurrentNumber = 1
PictureBox(CurrentNumber).backcolour = backcolour
You can use the Me.Controls(String) indexer. It lets you specify the name (as a string) of the control you want to access, thus you can dynamically access a picture box by concatenating the string "PictureBox" with a number.
Dim TargetPictureBox As PictureBox = TryCast(Me.Controls("PictureBox" & CurrentNumber), PictureBox)
'Verifying that the control exists and that it was indeed a PictureBox.
If TargetPictureBox IsNot Nothing Then
TargetPictureBox.BackColor = Color.Red
End If
Alternatively, to save processing power by avoiding looping through the entire control collection every time you can call the OfType() extension on Me.Controls, storing the result in an array sorted by the controls' names. That way it'd only have to iterate the control collection once.
'Class level - outside any methods (subs or functions).
Dim PictureBoxes As PictureBox() = Nothing
'Doesn't necessarily have to be done in a button, it's just an example.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If PictureBoxes Is Nothing Then
PictureBoxes = Me.Controls.OfType(Of PictureBox).OrderBy(Function(p As PictureBox) p.Name).ToArray()
End If
'NOTE: CurrentNumber - 1 is necessary when using an array!
PictureBoxes(CurrentNumber - 1).BackColor = Color.Red
End Sub
NOTE: This solution will only work properly if all your picture boxes are named "PictureBox1", "PictureBox2", etc. If you suddenly skip a number ("PictureBox3", "PictureBox5", "PictureBox6") then PictureBoxes(CurrentNumber - 1) for CurrentNumber = 5 would return PictureBox6 rather than PictureBox5.
What you really should do is create a PictureBox() and use that to reference your picture boxes via an index.
The best way to build your array is to create a method that builds the array from the references created by the designer. This lets you continue to use the designer to create your controls and it makes your code check for deleted controls at design-time. Using Me.Controls(...) suffers from run-time errors if controls you are looking for have been deleted.
Here's the code you need:
Private _PictureBoxes As PictureBox() = Nothing
Sub AssignPictureBoxesArray
_PictureBoxes = {PictureBox1, PictureBox2, PictureBox3}
End Sub
Then you access them like this:
Sub SomeMethod
Dim CurrentNumber = 1
Dim PictureBox = _PictureBoxes(CurrentNumber - 1)
PictureBox.BackColor = System.Drawing.Color.Red
End Sub

Checkboxlist applying If statements

I am stating VB and since it is so close to VBScript I have been having fun with it. But now I have come across the "Checkboxlist".
My boss saw me making a Windows Forms Application and asked me to make him a interface (GUI) for one of his batch files. In the batch you start by choosing between lines 1 through 10 and it does the rest. So I made a Checkboxlist and made check-boxes going from 1 to 10. Now I am not sure how to tell it that when I click a button a if statement looks at what has been checked and take to appropriate action.
I think i am suppose to start with something like
If CheckedListBox1.Items() = True then
But i know this does not work.
Anything thing will help.
Thank you.
It sounds like you're looking for the ItemCheck event. This event is fired when the checked state of an item changes.
Private Sub HandleCheckedListBox1ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
Dim item As Object = Me.CheckedListBox1.Items.Item(e.Index)
Dim text As String = Me.CheckedListBox1.GetItemText(item)
Select Case e.CurrentValue
Case CheckState.Unchecked
'...
Case CheckState.Checked
'...
Case CheckState.Indeterminate
'...
End Select
End Sub
Or iterate all checked items:
Private Sub HandleButton1Click(sender As Object, e As EventArgs) Handles Button1.Click
For Each item As Object In Me.CheckedListBox1.CheckedItems
Dim text As String = Me.CheckedListBox1.GetItemText(item)
'...
Next
End Sub

Autocomplete for single word in datagridview

I would need to implement a autocomplete feature in a datagridview cell. I would need it to work on a word by word basis, like it is in the SMS app on android. After I type a whitespace it should start looking for the word I am typing and propose it based on the other words i have already used inside the same Datagridview.
Its more a word suggestion, that if i hit tab autocompletes that word for me.
Is this possible? I know how to do it based on the entire cell, but have no clue on how to do it based on the single word. (like Google)
Thanks
EDIT:
So far I have this. The concept is working, but I need to update the list each time that a key is pressed. Any help on this?
Private Sub DataGridView2_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView2.EditingControlShowing
wrdlst.Add("arabia")
wrdlst.Add("burundi")
wrdlst.Add("closed")
wrdlst.Add("afganistan")
wrdlst.Add("door")
wrdlst.Add("banana")
wrdlst.Add("apple")
Dim basestring As String = Nothing
basestring = CStr(DataGridView2.CurrentCell.Value)
If Not IsNothing(basestring) Then
Dim lastword As String
Dim lastspaceindex As Integer = basestring.LastIndexOf(" ") + 1 '''+1 to get index after whitespace and compensate for -1 result
lastword = basestring.Substring(lastspaceindex)
Dim ItemCode As TextBox = TryCast(e.Control, TextBox)
If ItemCode IsNot Nothing Then
ItemCode.AutoCompleteMode = AutoCompleteMode.SuggestAppend
'ItemCode.AutoCompleteCustomSource = wrdlst
For Each element As String In wrdlst
If element.StartsWith(lastword) Then
ItemCode.AutoCompleteCustomSource.Add(basestring.Substring(0, lastspaceindex) & element)
End If
Next
ItemCode.AutoCompleteSource = AutoCompleteSource.CustomSource
End If
End If
End Sub
Private Sub DataGridView2_KeyUp(sender As Object, e As KeyEventArgs) Handles DataGridView2.KeyUp
??????????????????????????????????????????
End Sub