#region 窗口消息处理相关引用
        const Int32 WM_COPYDATA = 0x004A;
        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct COPYDATASTRUCT
        {
            /// <summary>
            /// 固定为 (IntPtr) 100?
            /// </summary>
            public IntPtr dwData;
            /// <summary>
            /// 消息长度+1,通过System.Text.Encoding.Default.GetByteCount函数取得字符串实际长度
            /// </summary>
            public int cbData;
            /// <summary>
            /// 字节数组表示的消息内容
            /// </summary>
            [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)]
            public string lpData;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="hWnd">handle to destination window</param>
        /// <param name="Msg">message identifier</param>
        /// <param name="wParam">first message parameter</param>
        /// <param name="lParam">second message parameter</param>
        /// <returns></returns>
        [System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(
        Int32 hWnd,
        Int32 Msg,
        Int32 wParam,
        ref COPYDATASTRUCT lParam
        );        /// <summary>
        /// 该函数将一个消息放入(寄送)到与指定窗口创建的线程相联系消息队列里,不等待线程处理消息就返回。
        /// </summary>
        /// <param name="hWnd">目标窗口句柄</param>
        /// <param name="Msg">message identifier</param>
        /// <param name="wParam">第一个信息参数</param>
        /// <param name="lParam">第一个信息参数</param>
        /// <returns></returns>
        [System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint = "PostMessage")]
        private static extern int PostMessage(
            Int32 hWnd,
            Int32 Msg,
            Int32 wParam,
            ref COPYDATASTRUCT lParam
            );        //[System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint = "GetWindowText")]
        //private static extern int GetWindowText(
        //    Int32 hWnd, // {a handle to a window}
        //    [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)]
        //    string lpString, // {a pointer to a buffer to receive the string}
        //   Int32 nMaxCount // {the maximum number of characters to copy}
        //    ); // {returns the length of the copied string}        //[System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint = "FindWindow")]
        //private static extern int FindWindow(string lpClassName, string
        //lpWindowName);
        #endregion        //窗口消息处理
        protected override void DefWndProc(ref Message m)//没接收到相应的窗口信息
        {
            switch (m.Msg)
            {
                case WM_COPYDATA:                    COPYDATASTRUCT cdsT = new COPYDATASTRUCT();
                    Type mytype = cdsT.GetType();
                    cdsT = (COPYDATASTRUCT)m.GetLParam(mytype);
                    //调试开始
                    tbContent.AppendText(cdsT.lpData);
                    MessageBox.Show("调试开始");
                    //调试结束
                    //cdsT.lpData
                    if (cdsT.lpData == ConstantVars.WindowMessageConst.sOptionChanged) LoadOption();
                    if (cdsT.lpData.StartsWith(ConstantVars.WindowMessageConst.sOpenFile))
                    {
                        Int32 I = cdsT.lpData.Length - ConstantVars.WindowMessageConst.sOpenFile.Length;
                        OpenFile(sflStoryFileList.DecreaseStoryFilesFrequecyBut(new StringBuilder(cdsT.lpData, ConstantVars.WindowMessageConst.sOpenFile.Length, I, I).ToString()));
                    }
                    else
                    {
                        if (cdsT.lpData == ConstantVars.WindowMessageConst.sOptionChanged)
                        {
                            LoadOption();
                        }
                    }
                    MessageBox.Show(cdsT.lpData);
                    break;
                default:
                    base.DefWndProc(ref m);
                    break;
            }
        }        /// <summary>
        /// //找出以前的实例并发送信息
        /// </summary>
        /// <param name="sMessage"></param>
        private void SendMessageToBefore(string sMessage)//这个函数有调用,但没有结果
        {
            COPYDATASTRUCT csT = new COPYDATASTRUCT();
            csT.dwData = (IntPtr)100;
            csT.lpData = sMessage;
            csT.cbData = System.Text.Encoding.Default.GetByteCount(sMessage) + 1;
            System.Diagnostics.Process prcCurrentProcess = System.Diagnostics.Process.GetCurrentProcess();
            string sFileName = prcCurrentProcess.MainModule.FileName;
            Int32 iID = prcCurrentProcess.Id;
            System.Diagnostics.Process[] prcs = System.Diagnostics.Process.GetProcesses();
            foreach (System.Diagnostics.Process prcT in prcs)
            {
                try
                {
                    Int32 I;
                    if (prcT.MainModule.FileName == sFileName)
                        if (prcT.Id != iID)
                            I = PostMessage(prcT.MainWindowHandle.ToInt32(), WM_COPYDATA, 0, ref csT);
                }
                catch
                {
                }
            }
        }

