David Emery

David Emery

  • NA
  • 13
  • 802

Clicking buttons and entering commands into a separate program

Jun 27 2023 5:22 PM

I am an old hand at VB but very new to C#. Recently I have been trying to write a routine to operate controls in another program, and came upon the following example posted by Sam Hobbs in 2012. I have successfully adapted it from a Console app to a Windows Forms app, but now I need to implement the following sequences:

    (1)    Focus on a TextBox (identified using Spy++);
    (2)    Clear the textbox (could be a series of backspaces if there is no 'clear' command);
    (3)    Load an integer into the textbox (could be one, two or three digits, such as 5, 40, or 160);
    (4)    Enter it into the program as if using the ENTER key.

And also:
(1)    Focus on a ComboBox (identified using Spy++);
(2)    Select an item either by its name or by its number in the collection (ie, 3rd listed item).

Can these things be done? How?This is the 2012 Hobbs program adapted for my purposes as a Windows Forms app:
 

using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace PressButton_cs
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
       
    private void Form1_Load(object sender, EventArgs e)
    {
    }

            const int WM_COMMAND = 0x0111;
            const int BN_CLICKED = 0;
            const int ButtonId = 0x7904;
            const string fn = @"C:\Program Files\MyTestProgram.exe";
            
            [DllImport("user32.dll")]
            static extern IntPtr GetDlgItem(IntPtr hWnd, int nIDDlgItem);

            [DllImport("user32.dll")]
            static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);

        private void button1_Click(object sender, EventArgs e)
        {
                   IntPtr handle = IntPtr.Zero;
            Process[] localAll = Process.GetProcesses();
            foreach (Process p in localAll)
            {
                if (p.MainWindowHandle != IntPtr.Zero)
                {
                    ProcessModule pm = GetModule(p);
                    if (pm != null && p.MainModule.FileName == fn)
                        handle = p.MainWindowHandle;
                }
            }
            if (handle == IntPtr.Zero)
            {
               textBox1.Text=("Not Found");
            }
            Console.WriteLine("{0:X}", handle);
           
            IntPtr hWndButton = GetDlgItem(handle, ButtonId);
            int wParam = (BN_CLICKED << 16) | (ButtonId & 0xffff);
            SendMessage(handle, WM_COMMAND, wParam, hWndButton);
            textBox1.Text = ("message sent");
        }

        private static ProcessModule GetModule(Process p)
        {
            ProcessModule pm = null;
            try { pm = p.MainModule; }
            catch
            {
                return null;
            }
            return pm;
        }
    }
}

 


Answers (1)