C# 引用API SENDMESSAGE进行窗体间通信

来源:互联网 发布:redis cluster java 编辑:程序博客网 时间:2024/06/05 05:18

经常看到有相关开发人员寻一些窗体通信的方法但大多网上的代码。有API基础的我当然不会这么做,就让哥来介绍一种方法.而且绝对是哥的原创.

首先是建立一个MDI窗体,然后再添加两个FORM子窗体命名为(form1,form2自己随便输入但是一定要记清楚这是查找窗口句柄的关键)

在FORM1(接收消息的窗体)中加入如下代码

///自定义消息

 public const int W_USER = 0x0400;

public const int W_TEXT = W_USER + 103;

//////////

////重写的WNDPROC事件

 protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                   
                case W_TEXT ://获取自定义消息并处理
                  //  MessageBox.Show(m.Msg.ToString());
                   // MessageBox.Show(m.WParam.ToString ());
                  //  dal.dal dal = new dal.dal();
                  //  SqlConnection conn = new SqlConnection(dal.sql_str());
                  //  SqlDataAdapter Dadap = new SqlDataAdapter("select * from member order by id desc", conn);
                  //  DataSet ds = new DataSet();
                  //  Dadap.Fill(ds, "0");
                    //this.dataGridView1.DataSource = ds.Tables[0];
                    break;
                
                default:
                    base.WndProc(ref m);
                    break;
           
            }
         
        }

 

////////在form2(通信发送)的窗体中写入以下事件

        public const int W_USER = 0x0400;
        public const int W_TEXT = W_USER + 103;//自定义消息

        public const int GW_CHILD = 5;//GETWINDOW消息常量得到父窗体的下属窗体
        public const int GW_HWNDNEXT = 2;///GETWINDOW消息常量得到下一个窗体

///引用API

    [DllImport("User32.dll")]
        public static extern int SendMessage(IntPtr Hwnd, uint Msg, uint wpala, uint lpala);//消息发送具体参考MSDN
        
        [DllImport("User32.dll")]
        public static extern IntPtr FindWindow(string lpclassname, string wname);//查找窗体具体参考MSDN
        
        [DllImport("User32.dll")]
        public static extern IntPtr FindWindowEx(IntPtr pwnd, IntPtr swnd, string x, string y);// 查找窗体具体参考MSDN

        public string xname;

        [DllImport("User32.dll")]
        public static extern IntPtr GetWindow(IntPtr whwnd, int varls);//得到窗体具体参考MSDN
        
        [DllImport("User32.dll")]
        public static extern IntPtr GetClassName(IntPtr hwnd, StringBuilder classname, int length); //得到类的信息具体参考MSDN

///////发送信息事件

private void button1_Click(object sender, EventArgs e)
        {
            IntPtr x = new IntPtr(0);//随便命名的一个指针变量 仅供参考
            IntPtr y = new IntPtr(0);//随便命名的一个指针变量 仅供参考
            IntPtr mwnd = new IntPtr(0);
            x = FindWindow(null, "注意此处添写父窗体标题名称");//得到父窗体名称
            mwnd = GetWindow(x, GW_CHILD);//得到父窗体 第一个子窗口   

           StringBuilder sb = new StringBuilder(1024);//定义接收类名称的变量
            while (mwnd.ToString() != "0")//循环得到子窗体如果类名包含MDICLIENT退出
            {

                GetClassName(mwnd, sb, 256);//得到类名称
                if (sb.ToString().Contains("MDICLIENT"))//类名如果为MDICLIENT执行事件
                {
               //  MessageBox.Show(mwnd.ToString());
                 //   MessageBox.Show(gwin);
                 y = FindWindowEx(mwnd, IntPtr.Zero ,null,"注意此处添写FORM1的窗体名称");//得到通信接收的窗口句柄
                    SendMessage(y, W_TEXT, 10, 0);//发送消息到接收通信的窗体
                    return;
                }
                
                mwnd = GetWindow(mwnd, GW_HWNDNEXT);//寻找下一子窗体句柄


            }

 

通过上边的代码我们可以随便进行和窗体的通信唯一注意的应该就是要找到子窗体要得到父窗体的MDICLIENT的句柄。

这也是为什么有些人得不到子窗体的原因.以上代码时间仓促命名有不规范的地方有需要用到的人员请自行修改,包括API的命名不规则,好了,有问题在交流

 

原创粉丝点击