|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Trouble with mouse clickto a given position and do a click, the application gets the focus. That is what this simple code should illustrate: Dim pt As Point Dim wnd As IntPtr Const WM_LBUTTONUP = &H202 '//LButton up Const WM_LBUTTONDOWN = &H201 '//LButton down pt.X = 450 pt.Y = 200 Windows.Forms.Cursor.Position = pt wnd = WindowFromPoint(pt.X, pt.Y) Call SendMessage(wnd, WM_LBUTTONDOWN, 0, 0&) Call SendMessage(wnd, WM_LBUTTONUP, 0, 0&) It moves the cursor, but the application beneith doesn't get focus, as it would had i clicked on that position manually. What am I missing out on? Regards /Snedker Morten Snedker wrote:
Show quoteHide quote > If I have a number of random applications open, move the mouse cursor I suggest you fire up Spy++ and then test your scenario again. When> to a given position and do a click, the application gets the focus. > > That is what this simple code should illustrate: > > Dim pt As Point > Dim wnd As IntPtr > > Const WM_LBUTTONUP = &H202 '//LButton up > Const WM_LBUTTONDOWN = &H201 '//LButton down > > pt.X = 450 > pt.Y = 200 > > Windows.Forms.Cursor.Position = pt > > wnd = WindowFromPoint(pt.X, pt.Y) > Call SendMessage(wnd, WM_LBUTTONDOWN, 0, 0&) > Call SendMessage(wnd, WM_LBUTTONUP, 0, 0&) > > > It moves the cursor, but the application beneith doesn't get focus, as > it would had i clicked on that position manually. What am I missing > out on? > you click on an application, besides the mouse messages, there are other messages sent, such as WM_ACTIVATE. If this is a continuation of our other thread - you didn't mention you
wanted it to receive focus too, just that you wanted it clicked and without moving the mouse. :) Chris' reply is correct. But if the mouse pointer is in, or will be moved to, the proper location, this is much easier: Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Int32, ByVal dX As Int32, ByVal dy As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo As Int32) mouse_event MOUSEEVENTF_LEFTDOWN + MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 As Tesla... suggests indirectly, there are limited ways to simulate
mouse events in Windows. We have both mouse_events (deprecated) and SendInput -- neither of which are managed code. I have searched the net at length and attacked this "simple" problem for many hours so I'm hoping my efforts will pay off for you. This is a VB.NET 2005 test bed solution that allows you to play with mouse_event, SendInput, and OnMouse... techniques. The OnMouse... approach has yet to yield fruits. Either other approach (comment out the other 2; uncomment the METHOD desired) work quite well. This example expects a form called frmMain, a picture box called picClick, three buttons: (btnClickStart, btnClick, btnScreen), and a multi-line text box called txtResults. This is an amalgam primarily based on http://vb-helper.com/howto_move_click_mouse.html and http://www.vbforums.com/showthread.php?t=398899 -- I'm trying to update http://www.pinvoke.net/ to share this information. Also, this code shows how to simulate a "union struct" in VB.NET -- I was pleased to figure this out. Rick Valstar Star Consulting r + last name + at + gmail + dot + com Here's the code: Option Explicit On Imports System.Runtime.InteropServices Public Class frmMain 'Const METHOD As String = "mouse_event" 'Const METHOD As String = "OnMouse" Const METHOD As String = "SendInput" Const INPUT_MOUSE As Int32 = 0 Const INPUT_KEYBOARD As Int32 = 1 Const INPUT_HARDWARE As Int32 = 2 Const MOUSEEVENTF_MOVE As Int32 = &H1 ' mouse move Const MOUSEEVENTF_LEFTDOWN As Int32 = &H2 ' left button down Const MOUSEEVENTF_LEFTUP As Int32 = &H4 ' left button up Const MOUSEEVENTF_RIGHTDOWN As Int32 = &H8 ' right button down Const MOUSEEVENTF_RIGHTUP As Int32 = &H10 ' right button up Const MOUSEEVENTF_MIDDLEDOWN As Int32 = &H20 ' middle button down Const MOUSEEVENTF_MIDDLEUP As Int32 = &H40 ' middle button up Const MOUSEEVENTF_ABSOLUTE As Int32 = &H8000 ' absolute move Const MOUSEEVENTF_WHEEL As Int32 = &H800 ' wheel button rolled Private Structure MOUSEINPUT Dim dx As Int32 Dim dy As Int32 Dim mouseData As Int32 Dim dwFlags As Int32 Dim time As Int32 Dim dwExtraInfo As IntPtr End Structure Private Structure KEYBDINPUT Dim wVk As Int16 Dim wScan As Int16 Dim dwFlags As Int32 Dim time As Int32 Dim dwExtraInfo As IntPtr End Structure Private Structure HARDWAREINPUT Dim uMsg As Int32 Dim wParamL As Int16 Dim wParamH As Int16 End Structure <StructLayout(LayoutKind.Explicit)> _ Private Structure INPUT <FieldOffset(0)> Dim dwType As Int32 ' simulate a union struct (C) or a variant record (Pascal) <FieldOffset(4)> Dim mi As MOUSEINPUT <FieldOffset(4)> Dim ki As KEYBDINPUT <FieldOffset(4)> Dim hi As HARDWAREINPUT End Structure Private Declare Auto Sub mouse_event Lib "user32.dll" (ByVal dwFlags As Int32, ByVal dx As Int32, ByVal dy As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo As IntPtr) <DllImport("user32.dll", SetLastError:=True)> _ Private Shared Function SendInput(ByVal nInputs As Int32, ByRef pInputs As INPUT, ByVal cbSize As Int32) As Int32 End Function Private Declare Auto Sub SetLastError Lib "kernel32.dll" (ByVal dwErrCode As Int32) Sub ClickMouse(ByVal MouseButton As Integer) Dim inputevents As New INPUT inputevents.mi.dx = 0 inputevents.mi.dy = 0 inputevents.mi.mouseData = 0 inputevents.mi.dwFlags = MouseButton inputevents.mi.time = 0 inputevents.dwType = INPUT_MOUSE SetLastError(0) Dim result As Integer = SendInput(1, inputevents, Marshal.SizeOf(GetType(INPUT))) Dim lasterror As Integer = Marshal.GetLastWin32Error Debug.WriteLine("Result: " & result) Debug.WriteLine("LastError: " & lasterror & " " & New System.ComponentModel.Win32Exception(lasterror).Message) End Sub Sub btnClickStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClickStart.Click txtResults.AppendText("***** btnClickStart *****" & vbCrLf) 'move mouse to the start button Dim pt As New System.Drawing.Point(20, Screen.PrimaryScreen.Bounds.Height - 20) 'Dim pt As Point = picClicker.PointToScreen(New Point(picClicker.ClientRectangle.Width / 2, picClicker.ClientRectangle.Height / 2)) Debug.WriteLine("pt " & pt.X & " " & pt.Y) System.Windows.Forms.Cursor.Position = pt Windows.Forms.Application.DoEvents() ClickMouse(MOUSEEVENTF_LEFTDOWN) 'press left button ClickMouse(MOUSEEVENTF_LEFTUP) 'release left button End Sub Private Sub btnClick_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles btnClick.Click Dim cur_x As Single Dim cur_y As Single Dim dest_x As Single Dim dest_y As Single txtResults.AppendText("***** btnClick *****" & vbCrLf) ' mouse_event moves in a coordinate system where (0, 0) is in the upper left corner and (65535,65535) is in the lower right corner. ' Get the current mouse coordinates and convert them into this new system. cur_x = System.Windows.Forms.Cursor.Position.X * 65535 / System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width cur_y = System.Windows.Forms.Cursor.Position.Y * 65535 / System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height ' Convert the coordinates of the center of the picClicker PictureBox into this new system. Dim pt As Point = picClicker.PointToScreen(New Point(picClicker.ClientRectangle.Width / 2, picClicker.ClientRectangle.Height / 2)) 'Dim pt As New System.Drawing.Point(20, Screen.PrimaryScreen.Bounds.Height - 20) dest_x = pt.X * 65535 / System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width dest_y = pt.Y * 65535 / System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height txtResults.AppendText("From " & System.Windows.Forms.Cursor.Position.X & " " & System.Windows.Forms.Cursor.Position.Y & " to " & pt.X & " " & pt.Y & vbCrLf) txtResults.AppendText("From " & cur_x & " " & cur_y & " to " & dest_x & " " & dest_y & vbCrLf) ' Move the mouse to its final destination and click it. Select Case METHOD Case "OnMouse" System.Windows.Forms.Cursor.Position = pt Windows.Forms.Application.DoEvents() 'Dim eMouseMove As New System.Windows.Forms.MouseEventArgs(Windows.Forms.MouseButtons.None, 0, pt.X, pt.Y, 0) 'Me.OnMouseMove(eMouseMove) Dim eMouseButton As New System.Windows.Forms.MouseEventArgs(Windows.Forms.MouseButtons.Left, 1, 0, 0, 0) Me.OnMouseDown(eMouseButton) Me.OnMouseUp(eMouseButton) Case "mouse_event" mouse_event(MOUSEEVENTF_ABSOLUTE + MOUSEEVENTF_MOVE + MOUSEEVENTF_LEFTDOWN + MOUSEEVENTF_LEFTUP, dest_x, dest_y, 0, 0) Case "SendInput" Dim pInputs(0 To 2) As INPUT With pInputs(0) .dwType = INPUT_MOUSE .mi.dx = dest_x .mi.dy = dest_y .mi.mouseData = 0 .mi.dwFlags = MOUSEEVENTF_ABSOLUTE + MOUSEEVENTF_MOVE .mi.time = 0 .mi.dwExtraInfo = IntPtr.Zero End With With pInputs(1) .dwType = INPUT_MOUSE .mi.dx = 0 .mi.dy = 0 .mi.mouseData = 0 .mi.dwFlags = MOUSEEVENTF_LEFTDOWN .mi.time = 0 .mi.dwExtraInfo = IntPtr.Zero End With With pInputs(2) .dwType = INPUT_MOUSE .mi.dx = 0 .mi.dy = 0 .mi.mouseData = 0 .mi.dwFlags = MOUSEEVENTF_LEFTUP .mi.time = 0 .mi.dwExtraInfo = IntPtr.Zero End With 'System.Windows.Forms.Cursor.Position = pt 'Windows.Forms.Application.DoEvents() 'Debug.WriteLine("Size: " & Marshal.SizeOf(pInputs(0)) & " " & Marshal.SizeOf(GetType(INPUT))) SetLastError(0) Debug.WriteLine("Result: " & SendInput(3, pInputs(0), Marshal.SizeOf(GetType(INPUT)))) Debug.WriteLine("LastError: " & Marshal.GetLastWin32Error & " " & New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error).Message) 'SetLastError(0) 'Debug.WriteLine("Result: " & SendInput(1, pInputs(1), Marshal.SizeOf(GetType(INPUT)))) 'Debug.WriteLine("LastError: " & Marshal.GetLastWin32Error & " " & New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error).Message) 'SetLastError(0) 'Debug.WriteLine("Result: " & SendInput(1, pInputs(2), Marshal.SizeOf(GetType(INPUT)))) 'Debug.WriteLine("LastError: " & Marshal.GetLastWin32Error & " " & New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error).Message) Case Else Beep() End Select 'Windows.Forms.Application.DoEvents() 'My.Application.DoEvents() End Sub Private Sub btnScreen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnScreen.Click Dim I As Integer Dim Screens() As System.Windows.Forms.Screen = System.Windows.Forms.Screen.AllScreens txtResults.AppendText("***** btnScreen *****" & vbCrLf) For I = 0 To Screens.GetUpperBound(0) txtResults.AppendText("Device Name: " + Screens(I).DeviceName & vbCrLf) txtResults.AppendText("Bounds: " + Screens(I).Bounds.ToString() & vbCrLf) txtResults.AppendText("Type: " + Screens(I).GetType().ToString() & vbCrLf) txtResults.AppendText("Working Area: " + Screens(I).WorkingArea.ToString() & vbCrLf) txtResults.AppendText("Primary Screen: " + Screens(I).Primary.ToString() & vbCrLf) Next I End Sub Private Sub picClicker_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles picClicker.Click txtResults.AppendText("picClicker_Click" & vbCrLf) End Sub Private Sub picClicker_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picClicker.MouseDown txtResults.AppendText("picClicker_MouseDown (" & e.X & ", " & e.Y & ")" & vbCrLf) End Sub Private Sub picClicker_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picClicker.MouseUp txtResults.AppendText("picClicker_MouseUp (" & e.X & ", " & e.Y & ")" & vbCrLf) End Sub Private Sub frmMain_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Click txtResults.AppendText("frmMain_Click" & vbCrLf) End Sub Private Sub frmMain_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown txtResults.AppendText("frmMain_MouseDown (" & e.X & ", " & e.Y & ")" & vbCrLf) End Sub Private Sub frmMain_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp txtResults.AppendText("frmMain_MouseUp (" & e.X & ", " & e.Y & ")" & vbCrLf) End Sub End Class
class library
How to Load string into mshtml object? Detect WiFi Networks what method to use to add 1 day to a date (hotel reservation for one night by clicking on calender) Adding rows to a data table: Rows do not show up PLEASE HELP - Executable properties - right click how to compare two date variables? How do I calculate the date of the previous day given a date ( in "MM/dd/yy" format) Variable precision How to send output ticket Printer(VB005) |
|||||||||||||||||||||||