• C#环境下使用Windows消息传递字符串数据的研究


    前言:

    日前,师兄交给了我一个课题,将一个后台运行的Console程序,修改为WindowsForm程序,并在其界面上增加配置设置,以及运行记录。

    原来的Console程序,后台运行的流程在其中一个类的函数里。我在我创建的主窗体上创建这个类的对象,然后执行它的函数。结果就遇到了一个问题,大部分需要记录下的运行记录,都是在这个类的函数中,而这个类怎么去访问我的主窗体上的RichTextBox呢?

    我尝试了下设置RichTextBox为Public,结果还是不能在外面的类调用它,尝试设置WinForm为Static这种蠢方法,也只是使过程变得原来越复杂。

    最后决定使用我最不想用的Windows消息方式(因为以前觉得比较麻烦)。虽然用的过程中有些存在风险,并且特别不专业,但是总之是达到了我想要的结果,也算是一个进步吧。

    1
    2
    [DllImport("User32.dll", EntryPoint ="SendMessage")]
    privatestaticexternIntPtr SendMessage(inthWnd,intmsg, IntPtr wParam, IntPtr lParam);

    当然,在使用过程中要用到这个SendMessage,具体的使用方法,参照http://blog.sina.com.cn/s/blog_90b91bf10100zj77.html,虽然有点问题,但是大体上是正确的。

    但是这个还不足以实现我的需求,因为我需要传递的是字符串,是string,而消息里面的两个参数wParam是IntPtr。在网上找了好一阵之后,发现这两篇文章很有指导意义:http://blog.csdn.net/lanruoshui/article/details/5432891http://blog.csdn.net/lanruoshui/article/details/5432953(同一个人写的,两篇文章有关联,主要是第二篇)。

    主体:

    首先,发送端在声明API函数的时候,直接声明wParam和lParam为string(不知道这么做有没有风险,但是确实没有报错……而且管用)

    1
    2
    3
    4
    [DllImport("User32.dll", EntryPoint ="SendMessage")]
    privatestaticexternIntPtr SendMessage(inthWnd,intmsg,stringwParam,stringlParam);
    [DllImport("User32.dll", EntryPoint ="FindWindow")]
    privatestaticexternintFindWindow(stringlpClassName,stringlpWindowName);

    然后,封装一个发送消息的函数SendMsgToMainForm,以便调用。这一部分与正常用法基本无异,需要注意封装的函数也需要修改参数属性为string。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //定义消息常数
    publicconstintCUSTOM_MESSAGE = 0X400 + 2;//自定义消息
    publicconstintCOMMAND_MESSAGE = 0X400 + 3;//指令消息
    //向窗体发送消息的函数
    publicvoidSendMsgToMainForm(intMSG,stringawParam,stringalParam)
    {
        intWINDOW_HANDLER = FindWindow(null, Factory.FormName);
        if(WINDOW_HANDLER == 0)
        {
            thrownewException("Could not find Main window!");
        }
        SendMessage(WINDOW_HANDLER, MSG, awParam, alParam);
        //立即执行此消息
        Application.DoEvents();
    }

    重点在接收端,也就是定义窗体的地方。使用string str = Marshal.PtrToStringAnsi(msg.WParam);//托管Marshal,把WParam托管为可以直接使用的string。这样一个字符串消息就传递过来了。调用窗体的WriteLog函数,来完成运行记录的记录。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    protectedoverridevoidWndProc(refSystem.Windows.Forms.Message msg)
    {
        stringstr = Marshal.PtrToStringAnsi(msg.WParam);//托管Marshal
        switch(msg.Msg)
        {
            caseICBC_BankChecking.CUSTOM_MESSAGE://处理消息
                {
                    this.WriteLog(str);
                }
                break;
            caseICBC_BankChecking.COMMAND_MESSAGE:
                {
                    switch(str)
                    {
                        case"00":
                            SetPage(true);
                            break;
                    }
                }
                break;
            default:
                base.WndProc(refmsg);//调用基类函数处理非自定义消息。
                break;
        }
    }
  • 相关阅读:
    最简单的 Java内存模型 讲解
    Chrome快捷键吐血整理
    【并发编程】InheritableThreadLocal使用详解
    【并发编程】Object的wait、notify和notifyAll方法
    【并发编程】Thread类的详细介绍
    【软件工具】easyExcel简明使用指南
    【并发编程】实现多线程的几种方式
    【并发编程】Java并发编程传送门
    CODING 研发管理系统上线全球加速,助力企业跨区域协作
    上帝的归上帝,凯撒的归凯撒—— CODING 权限管理更新
  • 原文地址:https://www.cnblogs.com/Ebony-Ivory/p/4291224.html
Copyright © 2020-2023  润新知