利用API函数向外部应用程序发送消息收藏

//为了使用Win32 API,需要先引入下面这个命名空间
using System.Runtime.InteropServices;

namespace k8
{
    public partial class _3k8Frm : Form
    {
        #region Dll Import 添加对API的引用

            //获取主窗口句柄的API函数
            [DllImport("User32.dll", EntryPoint = "FindWindow")]
            private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
           
            //获取子窗口句柄的API函数
            [DllImport("User32.dll", EntryPoint = "FindWindowEx")]
            private static extern IntPtr FindWindowEx(IntPtr hwndParent,IntPtr hwndChildAfter,string lpszClass,string lpszWindow);

            //向指定句柄的窗口发送消息
            [DllImport("User32.dll", EntryPoint = "SendMessage")]
            private static extern int SendMessage(IntPtr hWnd,int Msg,IntPtr wParam,string lParam);

            const int WM_GETTEXT = 0x000D;
            const int WM_SETTEXT = 0x000C;
            const int WM_CLICK = 0x00F5;

        #endregion

        #region 声明字段 用Spy++查到的
            //下面的这些参数都可以用Spy++查到
            string lpszParentClass = "TForm1"; //整个窗口的类名
            string lpszParentWindow = "Form1"; //窗口标题
            string lpszClass = "TEdit"; //需要查找的子窗口的类名,也就是输入框
            string lpszClass_Submit = "TBitBtn"; //需要查找的Button的类名
            string lpszName_Submit = "确定"; //需要查找的Button的标题
            string text = "";

            string lpszClass1 = "TPanel";//多了一个类,输入框和按钮都放在这个类上的!

            IntPtr ParenthWnd = new IntPtr(0);
            IntPtr ParenthWnd_sub = new IntPtr(0);
            IntPtr EdithWnd = new IntPtr(0);

            //下面的参数设定登陆用户名及密码
            string UserID_3k8 = "4898";
            string Pwd_3k8="2";

        #endregion

        #region 构造函数
       
        public _3k8Frm()
        {
            InitializeComponent();
        }
        #endregion
        
        #region SearchWindow 核心部分,查找窗体并对它进行登陆操作

        private int SearchWindow()
        {
            int retval = 0; //增加一个返回值用来判断操作是否成功

            //查到窗体,得到整个窗体
            ParenthWnd = FindWindow(lpszParentClass, lpszParentWindow);
            ParenthWnd_sub = FindWindowEx(ParenthWnd, EdithWnd, lpszClass1, "");


             //判断这个窗体是否有效
            if (!ParenthWnd_sub.Equals(IntPtr.Zero))
            {
                //得到User Name这个子窗体,并设置其内容
                EdithWnd = FindWindowEx(ParenthWnd_sub, EdithWnd, lpszClass, "");
                if (!EdithWnd.Equals(IntPtr.Zero))
                {
                    text = Pwd_3k8.Trim(); //this.tbUserName.Text.Trim();
                    //调用SendMessage方法设置其内容
                    SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, text);
                    retval++;
                }

                //得到Password这个子窗体,并设置其内容
                EdithWnd = FindWindowEx(ParenthWnd_sub, EdithWnd, lpszClass, "");
                if (!EdithWnd.Equals(IntPtr.Zero))
                {
                    text = UserID_3k8; //this.tbPassword.Text.Trim();
                    SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, text);
                    retval++;
                }

                 //得到Button这个子窗体,并触发它的Click事件
                EdithWnd = (IntPtr)0;
                EdithWnd = FindWindowEx(ParenthWnd_sub, EdithWnd, lpszClass_Submit, lpszName_Submit);
                if (!EdithWnd.Equals(IntPtr.Zero))
                {
                    SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0");
                    retval++;
                }

                return retval;
        }

        #endregion

    }
}

在win2003ser+vs2005下测试通过,交流QQ:69524898

2007.10.10补充如入:

在后面的测试中出现一个问题,当SendMessage当击确定按钮后,如果外部应用程序弹出对话框(比如提示你用户名或密码错误),这时你的程序将暂停运行,必须等待点击弹出的对话框你的程序才恢复正常!但我希望外部应用程序弹出的对话框并不影响我的程序的运行,于是想到了新开线程来解决,代码如下:
       private void a()
        {
            SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0");
        }

                 //得到Button这个子窗体,并触发它的Click事件
                EdithWnd = (IntPtr)0;
                EdithWnd = FindWindowEx(ParenthWnd_sub, EdithWnd, lpszClass_Submit, lpszName_Submit);
                if (!EdithWnd.Equals(IntPtr.Zero))
                {
                    //SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0");
                        Thread t = new Thread(new ThreadStart(a)); //新建一个运行a方法的线程
                        t.Start();//线程开始
                        t.Join(3000);//暂停3秒
                        t.Abort();//结束线程
                        retval++;
                }

   这样修改代码后,实现了想要的效果!但是很麻烦!后来进一步查找资料,原来SendMessage发送消息后要等待返回数据,所以才会出现程序无反应的问题,而另一个API函数PostMessage发送消息后不等待返回数据,于是又将代码更改如下:

//首先添加对PostMessage函数的引用
        [DllImport("User32.dll", EntryPoint = "PostMessage")]
        private static extern int PostMessage(IntPtr hwnd,int Msg,IntPtr wParam,string lParam);

//修改代码
                EdithWnd = (IntPtr)0;
                EdithWnd = FindWindowEx(ParenthWnd_sub, EdithWnd, lpszClass_Submit, lpszName_Submit);
                if (!EdithWnd.Equals(IntPtr.Zero))
                {
                    PostMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0");
                    retval++;
                }

问题圆满解决,又简单方便!

顺便说一下SendMessage和PostMessage如果是点击弹出对话框的确定,代码要如下:
PostMessage(EdithWnd, WM_CLICK, (IntPtr)0, "2");
SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "2");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值