查找流程中的所有按钮(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++,但没有发现任何有用的东西。。。
FindWindowEx
的class
参数与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;
}
我希望这些代码能帮助你。