Create New Project.

On top left of the form add a button -> change text to: Capture coordinates
Resize button to make it a bit bigger. 
On the right of this button add another button -> change text to: Cancel, change visible to: False
On the right of the "cancel" button add a label

Below the first button add a checkbox -> change text to: Whole Screen
Below this button (middle left of the form) add a small textbox -> Mulitline: yes, size around: 140, 90
Below the textbox add a button -> text: Clear

On the right of the first textbox add two more with the same properties, so that the middle of the field form has three small textboxes. Below each one there should be one "Clear" button.
On top of the second textbox add another checkbox -> text: Form + Borders
On top of the third textbox add a checkbox -> text: Form - No Borders

Go to toolbox -> All Windows Forms -> Double click a Timer to add to the program.

The program will be able to follow three types of mouse coordinates: the whole screen of your computer, the main form of the program including borders (like the blue header) and the coordinates of the space inside the borders of the program.

We will display the coordinates inside the textboxes. The capturing of coordinates will be done with the keyboard "Space" key (any pressed key really). This allows us to get mouse coordinates outside the main program form and over various objects inside the form, which would be hard to achieve with a mouse click.

First we will focus on making one textbox operational and then, at the end, we will easily add the code for the other two.

Double click on the "Capture coordinates" button and add this inside:

If CheckBox1.Checked Or CheckBox2.Checked Or CheckBox3.Checked Then
Label1.Text = "! Scroll with your mouse and then press Space !"
Button2.Visible = True
End If

-> if any of the checkboxes is checked (checked is true), then a person can start the operations form the "capture" button - otherwise this is not possible.
Button2, in this case, is the "cancel" button on the right of the "capture" button.

We will use the timer to calculate the coordinates in every moment. When the program is started, the timer is turned off. We have to turn it on right after turning a checkbox on. First we will only do checkbox1.

Double click Checkbox1 on the design page. Add this inside:
If Checkbox1.checked Then
Timer1.Enabled = True
Else
Timer1.Enabled = False
End If

When we turn on the timer it should start sending in data to our textbox1 every 100 miliseconds (which is the default interval). We will always write this data in the last used line of the textbox and save captured coordinates in previous text lines. For doing this we will need two variables.
Right after "Public Class Form1" declare this:
Private x1 As Integer
Private gg As String()

Double click on Timer1 on the design page. Inside the sub add this:
If CheckBox1.Checked Then
ReDim Preserve gg(0 To x1)
gg(x1) = Cursor.Position.ToString
TextBox1.Lines = gg
End If

-> only if checkbox1 is checked, re-dimension "gg". The string array variable "gg" didn't have a size defined before this point. That's why we couldn't write at a specific positions into it, like:  gg(12) = "hello"
The "Preserve" modifier keeps all the content inside the array's positions. So, if we create gg(0 To 2), then write words inside gg(0), gg(1) and gg(2) - we can use preserve this words in a later re-dimensioning and give the same array a new size like gg(0 To 20).
Cursor.Position.ToString - takes the current x and y positions of the cursor on the whole screen (0,0 should be at the most top-left corner of your computer screen).

We have to be using the "gg" variable to store values inside the textbox. This is required since we can't write directly in a specific line of the textbox, for example:
TextBox1.Lines(x1) = Cursor.Position.ToString   - doesn't work. We can't choose a specific textbox line.
That's why we store all the content from the "gg" inside the textbox all the time and only change "gg".

You can check the operation of timer so far by checking the checkbox1 on.

Code:

    Public Class Form1

    Private x1 As Integer
    Private gg As String()

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    If CheckBox1.Checked Or CheckBox2.Checked Or CheckBox3.Checked Then
    Label1.Text = "! Scroll with your mouse and then press Space !"
    Button2.Visible = True
        End If
    End Sub

    Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
    If CheckBox1.Checked Then
    Timer1.Enabled = True
    Else
    Timer1.Enabled = False
    End If
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    If CheckBox1.Checked Then
    ReDim Preserve gg(0 To x1)
    gg(x1) = Cursor.Position.ToString
    TextBox1.Lines = gg
    End If
    End Sub

    End Class


