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 ++,但我找不到任何有用的东西......
答案 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;
}
我希望这些代码可以帮助你。