各位大神好!我调用了获取了外部程序的菜单和子菜单,并且成功执行了,但是,一点开始按钮就“程序无响应”,好像也没有按照我设置的每隔8秒执行1次,一共执行30次。
程序UI:外部程序:
代码如下:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;using System.Runtime.InteropServices;
using System.Threading;namespace AutoTest
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
} private const int WM_COMMAND = 0x111; [DllImport("user32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "GetMenu")]
public static extern IntPtr GetMenu(IntPtr hwnd);
[DllImport("user32.dll", EntryPoint = "GetSubMenu")]
public static extern IntPtr GetSubMenu(IntPtr hMenu, int nPos);
[DllImport("user32.dll", EntryPoint = "GetMenuItemID")]
public static extern int GetMenuItemID(IntPtr hMenu, int nPos);
[DllImport("user32.dll", EntryPoint = "PostMessage")]
public static extern int PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
//[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
//private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam); [DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
private static extern void SetForegroundWindow(IntPtr hwnd); #region 指定txtTime值只能为数字
/// <summary>
/// 指定txtTime值只能为数字
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtTime_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 0x20) e.KeyChar = (char)0; //禁止空格键
if ((e.KeyChar == 0x2D) && (((TextBox)sender).Text.Length == 0)) return; //处理负数
if (e.KeyChar > 0x20)
{
try
{
double.Parse(((TextBox)sender).Text + e.KeyChar.ToString());
}
catch
{
e.KeyChar = (char)0; //处理非法字符
}
}
}
#endregion
#region 指定txtNumber值只能为数字
/// <summary>
/// 指定txtNumber值只能为数字
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtNumber_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 0x20) e.KeyChar = (char)0; //禁止空格键
if ((e.KeyChar == 0x2D) && (((TextBox)sender).Text.Length == 0)) return; //处理负数
if (e.KeyChar > 0x20)
{
try
{
double.Parse(((TextBox)sender).Text + e.KeyChar.ToString());
}
catch
{
e.KeyChar = (char)0; //处理非法字符
}
}
}
#endregion
private void btnStart_Click(object sender, EventArgs e)
{ //取得"ToolsTalk MT V04.40.02e"程式的Handle(句柄)
IntPtr ttkHwnd = FindWindow(null, "ToolsTalk MT V04.40.02e"); //取得ToolsTalk程式菜单的Handle
IntPtr ttkMenu = GetMenu(ttkHwnd); //取得主菜单第2项"View"的Handle
ttkMenu = GetSubMenu(ttkMenu, 1); //选单的句柄 改变后面的0,就可以得到不同选单的句柄 //取得子菜单第1项"System state"的ID
int ttkMenuId = GetMenuItemID(ttkMenu, 0); //子选单"System state"的ID //执行子菜单项"System state"
PostMessage(ttkHwnd, WM_COMMAND, ttkMenuId, 0);
const uint BM_CLICK = 0xF5; //鼠标点击的消息
IntPtr tclHwnd = FindWindow(null, "Tool control"); //查找Tool control窗口的句柄
if (tclHwnd != IntPtr.Zero)
{
IntPtr hwndStart = FindWindowEx(tclHwnd, 0, null, "Start"); //获取按钮"start"的句柄
IntPtr hwndReset = FindWindowEx(tclHwnd, 0, null, "Reset"); //获取按钮"Reset"的句柄
SetForegroundWindow(tclHwnd); //将Tool control设为当前活动窗口 int testTime = int.Parse(txtTime.Text); //转换测试时间为int
int testNumber = int.Parse(txtNumber.Text); //转换测试次数为int for (int i = 0; i < testNumber; i++)
{
System.Threading.Thread.Sleep(testTime); //延时执行,值等于txtTime.Text
SendMessage(hwndStart, BM_CLICK, 0, 0); //执行Start按钮
}
}
else
{
MessageBox.Show("请启动ToolsTalk MT软件!");
}
}
}
}
程序UI:外部程序:
代码如下:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;using System.Runtime.InteropServices;
using System.Threading;namespace AutoTest
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
} private const int WM_COMMAND = 0x111; [DllImport("user32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "GetMenu")]
public static extern IntPtr GetMenu(IntPtr hwnd);
[DllImport("user32.dll", EntryPoint = "GetSubMenu")]
public static extern IntPtr GetSubMenu(IntPtr hMenu, int nPos);
[DllImport("user32.dll", EntryPoint = "GetMenuItemID")]
public static extern int GetMenuItemID(IntPtr hMenu, int nPos);
[DllImport("user32.dll", EntryPoint = "PostMessage")]
public static extern int PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
//[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
//private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam); [DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
private static extern void SetForegroundWindow(IntPtr hwnd); #region 指定txtTime值只能为数字
/// <summary>
/// 指定txtTime值只能为数字
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtTime_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 0x20) e.KeyChar = (char)0; //禁止空格键
if ((e.KeyChar == 0x2D) && (((TextBox)sender).Text.Length == 0)) return; //处理负数
if (e.KeyChar > 0x20)
{
try
{
double.Parse(((TextBox)sender).Text + e.KeyChar.ToString());
}
catch
{
e.KeyChar = (char)0; //处理非法字符
}
}
}
#endregion
#region 指定txtNumber值只能为数字
/// <summary>
/// 指定txtNumber值只能为数字
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtNumber_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 0x20) e.KeyChar = (char)0; //禁止空格键
if ((e.KeyChar == 0x2D) && (((TextBox)sender).Text.Length == 0)) return; //处理负数
if (e.KeyChar > 0x20)
{
try
{
double.Parse(((TextBox)sender).Text + e.KeyChar.ToString());
}
catch
{
e.KeyChar = (char)0; //处理非法字符
}
}
}
#endregion
private void btnStart_Click(object sender, EventArgs e)
{ //取得"ToolsTalk MT V04.40.02e"程式的Handle(句柄)
IntPtr ttkHwnd = FindWindow(null, "ToolsTalk MT V04.40.02e"); //取得ToolsTalk程式菜单的Handle
IntPtr ttkMenu = GetMenu(ttkHwnd); //取得主菜单第2项"View"的Handle
ttkMenu = GetSubMenu(ttkMenu, 1); //选单的句柄 改变后面的0,就可以得到不同选单的句柄 //取得子菜单第1项"System state"的ID
int ttkMenuId = GetMenuItemID(ttkMenu, 0); //子选单"System state"的ID //执行子菜单项"System state"
PostMessage(ttkHwnd, WM_COMMAND, ttkMenuId, 0);
const uint BM_CLICK = 0xF5; //鼠标点击的消息
IntPtr tclHwnd = FindWindow(null, "Tool control"); //查找Tool control窗口的句柄
if (tclHwnd != IntPtr.Zero)
{
IntPtr hwndStart = FindWindowEx(tclHwnd, 0, null, "Start"); //获取按钮"start"的句柄
IntPtr hwndReset = FindWindowEx(tclHwnd, 0, null, "Reset"); //获取按钮"Reset"的句柄
SetForegroundWindow(tclHwnd); //将Tool control设为当前活动窗口 int testTime = int.Parse(txtTime.Text); //转换测试时间为int
int testNumber = int.Parse(txtNumber.Text); //转换测试次数为int for (int i = 0; i < testNumber; i++)
{
System.Threading.Thread.Sleep(testTime); //延时执行,值等于txtTime.Text
SendMessage(hwndStart, BM_CLICK, 0, 0); //执行Start按钮
}
}
else
{
MessageBox.Show("请启动ToolsTalk MT软件!");
}
}
}
}
{
System.Threading.Thread.Sleep(testTime); //问题就出在这里,Thread.Sleep暂停执行,让UI卡死了!!!
SendMessage(hwndStart, BM_CLICK, 0, 0); //正常
}搜索了百度,但是要用异步回调技术,但是不知道怎么用,哪位能给点意见或是思路吗???
for (int i = 0; i < testNumber; i++) //正常
{
System.Threading.Thread.Sleep(testTime); //问题就出在这里,Thread.Sleep暂停执行,让UI卡死了!!!
SendMessage(hwndStart, BM_CLICK, 0, 0); //正常
}});
therad.Start();