C# 查找进程中的所有按钮(API函数)
1。我有一个应用程序,试图从另一个表单中查找所有按钮。我将使用下面3个API函数:C# 查找进程中的所有按钮(API函数),c#,api,function,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", Set
[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,…)找出按钮的函数:
静态IntPtr FindWindowByIndex(IntPtr hwndpresent,int index)
{
如果(索引==0)
返回hWndParent;
其他的
{
int-ct=0;
IntPtr结果=IntPtr.0;
做
{
结果=FindWindowEx(hWndParent,结果,“按钮”,null);
如果(结果!=IntPtr.Zero)
++ct;
}
而(ct<索引和结果!=IntPtr.Zero);
返回结果;
}
}
但程序并没有按下另一个窗体的第一个按钮(索引0按钮)
2.是否有任何程序可以从正在运行的进程中找到所有按钮的名称?我尝试了Spy++,但没有发现任何有用的东西…FindWindowEx的
类的参数与C#中的类名不同。它是窗口类名称,在调用时返回
例如,下面在我的系统(Windows 7 Enterprise、.NET 4.5、Visual Studio 2012)上运行的代码显示“类名为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.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);
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!");
}
EnumChildWindows:
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);
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;
}
我希望这些代码对您有所帮助。谢谢您,吉姆,但是有了您提供的代码和解释,我无法解决我的问题。。。我试图得到它的按钮的过程,它不是用C#制作的,我也没有它的源代码。。。所以我只想访问这个过程的一个按钮…@charqus:我建议您编写一些调用EnumChildWindows
的代码,将您感兴趣的顶级窗口的句柄传递给它。在回调函数中,调用GetClassName
,并输出每个窗口的返回值。您还可以向窗口发送WM_GETTEXT
消息(不要尝试在另一个进程中的控件上使用GetWindowText
)来获取标题。所有这些都将帮助您识别按钮。然后你可以把你学到的东西整合到你真正想写的程序中。实际上,这是我试图接收它的按钮的进程的类名:ARCSOFT\uuuuu Magiccapp\uuuuuu WINDOW\uuuuuuu CLASS\uuuuw(我在AutoIT中发现的);从这里,是否可以访问它的按钮?这里是一个屏幕截图:您必须在顶级窗口上调用EnumChildWindows
,并检查所有返回窗口的类名。这是确定按钮类名称的唯一方法。我搜索了很多以获得一个好的EnumChildWindows,并列举了我应用程序的所有窗口,但找不到一个好的。你能帮我做一个可行的函数,或者类似的东西吗?我的流程名称是:uWebCam