I’m making an VB application which runs another process (windowed game). My app acts as a macro to that game.
I have managed to write code that sends keyboard input into the process in the background without using appActivate, however I’m struggling to get mouse click working the same way.
I mean the program to click into specific location within the process in the background, that means I could be browsing internet or playing another game when that mouse click takes action.
Hope I make sense, can somebody bring me on right track?
This code I use to send Q letter into app in background:
Public Const WM_KEYDOWNLPARAM As System.UInt32 = &H320001
Public Const WM_KEYUPLPARAM As System.UInt32 = 3224502273
Public Const WM_KEYDOWN As System.Int32 = &H100
Public Const WM_KEYUP As System.Int32 = &H101
<System.Runtime.InteropServices.DllImport("user32.dll")>
Public Shared Function PostMessage(<System.Runtime.InteropServices.In()> ByVal hWnd As System.IntPtr, <System.Runtime.InteropServices.In()> ByVal Msg As System.UInt32, <System.Runtime.InteropServices.In()> ByVal wParam As System.IntPtr, <System.Runtime.InteropServices.In()> ByVal lParam As System.UIntPtr) As System.Boolean
End Function
Public Sub InputPressKey(ByVal Handle As System.IntPtr, ByVal Key As System.Windows.Forms.Keys)
PostMessage(Handle, WM_KEYDOWN, CType(Key, System.IntPtr), CType(WM_KEYDOWNLPARAM, System.UIntPtr))
End Sub
Public Sub InputReleaseKey(ByVal Handle As System.IntPtr, ByVal Key As System.Windows.Forms.Keys)
PostMessage(Handle, WM_KEYUP, CType(Key, System.IntPtr), CType(WM_KEYUPLPARAM, System.UIntPtr))
End Sub
InputPressKey(Process.MainWindowHandle, System.Windows.Forms.Keys.Q)
Related
I have stuck at one place where I have to turn off the monitor and at background all my processes should work something like turn off the monitor only but cpu etc should work normally. Actually, my backend sends screenoFF command and accordingly I send a "SendMessage" command to off the monitor it is working fine on my laptop, but in production side system is going into sleep mode.
I would appreciate If anyone could help here thanks.
Private Const WM_SYSCOMMAND As Integer = &H112
Private Const SC_MONITORPOWER As Integer = &HF170
<DllImport("user32.dll")>
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal hMsg As Integer,
ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
SendMessage(Me.Handle, WM_SYSCOMMAND, CType(SC_MONITORPOWER, IntPtr), CType(2, IntPtr))
I am looking to send key and mouse events to notepad.exe, however not necessarily have the window be active. In some cases the key events are actual typing operations and in other cases the key input represents shortcut key combinations.
Using SendKeys works, but obviously needs focus. I would prefer to have that operate in the background so am investivating SendMessage from user32.dll. I can see it has different signatures based on what the message code is, and this may be the origin of the problem.
Starting with
Dim notepad() As Process = Process.GetProcessesByName("notepad")
Dim actualWindow As IntPtr = FindWindowEx(notepad(0).MainWindowHandle, IntPtr.Zero, "Edit", Nothing)
and using
<System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="SendMessageA")>
Public Function SendMessage(ByVal hWnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As String) As IntPtr
End Function
if I send
SendMessage(actualWindow, KeyEventType.WM_SETTEXT, 0, "Text")
then the editor text is replaced with "Text".
If however I use
<System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="SendMessageA")>
Public Function SendMessage(ByVal hWnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Int32) As IntPtr
End Function
and send
SendMessage(actualWindow, KeyEventType.WM_KEYDOWN, &H4C, 0)
SendMessage(actualWindow, KeyEventType.WM_KEYUP, &H4C, 0)
or even
SendMessage(notepad(0).MainWindowHandle, KeyEventType.WM_KEYDOWN, &H4C, 0)
SendMessage(notepad(0).MainWindowHandle, KeyEventType.WM_KEYUP, &H4C, 0)
where &H4C corresponds to the 'L' key (1.), no letter 'l' appears in the editor.
I am moderately convinced that the function signatures are correct for both WM_KEYDOWN/WM_KEYUP (2.) and WM_SETTEXT (3.). I think the problem might be one of 'focus' but am not sure how to tackle that if I want the operations to occur in the background. How can keystrokes be sent to the text editor?
The enumerations are defined as:
Public Enum KeyEventType As Int32
WM_SETTEXT = &HC
WM_KEYDOWN = &H100
WM_KEYUP = &H101
End Enum
Is there a way to Click the ENTER key on the keyboard, other than SendKeys.Send("{ENTER}"?
I have an Application I created in VB.net that will create a line of text then send it to another application with AppActivate, it works great when the receiving application was created in C++. But when the receiving application was created in Java the SendKeys.Send("{ENTER}" will not work. All the text is transferred to the Java application but the ENTER button will not click.
Is there another way to Click ENTER on the Keyboard or simulate it?
Thank You
Have you tried P/Invoke?
For example:
<DllImport("user32.dll", SetLastError:=True, EntryPoint:="PostMessageA")>
Public Shared Function PostMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Boolean
Public Const WM_KEYDOWN As Integer = &H0100 'Key Down Event
Public Const VK_RETURN As Integer = &H0D 'Enter Key
Public Shared Sub SendKeyDownEvent(ByVal hWnd As IntPtr, ByVal key As Integer)
PostMessage(hWnd, WM_KEYDOWN, key, 0)
System.Threading.Thread.Sleep(500)
End Sub
And you could call it like:
SendKeyDownEvent(handleToApplication, VK_RETURN)
There are plenty of resources available for obtaining handles to other applications:
https://www.codeproject.com/Tips/825946/Csharp-VB-NET-and-WinAPI-How-to-Access-Window-of-O
https://kellyschronicles.wordpress.com/2008/06/23/get-window-handles-associated-with-process-in-vb-net/
I’m making an VB application which runs another process (windowed game). My app acts as a macro to that game.
I’m struggling to get mouse click working, although my code to send keys in the background works excellent (can provide if needed).
I mean the program to click into specific location within the process in the background, that means I could be browsing internet or playing another game when that mouse click takes action.
I'm getting an error message: Specified cast is not valid.
Error is on InputPressRightMouse Sub where:
PostMessage(Handle, WM_RBUTTONDOWN, 1, coord)
Private Const WM_RBUTTONDOWN As System.UInt32 = &H204
Private Const WM_RBUTTONUP As System.UInt32 = &H205
Dim coord = MakeDWord(-220, 85)
Private Function MakeDWord(ByVal LoWord As Integer, ByVal HiWord As Integer) As Long
MakeDWord = (HiWord * &H10000) Or (LoWord And &HFFFF&)
End Function
<System.Runtime.InteropServices.DllImport("user32.dll")>
Public Shared Function PostMessage(<System.Runtime.InteropServices.In()> ByVal hWnd As System.IntPtr, <System.Runtime.InteropServices.In()> ByVal Msg As System.UInt32, <System.Runtime.InteropServices.In()> ByVal wParam As System.IntPtr, <System.Runtime.InteropServices.In()> ByVal lParam As System.UIntPtr) As System.Boolean
End Function
Public Sub InputPressKey(ByVal Handle As System.IntPtr, ByVal Key As System.Windows.Forms.Keys)
PostMessage(Handle, WM_KEYDOWN, CType(Key, System.IntPtr), CType(WM_KEYDOWNLPARAM, System.UIntPtr))
End Sub
Public Sub InputReleaseKey(ByVal Handle As System.IntPtr, ByVal Key As System.Windows.Forms.Keys)
PostMessage(Handle, WM_KEYUP, CType(Key, System.IntPtr), CType(WM_KEYUPLPARAM, System.UIntPtr))
End Sub
Public Sub InputPressRightMouse(ByVal Handle As System.IntPtr, ByVal Mouse As System.Windows.Forms.MouseButtons)
PostMessage(Handle, WM_RBUTTONDOWN, 1, coord)
End Sub
And code to perform mouse click:
InputPressRightMouse(Process.MainWindowHandle, System.Windows.Forms.MouseButtons.Right)
Code to send key (which works)
InputPressKey(Process.MainWindowHandle, System.Windows.Forms.Keys.V)
Can somebody help with what I did wrong here?
'send message implementation
SendMessage(Me.Handle.ToInt32, WM_SYSCOMMAND,
CType(SC_MONITORPOWER, IntPtr), CType(MonitorShutoff, IntPtr))
'declarations
Private Const MonitorShutoff As Integer = 2
Private Const WM_SYSCOMMAND As Integer = &H112
Private Const SC_MONITORPOWER As Integer = &HF170
<DllImport("user32.dll")> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal hMsg As Integer, _
ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
Whenever I want to turn off the monitor in Windows 8.1, this code turns my monitors off temporarily then turns back on to the lock screen, how to i avoid the lock screen?
This is only an issue on Windows 8+ systems. I want my monitors to turn off and stay off. How do i do this?
I believe it is working correctly for you. It's just that your mouse is "moving" (or your keyboard is being "touched").