Code Bye

c# defwndproc接收不到自定义消息

在一个类里给主窗体发送自定义消息
 private void SynReceiveData(object serialPortobj)
        {
            SerialPort serialPort = (SerialPort)serialPortobj;
            System.Threading.Thread.Sleep(0);
            serialPort.ReadTimeout = 500;
            int iReadBuffSize = 
                serialPort.ReadBufferSize;
            while(serialPort.IsOpen)
            {
                try
                {                   
                    byte firstByte = Convert.ToByte(serialPort.ReadByte());
                    int bytesRead = serialPort.BytesToRead;
                    byte[] bytesData = new byte[bytesRead + 1];
                    bytesData[0] = firstByte;
                    for (int i = 1; i <= bytesRead; i++)
                        bytesData[i] = Convert.ToByte(serialPort.ReadByte());
                    sData = System.Text.Encoding.Default.GetString(bytesData);                   
                    SendMessage(parentwnd, WM_TEST, 0, 0);
                    Thread.Sleep(200);
                }
                catch (Exception e)
                {
                    // 处理超时错误
                    Thread.Sleep(500);
                }
            }
        }

主窗体中接收不到那个自定义消息

protected override void DefWndProc(ref System.Windows.Forms.Message m)
        {
            switch (m.Msg)
            {
                case WM_TEST: //处理消息 
                    if (m.WParam.ToInt32() == 2) 
                    {
                        
                    }
                    RawData.AppendText(pcom.sData);
                    break;
                default:
                    base.DefWndProc(ref m);//调用基类函数处理非自定义消息。 
                    break;
            }
        }
解决方案

10

有几个疑问
1、为什么要定义 byte firstByte = Convert.ToByte(serialPort.ReadByte()); 呢
这样读取数据不是更好吗
var buffer = new byte[sp.BytesToRead];
sp.Read(buffer, 0, buffer.Length);
var sData = Encoding.Default.GetString(buffer);

2、为什么不直接用 SendMessage 发送 sData 呢

[DllImport("user32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, StringBuilder lParam); // 用 StringBuilder
// 模拟发送
button.Click += (o, g) =>
{
    const int WM_USER = 0x0400; // 依稀记得这是用户消息的常数值
    var sb = new StringBuilder();
    sb.AppendLine("fadfasdfadsfasdfasdfasd您好好");
    SendMessage(Handle, WM_USER, 0, sb); // 直接发送 StringBuilder
};
// 接收
protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    if (m.Msg == 0x0400)
    {
        Console.WriteLine(Marshal.PtrToStringAnsi(m.LParam)); // 接收消息
    }
}

10

引用 1 楼 qqamoon 的回复:


2、为什么不直接用 SendMessage 发送 sData 呢

为什么不直接用Control.Invoke呢?
:)谁告诉本人,语文里“直接”可以用比较级吗?

20

引用 4 楼 hereier 的回复:

怎么接收串口数据以及怎么发送不是重点,关键是为什么不能接收自定义消息

WM_TEST = ?
还有你确定执行到 SendMessage 了吗

20

那要检查 parentwnd 了
你这样,不要在这个方法中执行 sendmessage
在窗口上放个按钮,点击按钮,在事件代码中进行调试
主要 查看 parent 的 handler,还有,假如 parent 有 hide/show 的行为, parent.handler 是会被重新分配的

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明c# defwndproc接收不到自定义消息