各位大神好!我调用了获取了外部程序的菜单和子菜单,并且成功执行了,但是,一点开始按钮就“程序无响应”,好像也没有按照我设置的每隔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软件!");
            }
        }
    }
}

解决方案 »

  1.   

    目前找到了问题所在: for (int i = 0; i < testNumber; i++) //正常
                    {
                        System.Threading.Thread.Sleep(testTime);  //问题就出在这里,Thread.Sleep暂停执行,让UI卡死了!!!
                        SendMessage(hwndStart, BM_CLICK, 0, 0); //正常
                    }搜索了百度,但是要用异步回调技术,但是不知道怎么用,哪位能给点意见或是思路吗???
      

  2.   

    Thread therad = new Thread(()=>{
                    for (int i = 0; i < testNumber; i++) //正常
                    {
                        System.Threading.Thread.Sleep(testTime);  //问题就出在这里,Thread.Sleep暂停执行,让UI卡死了!!!
                        SendMessage(hwndStart, BM_CLICK, 0, 0); //正常
                    }});
    therad.Start();