解决方案 »

  1.   

    楼上的,是跨进程。
    我写的代码目的就是在程序第二次被打开的时候,把命令行的参数传递到前面打开的实例。实例运行的时候,SendMessageToBefore这个函数在调试的时候有被运行到。但前面打开的实例不能接收到相应的窗口消息。
      

  2.   

    有两个地方可以改进一下:
    1、发广播消息看看。
    2、PostMessage(prcT.MainWindowHandle.ToInt32(), WM_COPYDATA, 0, ref csT); 中第三个参数wParam,也就是你现在设为0的地方,改为发送此消息的窗口句柄试试看。
    参考:
    wParam
    Handle to the window passing the data. 
    lParam
    Pointer to a COPYDATASTRUCT structure that contains the data to be passed. 
      

  3.   

    楼上的兄弟,还是不行:(
    //I = PostMessage(prcT.MainWindowHandle.ToInt32(), WM_COPYDATA, 0, ref csT);
    I = PostMessage(prcT.MainWindowHandle.ToInt32(), WM_COPYDATA, this.Handle.ToInt32(), ref csT);
      

  4.   

    你的消息0x0004A太特殊了,换一个就行了,比如
    const Int32 WM_COPYDATA = 0x004;
      

  5.   

    楼上的兄弟,这样改不行的。
    System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
       在 System.Runtime.InteropServices.Marshal.PtrToStructureHelper(IntPtr ptr, Object structure, Boolean allowValueClasses)
       在 System.Runtime.InteropServices.Marshal.PtrToStructure(IntPtr ptr, Type structureType)
       在 System.Windows.Forms.UnsafeNativeMethods.PtrToStructure(IntPtr lparam, Type cls)
       在 System.Windows.Forms.Message.GetLParam(Type cls)
       在 TextReader.frmMain.DefWndProc(Message& m) 位置 E:\Visual Studio 2005\TextReader\TextReader\frmMain.cs:行号 1298
       在 System.Windows.Forms.Control.WndProc(Message& m)
       在 System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       在 System.Windows.Forms.ContainerControl.WndProc(Message& m)
       在 System.Windows.Forms.Form.WndProc(Message& m)
       在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
      

  6.   

    把COPYDATASTRUCT 这个参数去掉之后呢?        [System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint = "PostMessage")] 
            private static extern int PostMessage(Int32 hWnd, Int32 Msg, Int32 wParam); 之前用过这个形式的,用的挺好的,没出过问题
      

  7.   

    myh0305兄,把PostMessage改成那样的话,即使有那样的函数入口,可是,我该怎么把字符串传递过去呢?
    请不吝指教为盼。
      

  8.   

    你可以用SendMessage看看
    重写protected override void WndProc(ref Message m) 
    {}
    IntPtr hwnd;
    hwnd= this.Handle ;
    SendMessage(hwnd, 消息值,(IntPtr) 参数, (IntPtr)参数);
      

  9.   

    fuyuxin19801120兄弟,SendMessage和PostMessage差别仅仅是一个发完消息等待返回,一个马上返回。没多少区别的。
      

  10.   

    兄弟,在论坛提问的最基本规矩就是把出问题的代码贴出来。如果这个问题我直接问"PostMessage发出的消息目的窗口收不到",那谁能知道什么意思?
      

  11.   

     I = PostMessage(prcT.MainWindowHandle.ToInt32(), WM_COPYDATA, 0, ref csT); 不是TOINT32是ToIntPtr
    HANDLE是个UINT指针  protected override void DefWndProc(ref Message m)//没接收到相应的窗口信息 
    不是DefWndProc
    是重载
    WndProc
      

  12.   

    Deathsign:
    发送消息的这句改成下面这样还是不行,
    I = PostMessage((UInt32)(prcT.MainWindowHandle), WM_COPYDATA, 0, ref csT);另外,WndProc也重写了,一样的结果,没反应。
    prcT.MainWindowHandle只有ToPointer()这个成员,没有ToIntPtr()成员。
      

  13.   

    你那种写法消息传不过去的,我的改动是让你能成功的将消息发送过去,我是解决了你的“//没接收到相应的窗口信息”的问题,但是你的
     case WM_COPYDATA: 里的处理有Bug,造成程序出错,这个是另一个问题了
      

  14.   

    你可以这么改
      [System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint = "PostMessage")]
            private static extern int PostMessage(
                Int32 hWnd,
                Int32 Msg,
                Int32 wParam,
                IntPtr lParam
                );
    private void SendMessageToBefore(string sMessage)//这个函数有调用,但没有结果 
            {
                COPYDATASTRUCT csT = new COPYDATASTRUCT();
                csT.dwData = (IntPtr)100;
                csT.lpData = sMessage;
                csT.cbData = System.Text.Encoding.Default.GetByteCount(sMessage) + 1;
                IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(csT));
                Marshal.StructureToPtr(csT, pt, true);
                ……
                I = PostMessage(prcT.MainWindowHandle.ToInt32(), WM_COPYDATA, 0, pt);
                ……
    }
    //窗口消息处理 
            protected override void DefWndProc(ref Message m)//没接收到相应的窗口信息 
            {
                switch (m.Msg)
                {
                    case WM_COPYDATA:
                        COPYDATASTRUCT cdsT = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
                        
    }
      

  15.   

    冰风漫天:
    还是不行的,照你写的代码改了。但还是执行不到这句
    case WM_COPYDATA: 
          COPYDATASTRUCT cdsT = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT)); 
      

  16.   

    之间说的,const Int32 WM_COPYDATA = 0x004;
    这句你改了吗?
      

  17.   

    冰风漫天兄,作了如下更改:
    const Int32 WM_COPYDATA = 0x004;//4A;出错情形:
    有时候,
    COPYDATASTRUCT cdsT = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT)); 

    尝试读取或写入受保护的内存。这通常指示其他内存已损坏。有时候,
    tbContent.AppendText(cdsT.lpData);
    未将对象引用设置到对象的实例。
    或:乱码。
    这个参数是能传递消息到先前实例窗口,但消息所带的lpData明显不对,cdsT.cbData为0。应该是lpData已经被放弃了。