Move mouse position, click by code Windows

I am trying to go around HTMLViewer limitations and would like to simulate the mouse.

I already found this to change the mouse position :

[quote=51204:@Mike Charlesworth]For windows see https://www.boxedbyte.com/xippet-124 for the same.
Just add the code to the open event of pushbutton on the modal window and set the position to the centre of the button
[/quote]

#if TargetWin32 Declare Function SetCursorPos Lib "user32" (ByVal x As Integer, ByVal y As Integer) As Integer //========================================== // Set cursor position to top left of screen //========================================== call SetCursorPos(0,0) #endif

Now I am trying to find a way to simulate a click.

I found the mouse_event function in the MS documentation at http://msdn.microsoft.com/en-us/library/windows/desktop/ms646260(v=vs.85).aspx

VOID WINAPI mouse_event( _In_ DWORD dwFlags, _In_ DWORD dx, _In_ DWORD dy, _In_ DWORD dwData, _In_ ULONG_PTR dwExtraInfo );

Apparently all parameters are integers.

Then I found this http://vb-helper.com/howto_move_click_mouse.html

' see the page for all the code. I retained only the part I wanted. ' Move the mouse to its final destination and click it. mouse_event _ MOUSEEVENTF_ABSOLUTE + _ MOUSEEVENTF_MOVE + _ MOUSEEVENTF_LEFTDOWN + _ MOUSEEVENTF_LEFTUP, _ dest_x, dest_y, 0, 0

I already have the snippet from Xippets to move the cursor. Now I need to translate the last block of code to Xojo. This where I am :

[code]Declare sub mouse_event Lib “user32” (ByVal dwFlags As Integer, ByVal dx As Integer, ByVal dy As Integer, ByVal dwData As Integer, ByVal dwExtraInfo As Integer)

//Not so sure const is integer. May have to do dim instead
const MOUSEEVENTF_ABSOLUTE = &h8000
const MOUSEEVENTF_LEFTDOWN = &h2
const MOUSEEVENTF_LEFTUP = &h4
const MOUSEEVENTF_MIDDLEDOWN = &h20
const MOUSEEVENTF_MIDDLEUP = &h40
const MOUSEEVENTF_MOVE = &h1
const MOUSEEVENTF_RIGHTDOWN = &h8
const MOUSEEVENTF_RIGHTUP = &h10
const MOUSEEVENTF_WHEEL = &h800
const MOUSEEVENTF_XDOWN = &h80
const MOUSEEVENTF_XUP = &h100
const MOUSEEVENTF_HWHEEL = &h1000

Dim cur_x As integer
Dim cur_y As integer
Dim dest_x As integer = 150+self.left+1 // value in points
Dim dest_y As integer = 100+self.top+1 //value in points
Dim dx As integer
Dim dy As integer

coords(dest_x,dest_y) //converts points to normalized absolute

call mouse_event(MOUSEEVENTF_ABSOLUTE+MOUSEEVENTF_MOVE+MOUSEEVENTF_LEFTDOWN+MOUSEEVENTF_LEFTUP,dest_x, dest_y, 0, 0)
[/code]

The values dest_x and dest_y to call the API are not in points but in “normalized absolute” form 0 to 65535,65535 being the lower right corner. So I had to figure a conversion between the screen resolution and these coordinates. As the coordinates are relative to 0,0 of the screen, I have to add the left and top of the window. And I don’t know why, the resulting click is 1 pix off horizontally and vertically, so I add that as well.

Sub coords(ByRef x as integer, ByRef y as integer) x = (65535/screen(0).width)*x y = (65535/screen(0).height)*y End Sub

I will appreciate any comment and improvement suggestion. TIA.

Here is the click method :

[code]Sub click(x as integer, y as integer)
#if TargetWin32
Declare sub mouse_event Lib “user32” (ByVal dwFlags As Integer, ByVal dx As Integer, _
ByVal dy As Integer, ByVal dwData As Integer, ByVal dwExtraInfo As Integer)

const MOUSEEVENTF_ABSOLUTE = &h8000
const MOUSEEVENTF_LEFTDOWN = &h2
const MOUSEEVENTF_LEFTUP = &h4
const MOUSEEVENTF_MIDDLEDOWN = &h20
const MOUSEEVENTF_MIDDLEUP = &h40
const MOUSEEVENTF_MOVE = &h1
const MOUSEEVENTF_RIGHTDOWN = &h8
const MOUSEEVENTF_RIGHTUP = &h10
const MOUSEEVENTF_WHEEL = &h800
const MOUSEEVENTF_XDOWN = &h80
const MOUSEEVENTF_XUP = &h100
const MOUSEEVENTF_HWHEEL = &h1000

Dim cur_x As integer
Dim cur_y As integer
Dim dest_x As integer
Dim dest_y As integer
Dim dx As integer
Dim dy As integer

dest_x = (65535/screen(0).width)*x
dest_y = (65535/screen(0).height)*y

call mouse_event(MOUSEEVENTF_ABSOLUTE+MOUSEEVENTF_MOVE+ _ MOUSEEVENTF_LEFTDOWN+MOUSEEVENTF_LEFTUP,dest_x, dest_y, 0, 0)

#Endif

End Sub
[/code]

:slight_smile:

Here is the final method.

To use, call click(x,y,click)

The click parameter is true for a click, false for a simple mouse cursor move. x and y are relative to the screen. So to make it relative to the window, it is necessary to take into account self.left and self.right. The advantage of this method is that it can click all over the screen, not limited to your app, opening automation possibilities.

[code]Sub click(x as integer, y as integer, click as boolean)
#if TargetWin32
if click = true then
Declare sub mouse_event Lib “user32” (ByVal dwFlags As Integer, ByVal dx As Integer, ByVal dy As Integer, ByVal dwData As Integer, ByVal dwExtraInfo As Integer)

  const MOUSEEVENTF_ABSOLUTE = &h8000
  const MOUSEEVENTF_LEFTDOWN = &h2
  const MOUSEEVENTF_LEFTUP = &h4
  const MOUSEEVENTF_MIDDLEDOWN = &h20
  const MOUSEEVENTF_MIDDLEUP = &h40
  const MOUSEEVENTF_MOVE = &h1
  const MOUSEEVENTF_RIGHTDOWN = &h8
  const MOUSEEVENTF_RIGHTUP = &h10
  const MOUSEEVENTF_WHEEL = &h800
  const MOUSEEVENTF_XDOWN = &h80
  const MOUSEEVENTF_XUP = &h100
  const MOUSEEVENTF_HWHEEL = &h1000
  
  Dim cur_x As integer
  Dim cur_y As integer
  Dim dest_x As integer
  Dim dest_y As integer
  Dim dx As integer
  Dim dy As integer
  
  dest_x = (65535/screen(0).width)*x
  dest_y = (65535/screen(0).height)*y
  
  call mouse_event(MOUSEEVENTF_ABSOLUTE+MOUSEEVENTF_MOVE+MOUSEEVENTF_LEFTDOWN+MOUSEEVENTF_LEFTUP,dest_x, dest_y, 0, 0)
else
  Declare Function SetCursorPos Lib "user32" (ByVal x As Integer, ByVal y As Integer) As Integer
  //==========================================
  // Set cursor position to top left of screen
  //==========================================
  call SetCursorPos(x,y)
end if

#Endif

End Sub
[/code]

Thanks Michel.
Works Great.
Lennox