The question asked “What i want is how do i make a program to be able to send inputs (key clicks) into the application when it is minimized”
The solution:
Imports System.Runtime.InteropServices Public Class Form1 ''-------------------- ''Minimise the window <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto) > _ Private Shared Function ShowWindow(ByVal hwnd As IntPtr, _ ByVal nCmdShow As Integer) As Integer End Function Private Const SW_SHOWMINIMIZED = 2 ''-------------------- ''Finding the Control <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto) > _ Private Shared Function FindWindowEx(ByVal parentHandle As IntPtr, _ ByVal childAfter As IntPtr, _ ByVal lclassName As String, _ ByVal windowTitle As String) As IntPtr End Function ''-------------------- ''Sending the click Private Declare Auto Function SendMessage Lib "user32" (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As String) As IntPtr Private Const BM_CLICK = &HF5 Private Const WM_LBUTTONDOWN = &H201 Private Const WM_LBUTTONUP = &H202 Private Const BM_SETSTATE = &HF3 ''-------------------- ''Read the edit control Private Declare Auto Function SendMessage Lib "user32" (ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As System.Text.StringBuilder) As IntPtr Private Const WM_GETTEXT = &HD Private Const WM_GETTEXTLENGTH As Integer = &HE ''-------------------- ''Keyboard Input <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto) > _ Private Shared Function PostMessage( _ ByVal hWnd As IntPtr, _ ByVal Msg As UInteger, _ ByVal wParam As IntPtr, _ ByVal lParam As IntPtr) As Boolean End Function Private Const WM_KEYDOWN = &H100 Private Const WM_KEYUP = &H101 Private Const WM_SYSKEYDOWN = &H104 Private Const WM_SYSKEYUP = &H105 Private Function GetAnswer(ByVal hWnd As Integer) As String ''Get the controls handle Dim calc_textHandle As Integer = FindWindowEx(hWnd, IntPtr.Zero, "Edit", vbNullChar) ''Get length of the text Dim calc_textLen As IntPtr = SendMessage(calc_textHandle, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero) ''Create string builder Dim calc_textSb As New System.Text.StringBuilder(calc_textLen.ToInt32 + 2) ''Get text SendMessage(calc_textHandle, WM_GETTEXT, calc_textLen.ToInt32 + 2, calc_textSb) ''Return If Not calc_textSb.ToString = "" Then Return ("Result: " & calc_textSb.ToString) Else Return ("Error Reading Answer") End If End Function Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim ProcessFileName As String = "calc" Dim p As Process = Process.GetProcessesByName(ProcessFileName)(0) ' Instead of using Process.GetProcessByName, you could use: ' Private Declare Auto Function FindWindow Lib "user32" (ByVal lpClassName As String,_ ' ByVal lpWindowName As String) As IntPtr ' FindWindow('SciCalc', 'Calculator') ' or FindWindow('SciCalc', vbNullChar) ' or FindWindow(vbNullChar, 'Calculator') 'To return the handle of the window ''Minimise Window ShowWindow(p.MainWindowHandle, SW_SHOWMINIMIZED) ''Now to do a basic sum on the calculator ''Firstly reset the calculator, and then do 1+1=" Dim calc_CButton As Integer = FindWindowEx(p.MainWindowHandle, IntPtr.Zero, "Button", "C") ''Clear SendMessage(calc_CButton, BM_CLICK, 0, 0) Dim calc_1Button As Integer = FindWindowEx(p.MainWindowHandle, IntPtr.Zero, "Button", "1") ''1 SendMessage(calc_1Button, BM_CLICK, 0, 0) Dim calc_plusButton As Integer = FindWindowEx(p.MainWindowHandle, IntPtr.Zero, "Button", "+") ''+ SendMessage(calc_plusButton, BM_CLICK, 0, 0) ''1, instead of using BM_CLICK using Mouse events [BM_CLICK works fine] SendMessage(calc_1Button, WM_LBUTTONDOWN, 0, 0) SendMessage(calc_1Button, BM_SETSTATE, 1, 0) SendMessage(calc_1Button, WM_LBUTTONUP, 0, 0) Dim calc_equalButton As Integer = FindWindowEx(p.MainWindowHandle, IntPtr.Zero, "Button", "=") ''= SendMessage(calc_equalButton, BM_CLICK, 0, 0) ''Now read the results Debug.WriteLine(GetAnswer(p.MainWindowHandle)) ''Now using Keyboard input ''Escape Key to clear textbox PostMessage(p.MainWindowHandle, WM_KEYDOWN, Keys.Escape, 0) PostMessage(p.MainWindowHandle, WM_KEYUP, Keys.Escape, 0) ''5 PostMessage(p.MainWindowHandle, WM_KEYUP, Keys.D5, 0) ''* PostMessage(p.MainWindowHandle, WM_KEYUP, Keys.Multiply, 0) ''10 PostMessage(p.MainWindowHandle, WM_KEYUP, Keys.D1, 0) PostMessage(p.MainWindowHandle, WM_KEYUP, Keys.D0, 0) ''= PostMessage(p.MainWindowHandle, WM_KEYUP, &HBB, 0) Debug.WriteLine(GetAnswer(p.MainWindowHandle)) End Sub End Class
This is an old project demonstrating how to click buttons and send keys to a minimised window.
Use FindWindow/FindWindowEx/EnumChildWindows/etc to get the handle of the button
Then I would use the BM_CLICK message as the Msg param however you could also use WM_LBUTTONDOWN+BM_SETSTATE(1)+WM_LBUTTONUP
The above is an example using Windows Calculator. It clicks the buttons on the form, sends key presses, and gets the answer.
Advertisements