程序間消息傳遞

程序間消息傳遞


1.在本程序中處理消息時,通過重載DefWndProc來處理.
        protected override void DefWndProc(ref System.WinForms.Message m)
        {
            switch (m.msg)
            {
                case WM_Lbutton:
                    ///string与MFC中的CString的Format函数的使用方法有所不同
                    string message = string.Format("收到消息!参数为:{0},{1}", m.wParam,

m.lParam);

                    MessageBox.Show(message);///显示一个消息框
                    break;

                default:
                    base.DefWndProc(ref m);///调用基类函数处理非自定义消息。
                    break;
            }

        }

2.向其它程序發送消息
--1.函數介紹
主要是調用2個API函數,PostMessage和SendMessage.
PostMessage只负责将消息放到消息队列中,不确定何时及是否处理 SendMessage要等到受到消息处理的返回

码(DWord类型)后才继续 PostMessage执行后马上返回 SendMessage必须等到消息被处理后才会返回

[DllImport("User32.dll",EntryPoint="SendMessage")]
   private static extern int SendMessage(
          IntPtr hWnd,   // handle to destination window
          IntPtr Msg,    // message
          IntPtr wParam, // first message parameter
          IntPtr lParam // second message parameter
    );

wParam,它表示此次的消息类型是什么?是键盘?是鼠标?键盘里又分按下还是抬起,鼠标里又分是单击还

是双击,等等。lParam是一个指针,它指向本条消息所存储的信息的内存区域的首地址,很显然,这个地址

存放的东西是很灵活的,比如鼠标消息,那么这里可能存放的是各键的状态或者光标的X,Y座标。换成键盘消

息,则是键码等等。总之,wParam区分了类别,lParam存放了该类别所存储的信息。


第一個參數hWnd,是窗口的句柄,
第二個參數Msg,是消息的標識符(參見附表1)
第三個參數wParam,是消息的類別,但不知道有什么用,
第四個參數lParam,该类别所存储的信息


對于第四個參數lParam,可能經常要轉化成其它的數据類型,方法主要是
(1)聲明多個SendMessage函數
(2)利用Marshal或GCHandle的相關方法.
具体參見: http://www.zlku.cn/f/91n/


--2.應用

主要分以下4种情況:
(1)取得屬性
(2)設置屬性
(3)触發事件

 //下面几個是消息的標識符,參見附表1
        const int WM_GETTEXT = 0x000D;
        const int WM_SETTEXT = 0x000C;
        const int WM_CLICK = 0x00F5;

        #region Dll Import

        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [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);

 [DllImport("user32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, StringBuilder

lParam);

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

            //下面的这些参数都可以用Spy++查到
            string lpszParentClass = "WindowsForms10.Window.8.app.0.378734a"; //整个窗口的类名
            string lpszParentWindow = "Form1"; //窗口标题
            string lpszClass = "WindowsForms10.EDIT.app.0.378734a"; //需要查找的子窗口的类名,

也就是输入框
            string lpszClass_Submit = "WindowsForms10.BUTTON.app.0.378734a"; //需要查找的Button

的类名
            string lpszName_Submit = "button1"; //需要查找的Button的标题
            string text = "";

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

            //查到窗体,得到整个窗体
            ParenthWnd = FindWindow(lpszParentClass, lpszParentWindow);

            //判断这个窗体是否有效
            if (!ParenthWnd.Equals(IntPtr.Zero))
            {
         /*
  //取得这个子窗体,并取得上面的文字
  EdithWnd = FindWindowEx(ParenthWnd, EdithWnd, lpszClass, null);
                if (!EdithWnd.Equals(IntPtr.Zero))
                {
                    //调用SendMessage方法取得其内容
                    const int buffer_size = 1024;
                    StringBuilder buffer = new StringBuilder(buffer_size);
                    SendMessage(EdithWnd, WM_GETTEXT, buffer_size, buffer);
                    this.tbUserName.Text = buffer.ToString();
                    retval++;
                }
  */

                //得到这个子窗体,并设置其内容
                EdithWnd = FindWindowEx(ParenthWnd, EdithWnd, lpszClass, null);
                if (!EdithWnd.Equals(IntPtr.Zero))
                {
                    text = this.tbUserName.Text.Trim();
                    //调用SendMessage方法设置其内容
                    SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, text);
                    retval++;
                }

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

                //得到Button这个子窗体,并触发它的Click事件
                EdithWnd = FindWindowEx(ParenthWnd, EdithWnd, lpszClass_Submit,

lpszName_Submit);
                if (!EdithWnd.Equals(IntPtr.Zero))
                {
                    SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0");
                    retval++;
                }
             
            }

            return retval;
        }
        #endregion

3.取得其它程序的消息
本文主要調用函數GetMessage和PeekMessage,其實關聯到線程鉤子与系統鉤子,就不詳述了.
參見:
http://hi.baidu.com/zrrn/blog/item/3e2b09139694ee846438db4d.html

附表1:
消息表
http://hi.baidu.com/myvfp/blog/item/524b281caddfde8f86d6b6e7.html

參考文獻:
http://www.cnblogs.com/sizzle/archive/2007/08/29/874796.html
http://www.zlku.cn/f/91n/
http://www.vckbase.com/document/viewdoc/?id=240
http://www.cnblogs.com/index/archive/2005/01/16/92651.html
http://topic.csdn.net/t/20050109/03/3710210.html
http://www.bllll.com/thread-33943-1-1.html 

你可能感兴趣的:(程序間消息傳遞)