Results 1 to 7 of 7

Thread: Sending a click to exact coordinates in an inactive program

  1. #1

    Thread Starter
    Member
    Join Date
    May 2011
    Posts
    52

    Question Sending a click to exact coordinates in an inactive program

    So I'm trying to send a click of exact coordinates to an inactive program. I've used this code send clicks before and it's worked fine but the coordinates don't seem to be correct because when I enter them in the textboxes for the ovalshape the messagebox won't popup. So my question is, how can I grab the coordinates that work with the click and set them to label1.text?

    Here's the form:


    And here's the complete code:
    Code:
    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
        <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
        Public Shared Function PostMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
        End Function
    
        <DllImport("user32.dll")> _
        Shared Function WindowFromPoint(ByVal pnt As Point) As IntPtr
        End Function
    
        Private point As New Point
        Private lButtonUp As UInteger = &H202
        Private lButtonDown As UInteger = &H201
    
        Private Function returnlParam(ByVal Lo As Short, ByVal Hi As Short) As IntPtr
            Return CInt(Hi) << 16 Or Lo
        End Function
    
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Label1.Text = (Cursor.Position.X - Me.Location.X) & ", " & (Cursor.Position.Y - Me.Location.Y)
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            point = New Point(textbox1.text, textbox2.text)
            Timer2.Enabled = True
        End Sub
    
        Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
            Dim hWnd As IntPtr
            Dim wParam As IntPtr
            Dim lParam As IntPtr
    
            hWnd = WindowFromPoint(point)
            wParam = CUInt(Keys.LButton)
            lParam = returnlParam(point.X, point.Y)
    
            PostMessage(hWnd, lButtonDown, wParam, lParam)
            PostMessage(hWnd, lButtonUp, wParam, lParam)
    
            MsgBox("clicked")
    
            Timer2.Enabled = False
        End Sub
    
        Private Sub OvalShape1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OvalShape1.Click
            MsgBox("clicked me!")
        End Sub
    End Class
    This is the code I'm using to get the coordinates currently:
    Code:
    Label1.Text = (Cursor.Position.X - Me.Location.X) & ", " & (Cursor.Position.Y - Me.Location.Y)
    Last edited by code; May 10th, 2013 at 11:28 PM.

  2. #2
    Fanatic Member
    Join Date
    Feb 2013
    Posts
    985

    Re: Sending a click to exact coordinates in an inactive program

    if you want to get the point using the forms events

    in form_clickevent or any click event for that matter
    use the event arguments, the location of the click is there

    Code:
    Private Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Click
            Dim message As String
    
            message = DirectCast(e, System.Windows.Forms.MouseEventArgs).X & ","  & DirectCast(e, System.Windows.Forms.MouseEventArgs).Y
    
            MessageBox.Show(message)
        End Sub
    Yes!!!
    Working from home is so much better than working in an office...
    Nothing can beat the combined stress of getting your work done on time whilst
    1. one toddler keeps pressing your AVR's power button
    2. one baby keeps crying for milk
    3. one child keeps running in and out of the house screaming and shouting
    4. one wife keeps nagging you to stop playing on the pc and do some real work.. house chores
    5. working at 1 O'clock in the morning because nobody is awake at that time
    6. being grossly underpaid for all your hard work


  3. #3

    Thread Starter
    Member
    Join Date
    May 2011
    Posts
    52

    Re: Sending a click to exact coordinates in an inactive program

    Quote Originally Posted by GBeats View Post
    if you want to get the point using the forms events

    in form_clickevent or any click event for that matter
    use the event arguments, the location of the click is there

    Code:
    Private Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Click
            Dim message As String
    
            message = DirectCast(e, System.Windows.Forms.MouseEventArgs).X & ","  & DirectCast(e, System.Windows.Forms.MouseEventArgs).Y
    
            MessageBox.Show(message)
        End Sub
    That still does not work. Using that code I found a point on top of the ovalshape is 110,110. However when I enter this and hit the buttons, nothing happens.

  4. #4
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    Re: Sending a click to exact coordinates in an inactive program

    So I'm trying to send a click of exact coordinates to an inactive program.
    Why? There must be more to this than you''re telling us because frankly the whole exercise appears to be completely pointless. If you tell us what you're ultimately trying to achieve we might be able to make useful suggestions.

    Your main problem is that you make no distinction between screen co-ordinates, the active client co-ordinates, and the inactive client co-ordinates, and more importantly which of the commands uses which of them. An inactive form is particularly tricky in that respect.
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  5. #5

    Thread Starter
    Member
    Join Date
    May 2011
    Posts
    52

    Re: Sending a click to exact coordinates in an inactive program

    Quote Originally Posted by dunfiddlin View Post
    Why? There must be more to this than you''re telling us because frankly the whole exercise appears to be completely pointless. If you tell us what you're ultimately trying to achieve we might be able to make useful suggestions.

    Your main problem is that you make no distinction between screen co-ordinates, the active client co-ordinates, and the inactive client co-ordinates, and more importantly which of the commands uses which of them. An inactive form is particularly tricky in that respect.
    It appears pointless because it is pointless and is a challenge given to me by my professor. Alright I think I understand what you're saying. So the active coordinates are different from the inactive coordinates. But why? If I find the coords while the form is active then click on something else (without moving the form) shouldn't the coords be the same?

  6. #6
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    Re: Sending a click to exact coordinates in an inactive program

    When the form is inactive you cannot seek a point on the form, you must seek a point on the screen. Now there are two problems. If the form has become covered then even an accurate click won't work. And you cannot convert the form co-ordinates to a screen point using PointToScreen because the form's co-ordinate system is not accessible. So you have to record the screen position while the form is active, ensure that the form is not moved or covered, then pray that the cursor isn't being moved when the timing tick occurs because it will immediately override your cursor positioning and that the form is woken in time to process the events responding to the click.

    For all those reasons you simply wouldn't do this in real life. If you wanted to access an inactive form programatically you would always activate it first so that you can be sure of where it's at. And you would only do a move cursor and click simulation as a last resort in any case.

    One thing I did notice, is that you are using the top left corner as your cursor target which is always a bad idea as it only takes an error of 1 pixel in 3/4 of all possible directions to miss the control altogether. You should always aim for a point inside the control, preferably at its centre.
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  7. #7

    Thread Starter
    Member
    Join Date
    May 2011
    Posts
    52

    Re: Sending a click to exact coordinates in an inactive program

    Quote Originally Posted by dunfiddlin View Post
    When the form is inactive you cannot seek a point on the form, you must seek a point on the screen. Now there are two problems. If the form has become covered then even an accurate click won't work. And you cannot convert the form co-ordinates to a screen point using PointToScreen because the form's co-ordinate system is not accessible. So you have to record the screen position while the form is active, ensure that the form is not moved or covered, then pray that the cursor isn't being moved when the timing tick occurs because it will immediately override your cursor positioning and that the form is woken in time to process the events responding to the click.

    For all those reasons you simply wouldn't do this in real life. If you wanted to access an inactive form programatically you would always activate it first so that you can be sure of where it's at. And you would only do a move cursor and click simulation as a last resort in any case.

    One thing I did notice, is that you are using the top left corner as your cursor target which is always a bad idea as it only takes an error of 1 pixel in 3/4 of all possible directions to miss the control altogether. You should always aim for a point inside the control, preferably at its centre.
    Thanks for the explanation. I think my professor just assigned me this because I'm ahead of my class and he was looking to stump me. Anyways I found a solution to my issue.

    me.cursor.position returns the correct points to use with the postmessage function. However upon using it (me.cursor.position.tostring) I got a warning that reads:
    Code:
    Access of shared member, constant member, enum member or nested type through an instance; qualifying expression will not be evaluated.
    My app still runs fine and displays the coordinates so I'm looking into what this means. Thanks again for responding.

    And I know I didn't ask for this (and neither did my professor), but to click the control without a coordinate you can just use the control's handle in the hWnd parameter.
    Last edited by code; May 11th, 2013 at 10:25 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width