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

时间:2013-06-25 18:51:38

标签: c# api function

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);

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

    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 ++,但我找不到任何有用的东西......

2 个答案:

答案 0 :(得分:1)

class的{​​{1}}参数与C#中的类名不同。这是窗口类名,在您致电GetClassName时返回。

例如,在我的系统(Windows 7 Enterprise,.NET 4.5,Visual Studio 2012)上运行的以下代码显示FindWindowEx。嗯,这是我第一次运行它时显示的内容。下次返回的值不同。

"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",因为我怀疑这是版本号。

无论你在这做什么,都要注意你正在研究Windows Forms的无证实现细节,这些细节可能会随时改变。

答案 1 :(得分:0)

您应该使用EnumChildWindows()查找所有子Windows。

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;
    }

我希望这些代码可以帮助你。