• 消息处理(四)


    一、线程消息

          在窗体应用中,线程可调用窗口过程处理属于他创建的某个窗口的消息(投递而来),此外还可以直接处理其他线程投递的消息。

    (1)定义线程消息标志

          线程消息可以是任意的,不必为WM_USER,当然为了获得系统范围内唯一的消息标志,也可以使用自定义的登记消息作为线程消息

          UINT MYTHREADMSG = RegisterWindowMessage("MYTHREADMSG");

    提示:不用static关键字修饰MYTHREADMSG 变量,使得其他CPP文件中可以使用该变量。

    (2)手工修改CWindThread的消息映射表,添加线程消息映射宏

         跟线程消息相关的映射宏有两个:ON_THREAD_MESSAGE和ON_REGISTERED_THREAD_MESSAGE。前者处理一般的线程消息,而后者专用于处理登记的线程消息。

    #define ON_THREAD_MESSAGE(message,memberFxn)
    {message,0,0,0,AfxSig_vwl,
    (AFX_PMSG)(AFX_PMSGT)(static_cast<void (AFX_MSG_CALL CWinThread::*)(WPARAM,LPARAM)>(memberFxn))},
    #define ON_REGISTERED_THREAD_MESSAGE(message,memberFxn)
    {message,0,0,0,(UINT_PTR)(UINT *)(&nMessageVariable),
    (AFX_PMSG)(AFX_PMSGT)(static_cast<void (AFX_MSG_CALL CWinThread::*)(WPARAM,LPARAM)>(memberFxn))},

     从上面的定义可以看出:

          a.只有CWinThread类才允许处理线程消息。

          b.线程消息处理函数的签名形式为:void (WPARAM,LPARAM)

    (3)实现处理线程消息的成员

         void (WPARAM,LPARAM)

    (4)引发线程消息。

         通过调用CWinThread对象的PostThreadMessage,将线程消息投递到CWinThread对象的线程队列。

    Example:

    二、跨进程处理消息

          进程是操作系统分配资源的基本单位。每个进程都有一个独立的地址空间,并至少拥有一个线程来执行其代码。事实上,Windows提供的消息处理机制是完全可以跨进程进行的。虽然每个进程都在独立的地址空间中运行,但是各个进程都共享一段系统分区(又称核心区),核心区将被映射到每个进程空间中,并且其位置也是固定的。操作系统在核心区放置了一些关键数据(这些数据又称核心对象),并提供了一组API函数对这些数据进行操作。而这些核心区恰好就保存了系统当前创建的所有窗口,并将每个窗口和创建它的线程关联起来。

          因为由核心区的数据提供的信息,系统可以定位到任何一个窗口,从窗口出发,系统还可以找到创建该窗口的线程,然后就可以轻易的把消息放入线程的消息队列中。

    (1)定位到接收消息的窗口

          为了找到接收消息的窗口,可以调用FindWindow,依据窗口的类名和窗口名(也就是窗口标题)查找特定的窗口:

    HWND FindWindow(
         LPCTSTR lpClassName,             //窗口类名
          LPCTSTR lpWindowName             //窗口名,也就是窗口标题
    );

          可以将lpClassName或lpWindowName设为NULL,这时将忽略窗口类名或窗口名,仅依据一个条件进行搜索。这种方法最多只能返回一个窗口。
          如果要支持查找多个窗口,可以用EnumWindow函数:

    BOOL EnumWindows(
         WNDENUMPROC lpEnumFunc,            //回调函数
          LPARAM lParam                      //回调函数的参数
    );

          每当找到一个窗口,系统就会执行lpEnumFunc,其原型定义为:BOOL CALLBACK (HWND hWnd, LPARAM lParam)

          参数hWnd表示当前正在枚举的窗口,lParam是由调用EnumWindows时的第二参数lParam规定的,如果希望继续枚举窗口,则返回TRUE,否则返回FALSE。在回调函数内,可以依据一定的条件判断hWnd窗口是否为目标窗口,若是,则可以向其发送消息。

          提示:对于代表窗口的窗口句柄,其值在系统范围都是唯一的,这也简化了跨进程的消息通信的实现。

    (2)向窗口发送消息

           找到目标窗口后,就可以用SendMessage或PostMessage向其发送或投递消息。

    (3)目标窗口响应消息

          消息映射宏:ON_REGISTERED_MESSAGE

          成员函数的签名:LRESULT (WPARAM,LPARAM)

    Example:

  • 相关阅读:
    高精度模板_C++
    NOIP总结
    HDU2063_过山车_C++
    手写堆_C++
    NOIP2013Day1解题报告
    [ CodeVS冲杯之路 ] P1368
    POJ1002_487-3279_C++
    [ CodeVS冲杯之路 ] P1092
    POJ2376_Cleaning Shifts_C++
    欧几里得距离_曼哈顿距离_切比雪夫距离
  • 原文地址:https://www.cnblogs.com/chengtulang/p/3196414.html
Copyright © 2020-2023  润新知