I want to send a leftbutton-mouseclick to a (specific) program but it doesn't work. when i tried my code on several other apps it worked without any major changes.
this is my Declaration:
Public Class Win32
#Region "Methods And Functions Declaration"
Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal IpClassName As String, ByVal IpWindowName As String) As Int32
Public Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hwnd As Int32) As Int32
Public Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As Int32, ByVal hWnd2 As Int32, ByVal lpsz1 As String, ByVal lpsz2 As String) As Int32
Public Declare Function EnumChildWindows Lib "user32.dll" (ByVal hWndParent As Int32, ByVal lpEnumFunc As Int32, ByVal lParam As Int32) As Int32
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByRef lParam As Int32) As Int32
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByRef lParam As String) As Int32
#End Region
#Region "Messages"
Public Const BM_CLICK As Int32 = &HF5
Public Const WM_NCLBUTTONDOWN As Int32 = &HA1
Public Const WM_NCHITTEST As Int32 = &H84
Public Const WM_NCLBUTTONDBLCLK As Int32 = &HA3
Public Const WM_NCLBUTTONUP As Int32 = &HA2
Public Const WM_SETFOCUS As Long = &H7
Public Const WM_SETTEXT As Long = &HC
Public Const WM_NCRBUTTONDOWN As Int32 = &HA4
#End Region
the actual code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Druck Eingeben
Dim Hwnd As Integer = Win32.FindWindow(Nothing, "V1.22 BMTS Prüfstand 2")
If (Not Hwnd = 0) Then
Dim HwndInfo As Integer = Win32.FindWindowEx(Hwnd, Nothing, "TGroupBox", "Info")
If Not HwndInfo = 0 Then
Dim ccHwnd As Integer = Win32.FindWindowEx(HwndInfo, Nothing, "TPanel", Nothing)
If Not ccHwnd = 0 Then
Dim cccHwnd As Integer = Win32.FindWindowEx(ccHwnd, Nothing, "Tedit", Nothing)
If Not cccHwnd = 0 Then
Win32.SetForegroundWindow(cccHwnd)
SendKeys.Send("990")
Else
MessageBox.Show("Bitte Starte erst die Programme")
End If
Else
MessageBox.Show("Bitte Starte erst die Programme")
End If
Else
MessageBox.Show("Bitte Starte erst die Programme")
End If
Win32.SetForegroundWindow(HwndInfo)
SendKeys.Send("999")
Else
MessageBox.Show("Bitte Starte erst die Programme")
End If
'Startbutton Klicken
Dim HwndFunktion As Integer = Win32.FindWindowEx(Hwnd, Nothing, "TGroupBox", "Funktion")
If Not HwndFunktion = 0 Then
Dim cHwnd As Integer = Win32.FindWindowEx(HwndFunktion, Nothing, "TButton", "S T A R T")
If Not cHwnd = 0 Then
Win32.SetForegroundWindow(cHwnd)
Win32.SendMessage(cHwnd, Win32.WM_SETFOCUS, 0, 0)
Win32.SendMessage(cHwnd, Win32.WM_NCLBUTTONDBLCLK, 0, 0)
Win32.SendMessage(cHwnd, Win32.WM_NCLBUTTONDBLCLK, 0, 0)
Win32.SendMessage(cHwnd, Win32.WM_NCLBUTTONDOWN, 0, 0)
Win32.SendMessage(cHwnd, Win32.WM_SETTEXT, 0, "6")
Else
MessageBox.Show("Bitte Starte erst die Programme")
End If
Else
MessageBox.Show("Bitte Starte erst die Programme")
End If
End Sub
To the Program itself: It runs on an old test bench, on win 7.
I think it depends on .net 3.5 but i don't have detailed information about it.
As a test, i filled a textbox with my code and even changed the label of the button. Just the click function doesn't work.
First I tried in with mouse positioning, now directly with the handles.
It doesn't work either way.
Please remember, the code works fine on a few tested Programs (except the one I need it for).
Related
I'm trying to pass text to a 3rd party program but running into a snag.
I have isolated the Class Handler ID inside my program,validated with the messagebox. However, when I try sending it text, I get a run time error.
Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Int32) As Int32
Public Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As Int32, ByVal hWnd2 As Int32, ByVal lpsz1 As String, ByVal lpsz2 As String) As Int32
Dim hwnd As Integer
Dim hwindow2 As Integer
Dim main_view As Integer
Dim sub_window As Integer
Public Const WM_SETTEXT = &H0
And
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
hwindow2 = FindWindow(vbNullString, "Trace")
main_view = FindWindowEx(hwindow2, 0&, "#32770", vbNullString)
System.Threading.Thread.Sleep(10)
sub_window = FindWindowEx(main_view, 0&, "Edit", vbNullString)
MessageBox.Show(main_view)
MessageBox.Show(sub_window)
Call SendMessage(sub_window, WM_SETTEXT, 0, "test")
End Sub
Any help would be appreciated.
Thanks
you might consider using PostMessage(), it is an asynchronous method and it won't wait for the response from the receiving end. while SendMessage method is synchronous, it 'does not return until the window procedure has processed the message'.
see suggestions from post here
it is also good to indicate the error message to better understand the problem.
I'm using this code to get a list of open windows:
Delegate Function EnumWindowDelegate(ByVal hWnd As IntPtr, ByVal Lparam As IntPtr) As Boolean
Private Callback As EnumWindowDelegate = New EnumWindowDelegate(AddressOf EnumWindowProc)
Private Function EnumWindowProc(ByVal hWnd As IntPtr, ByVal Lparam As IntPtr) As Boolean
If IsWindowVisible(hWnd) Then
Dim TheLength As Integer = GetWindowTextLengthA(hWnd)
Dim TheReturn(TheLength * 2) As Byte
GetWindowText(hWnd, TheReturn, TheLength + 1)
Dim TheText As String = ""
For x = 0 To (TheLength - 1) * 2
If TheReturn(x) <> 0 Then
TheText &= Chr(TheReturn(x))
End If
Next
If TheText <> "" Then
ListBox1.Items.Add(TheText & " (" & CStr(hWnd) & ")")
End If
End If
Return True
End Function
Private Declare Function EnumWindows Lib "User32.dll" (ByVal WNDENUMPROC As EnumWindowDelegate, ByVal lparam As IntPtr) As Boolean
Private Declare Auto Function GetWindowText Lib "User32.dll" (ByVal Hwnd As IntPtr, ByVal Txt As Byte(), ByVal Lng As Integer) As Integer
Private Declare Function IsWindowVisible Lib "User32.dll" (ByVal hwnd As IntPtr) As Boolean
Private Declare Function GetWindowTextLengthA Lib "User32.dll" (ByVal hwnd As IntPtr) As Integer
Usage: EnumWindows(Callback, IntPtr.Zero)
It works BUT if a window with a greek title is opened ex. 'Μουσική' this code outputs 'œ¿Åùº® '. As you can see something is wrong. Is there a way to fix this?
P.S. Sorry for my bad English :)
Ok I think i found the solution: Use GetWindowTextA instead of GetWindowText.
#Trevor suggested this in the comments of the question and I tried it but it didn't work. Somehow I managed to make it work.
Thanks to everybody who tried to help :). Here is the working code:
Delegate Function EnumWindowDelegate(ByVal hWnd As IntPtr, ByVal Lparam As IntPtr) As Boolean
Private Callback As EnumWindowDelegate = New EnumWindowDelegate(AddressOf EnumWindowProc)
Private Function EnumWindowProc(ByVal hWnd As IntPtr, ByVal Lparam As IntPtr) As Boolean
If IsWindowVisible(hWnd) Then
Dim TheLength As Integer = GetWindowTextLengthA(hWnd)
Dim TheReturn(TheLength * 2) As Byte
GetWindowText(hWnd, TheReturn, TheLength + 1)
Dim TheText As String = ""
For x = 0 To (TheLength - 1) * 2
If TheReturn(x) <> 0 Then
TheText &= Chr(TheReturn(x))
End If
Next
If Not TheText = "" Then
ListBox1.Items.Add(TheText & " (" & CStr(hWnd) & ")")
End If
End If
Return True
End Function
Private Declare Function EnumWindows Lib "User32.dll" (ByVal WNDENUMPROC As EnumWindowDelegate, ByVal lparam As IntPtr) As Boolean
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal Hwnd As IntPtr, ByVal Txt As Byte(), ByVal Lng As Integer) As Integer
Private Declare Function IsWindowVisible Lib "User32.dll" (ByVal hwnd As IntPtr) As Boolean
Private Declare Function GetWindowTextLengthA Lib "User32.dll" (ByVal hwnd As IntPtr) As Integer
i try to make automatic key presser that make minimized game client do order for me while i work in other thing (aion game client) but nothing work here is the code i use please tell me what is wrong with it
Const WM_SETTEXT As Long = &HC
Const GW_CHILD As Long = 5
Declare Function GetWindow Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal uCmd As Integer) As IntPtr
Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr 'Int32
Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" ( _
ByVal hWnd As IntPtr, _
ByVal wMsg As Int32, _
ByVal wParam As Int32, _
ByVal lParam As String) As Int32
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim hWnd1 As IntPtr = FindWindow("AIONClientWndClass1.0", "AION Client")
Dim hWndR2 As IntPtr = GetWindow(hWnd1, GW_CHILD)
SendMessage(hWndR2, WM_SETTEXT, 0, "h")
End Sub
this is the code i use it must show window in the game when i click button1 , but nothing happen
i use visual studio 2013 and windows 10 64 bit
here is my wrong
1st my app need to run as administrator
2nd have to set target cpu to 86x
3rd i fixed my code , and here it is
Const WM_SETTEXT As Long = &HC
Const GW_CHILD = 5
Const WM_KEYDOWN As Integer = &H100
Const WM_KEYUP As Integer = &H101
Declare Function GetWindow Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal uCmd As Integer) As IntPtr
Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr 'Int32
Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr,ByVal wMsg As Int32,ByVal wParam As Int32,ByVal lParam As IntPtr) As IntPtr
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim _hndl As IntPtr = FindWindow("AIONClientWndClass1.0", "AION Client")
SendMessage(_hndl, WM_KEYDOWN, &H55, 0)
End Sub
&H55 is virtual key code = u
I can't figure out how to make my ComboBox (which lists all open windows(I can see these already)) to make my form type on that selected window. I just can't make it so when screen1 is selected, it clicks on that screen.
Example:
I have 2 different forms open.
Form (1) clicks on a specified screen. (screen1)
Form (2) clicks on a different specified screen. (screen2)
The forms are the same program just opened twice.
I want my form to be able to click on a certain screen even if it's not open.
Imports System.Runtime.InteropServices
Imports System.Diagnostics
Public Class W1
Public Declare Function EnumWindows Lib "user32.dll" (ByVal lpEnumFunc As EnumWindowsProc, ByVal lParam As Int32) As Int32
Public Declare Function IsWindowVisible Lib "user32.dll" (ByVal hwnd As IntPtr) As Boolean
Public Delegate Function EnumWindowsProc(ByVal hwnd As IntPtr, ByVal lParam As Int32) As Boolean
Public Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As Int32) As Int32
Public Declare Function GetWindowTextLength Lib "user32.dll" Alias "GetWindowTextLengthA" (ByVal hwnd As IntPtr) As Int32
Public Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hwnd As IntPtr, ByVal nIndex As Int32) As Int32
Public Declare Function GetParent Lib "user32.dll" (ByVal intptr As IntPtr) As IntPtr
Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
Public Property SelectedItem As Object
Public Const GWL_HWNDPARENT As Int32 = -8
Private newwindowlist As List(Of String)
Private newhandlelist As List(Of IntPtr)
Private Structure RECT
Public left As Integer
Public top As Integer
Public right As Integer
Public bottom As Integer
Public Sub New(ByVal _left As Integer, ByVal _top As Integer, ByVal _right As Integer, ByVal _bottom As Integer)
left = _left
top = _top
right = _right
bottom = _bottom
End Sub
End Structure
Private Function EnumWinProc(ByVal hwnd As IntPtr, ByVal lParam As Int32) As Boolean
If IsWindowVisible(hwnd) Then
If GetParent(hwnd) = IntPtr.Zero Then
If GetWindowLong(hwnd, GWL_HWNDPARENT) = 0 Then
Dim str As String = String.Empty.PadLeft(GetWindowTextLength(hwnd) + 1)
GetWindowText(hwnd, str, str.Length)
If Not String.IsNullOrEmpty(str.Substring(0, str.Length - 1)) Then
newwindowlist.Add(str.Substring(0, str.Length - 1))
End If
End If
End If
End If
EnumWinProc = True
End Function
Private Sub RefreshWindowList()
newwindowlist = New List(Of String)
EnumWindows(AddressOf EnumWinProc, CInt(True))
End Sub
And
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
RefreshWindowList()
For Each item As String In newwindowlist
ComboBox1.Items.Add(item)
ComboBox1.SelectedItem = Convert.ToInt64(GWL_HWNDPARENT)
Next
End Sub
I'm attempting to intercept and interrupt mouse events. Lets say I wanted to disable the right mouse button down event, or even the mouse move event. I haven't been able to figure out the interrupting part.
I am using the (I assume pretty widely used) following code for Global Hooking of the mouse.
Private Structure MSLLHOOKSTRUCT
Public pt As Point
Public mouseData As Int32
Public flags As Int32
Public time As Int32
Public extra As IntPtr
End Structure
Private _mouseHook As IntPtr
Private Const WH_MOUSE_LL As Int32 = 14
Private Delegate Function MouseHookDelegate(ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32
<MarshalAs(UnmanagedType.FunctionPtr)> Private _mouseProc As MouseHookDelegate
Private Declare Function SetWindowsHookExW Lib "user32.dll" (ByVal idHook As Int32, ByVal HookProc As MouseHookDelegate, ByVal hInstance As IntPtr, ByVal wParam As Int32) As IntPtr
Private Declare Function UnhookWindowsHookEx Lib "user32.dll" (ByVal hook As IntPtr) As Boolean
Private Declare Function CallNextHookEx Lib "user32.dll" (ByVal idHook As Int32, ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32
Private Declare Function GetCurrentThreadId Lib "kernel32.dll" () As Integer
Private Declare Function GetModuleHandleW Lib "kernel32.dll" (ByVal fakezero As IntPtr) As IntPtr
Public Function HookMouse() As Boolean
Debug.Print("Mouse Hooked")
If _mouseHook = IntPtr.Zero Then
_mouseProc = New MouseHookDelegate(AddressOf MouseHookProc)
_mouseHook = SetWindowsHookExW(WH_MOUSE_LL, _mouseProc, GetModuleHandleW(IntPtr.Zero), 0)
End If
Return _mouseHook <> IntPtr.Zero
End Function
Public Sub UnHookMouse()
Debug.Print("Mouse UnHooked")
If _mouseHook = IntPtr.Zero Then Return
UnhookWindowsHookEx(_mouseHook)
_mouseHook = IntPtr.Zero
End Sub
Private Function MouseHookProc(ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32
'Debug.Print("Message = {0}, x={1}, y={2}", wParam.ToInt32, lParam.pt.X, lParam.pt.Y)
If wParam.ToInt32 = 513 Then
'''interrupt the left mouse button event here, but don't know what to return to do so.
End If
Return CallNextHookEx(WH_MOUSE_LL, nCode, wParam, lParam)
End Function
Return 1 - sorry for posting this.