查找流程中的所有按钮(API函数)

本文关键字:API 函数 按钮 程中 查找 | 更新日期: 2023-09-27 18:19:56

1。我有一个应用程序,我正在尝试从另一个表单中查找所有按钮。我正在使用接下来的3个API函数:

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

在我的程序中,我检查要检查的应用程序是否正在运行,如果为true,我会执行下一步操作:

    Process[] uWebCam = Process.GetProcessesByName("asd.vshost");
    if (uWebCam.Length != 0)
    {
        IntPtr ptr = uWebCam[0].MainWindowHandle;
        IntPtr x = FindWindowByIndex(ptr, 0);
        const int BM_CLICK = 0x00F5;
        SendMessage(x, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
    }

这是我试图通过索引(0,1,…)找到按钮的函数:

static IntPtr FindWindowByIndex(IntPtr hWndParent, int index)
    {
        if (index == 0)
            return hWndParent;
        else
        {
            int ct = 0;
            IntPtr result = IntPtr.Zero;
            do
            {
                result = FindWindowEx(hWndParent, result, "Button", null);
                if (result != IntPtr.Zero)
                    ++ct;
            }
            while (ct < index && result != IntPtr.Zero);
            return result;
        }
    }

但程序并没有按下我的另一个表单的第一个按钮(索引0按钮)

2.是否有任何程序可以从正在运行的进程中找到所有按钮的名称?我试过Spy++,但没有发现任何有用的东西。。。

查找流程中的所有按钮(API函数)

FindWindowExclass参数与C#中的类名不同。它是调用GetClassName时返回的窗口类名。

例如,在我的系统(Windows 7 Enterprise、.NET 4.5、Visual Studio 2012)上运行的以下代码显示"Classname is WindowsForms10.BUTTON.app.0.b7ab7b_r13_ad1"。好吧,这就是我第一次运行它时显示的内容。下一次返回的值不同了。

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hwnd, StringBuilder lpClassName, int nMaxCount);
private void button1_Click(object sender, EventArgs e)
{
    int nret;
    var className = new StringBuilder(255);
    nret = GetClassName(button1.Handle, className, className.Capacity);
    if (nret != 0)
        MessageBox.Show("Classname is " + className.ToString());
    else
        MessageBox.Show("Error getting window class name");
}

窗口类名显然是由Button类静态构造函数生成的,并且随着程序的每次执行而更改。所以你不能使用完整的类名。

可能能够查找子字符串".BUTTON.",甚至可能是".BUTTON.app.0",因为它看起来是常量。您甚至可以检查字符串是否以"WindowsForms"开头,但我不建议添加"10",因为我怀疑这是版本号。

无论你在这里做什么,请注意,你正在践踏Windows窗体的未记录的实现细节,这些细节可能随时更改。

您应该使用EnumChildWindows()来查找所有子窗口。

Api功能:

  public delegate bool EnumChildCallback(IntPtr hwnd, ref IntPtr lParam); 
  [DllImport("user32.dll")]
  public static extern int EnumChildWindows(IntPtr hwnd, EnumChildCallback Proc, int lParam);
  [DllImport("User32.dll")]
  public static extern int SendMessage(int hWnd, int uMsg, int wParam, string lParam);

EnumChildWindows:

System.Diagnostics.Process[] uWebCam = Process.GetProcessesByName("asd.vshost");
            if (uWebCam .Length > 0)
            {
                foreach (System.Diagnostics.Process p in uWebCam )
                {
                    IntPtr handle = p.MainWindowHandle;
                    EnumChildWindows(handle, EnumChildProc, 0);
                }
            }
            else
            {
                MessageBox.Show("Process can not be found!");
            }

EnumChildProc:在此处编写SendMessage ()函数

 public bool EnumChildProc(IntPtr hwndChild, ref IntPtr lParam)
    {
        SendMessage(hwndChild.ToInt32(), WM_SETTEXT, 0, textBox1.Text);
        return true;
    }

我希望这些代码能帮助你。