The first click on the "capture" button will start the process of waiting for a keyboard keypress. We will end this process by pressing the "space" button while the object selected inside the program is our "capture" button. First click starts the process, second one ends it.  

At the beginning of our button1 we will add the operation for the second (awaited) press of the button. Add:
If Button2.Visible = True Then
x1 = x1 + 1
Label1.Text = ""
Button2.Visible = False
Label1.Focus()
Exit Sub
End If

-> first button1 press makes button2 visible, therefore, this option becomes available for the second press.
x1 = x1+1  - this line is the main reason why we get a capture. Right after this line happens, the timer will write it's last cursor data in the old gg(x1) and directly start writing the new data inside the next "gg" line from now on.
After we make a capture, the label is emptied, the "cancel" button is made invisible.
At this point, we should have found a good location for our label on the form. If that's the case go to the design page, click on the label -> go to properties -> leave the "text" property empty.
Label1.Focus() - removing the focus from the "capture" is done only for esthetical reasons. Not important.

Let's add an operation to the "cancel" button. Go to the design page and double click on button2. Add:
Button2.Visible = False
Label1.Text = ""

-> pressing the "cancel" button makes it invisible and reset's it's text. This will also disable the process of capturing the cursor coordinates, since the second button press on the "capture" button is expecting a visible "cancel" button.

Currently we have a problem that must solve: after a person clicks on the "capture" button, the same button awaits for a keypress BUT the user doesn't have to do that, he can click with the left mouse button on some other object on the form (i.e. inside a textbox) and lose the focus from the "capture" button. After the focus was lost, pressing the "space" button won't press the button1 anymore. This will leave the waiting for "space" process hanging until the mouse is used on either button1 or button2.
We'll have to keep the focus on the "capture" button after it was pressed.

At the bottom of the Timer1 sub, below the "End If" line, add this:
If Button2.Visible = True Then
Button1.Focus()
End If

-> this will keep the focus on the "capture" button every 100 miliseconds. The problem of this is that this will ALSO keep the focus away from the "cancel" button (unless we click really fast). This is inconvenient. We have to be able to retain the focus on the "cancel" button when we want to click on it.
We'll add the code to fix this in the following post.

What happens when we uncheck checkbox1? Inside the checkbox1 sub , below "End If", insert:
If CheckBox1.Checked = False Then
gg(x1) = ""
TextBox1.Lines = gg
End If

-> this will empty the last line of the textbox - the 'active coordinates' line. If you removed:  gg(x1) = "" , and then checked / unchecked the checkbox, you would get like a capture inside of it you didn't want.


    Public Class Form1

    Private x1 As Integer
    Private gg As String()

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    If Button2.Visible = True Then
    x1 = x1 + 1
    Label1.Text = ""
    Button2.Visible = False
    Label1.Focus()
    Exit Sub
    End If
    If CheckBox1.Checked Or CheckBox2.Checked Or CheckBox3.Checked Then
    Label1.Text = "! Scroll with your mouse and then press Space !"
    Button2.Visible = True
    End If
    End Sub

    Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
    If CheckBox1.Checked Then
    Timer1.Enabled = True
    Else
    Timer1.Enabled = False
    End If
    If CheckBox1.Checked = False Then
    gg(x1) = ""
    TextBox1.Lines = gg
    End If
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    If CheckBox1.Checked Then
    ReDim Preserve gg(0 To x1)
    gg(x1) = Cursor.Position.ToString
    TextBox1.Lines = gg
    End If
    If Button2.Visible = True Then
    Button1.Focus()
    End If
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    Button2.Visible = False
    Label1.Text = ""
    End Sub

    End Class


Continuing in the next post.
Go to next post.