Ok, heres code I created in a console app
[VB]
Imports System
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Windows.Forms
Imports System.ComponentModel
Module Module1
<DllImport("user32.dll", SetLastError:=True)> _
Public Function FindWindowA(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Public Function SetForegroundWindow(ByVal hWnd As IntPtr) As Boolean
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Public Sub BringWindowToTop(ByVal window As IntPtr)
End Sub
<DllImport("user32.dll", SetLastError:=True)> _
Public Function FindWindowExA(ByVal hWnd1 As IntPtr, ByVal hWnd2 As Integer, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Public Function GetWindowRect(ByVal hwnd As IntPtr, <Out()> ByRef rectangle As Rectangle) As Boolean
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Public Function TranslateMessage(ByRef lpMsg As Message) As Integer
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Public Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As UIntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Public Sub mouse_event(ByVal dwFlags As Integer, ByVal dx As Integer, ByVal dy As Integer, ByVal dwData As Integer, ByVal dwExtraInfo As IntPtr)
End Sub
Private Const WM_KEYDOWN = &H100
Private Const WM_KEYUP = &H101
Public Const WM_CHAR = &H102
<STAThread()> _
Sub Main()
Try
Dim ret As Integer
Dim Rec1 As Rectangle = New Rectangle
Find Window
Dim hwnd As IntPtr = FindWindowA(vbNullString, "Untitled - NotePad") Using Notepad as example to real program
Dim PTools_hWnd As IntPtr = FindWindowExA(hwnd, 0, "Edit", vbNullString) finds child windows
Dim myMsg As Message = New Message
Set the send message Structure, works great for keystrokes
myMsg.HWnd = PTools_hWnd
myMsg.Msg = WM_KEYDOWN
myMsg.WParam = New IntPtr(Keys.L)
myMsg.LParam = IntPtr.Zero
ret = TranslateMessage(myMsg)
Get Left, Right, Top and Bottom of Form1
Dim success As Boolean = GetWindowRect(hwnd, Rec1)
Debug.WriteLine(String.Format("Rec1={0}", Rec1))
If Not success Then
Throw New Win32Exception
End If
GetWindowRect returning zero values
Tried both hwnd & PTools_hWnd
MoveCursor((Rec1.Left + 25), (Rec1.Top + 25))
If Not SetForegroundWindow(hwnd) Then
Throw New Win32Exception
End If
mouse_event(2, 0, 0, 0, IntPtr.Zero)
mouse_event(4, 0, 0, 0, IntPtr.Zero)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub MoveCursor(ByVal Fx As Integer, ByVal Fy As Integer)
Dim newPoint As Point = New Point(Fx, Fy)
Debug.WriteLine(String.Format("Old mouse position = {0}.", Cursor.Position))
Debug.WriteLine(String.Format("Moving mouse to {0}.", newPoint))
Cursor.Position = newPoint
Debug.Assert(newPoint.Equals(Cursor.Position), "The cursor position was not set to the desired location.")
End Sub
End Module
[/VB]
There are a few differences between your code and mine, the most important being the declaration of the native methods such as GetWindowRect. Note that I declare my methods using <DLLImport> and use the SetLastError attribute because all of those imported functions modify the error code (according to the msdn documentation). I needed to use
BringWindowToTop to make sure the notepad window was visible before doing any mouse clicking otherwise the click could be sent to the wrong screen.
I also use the
Message Structure instead of the MSG structure you declared. Nothing major, but its less code that needs to be maintained =]
I also use
Debug.WriteLine to write debug info to any listeners (the output window in vs.net always listens) and I use
Debug.Assert to make sure the cursor position was moved to the desired location.