Win32消息处理API---BroadcastSystemMessage、BroadcastSystemMessageEx

    技术2022-05-19  21

    01 BroadcastSystemMessageBroadcastSystemMessageEx

    功能说明

    广播特定消息给特定的接收器,接收器可以是应用程序、或者是安装的驱动器、网络驱动器、系统级设备驱动器、或这些系统组件的任何组合。常见于系统将一条系统级消息广播给系统中所有的活动窗口,例如:系统检测到有USB 盘插拔、有光盘放入光驱、或者检测出新硬件等,系统就使用BroadcastSystemMessage 将该消息广播到系统中去,使跟这些设备相关联的程序去处理对应事件。一般用到的情况是使用它给一组应用程序(该组应用程序能够接收到同一个消息)广播统一的消息,例如关闭当前系统所有打开的窗口等。

    二者区别在于BroadcastSystemMessageEx 可以从消息接收器返回更多的信息。

     

    函数形式

    long   BroadcastSystemMessage (

    DWORD   dwFlags,         // 发送消息的方式

    LPDWORD lpdwRecipients, // 消息接受器 的信息,消息发送的目标

    UINT   uiMessage,          // 系统消息标识符

    WPARAM   wParam,        // 消息参数

    LPARAM   lParam          // 消息参数

    );

     

    long   BroadcastSystemMessageEx (

    DWORD   dwFlags,         // 发送消息的方式

    LPDWORD lpdwRecipients, // 消息接受器 的信息,消息发送的目标

    UINT   uiMessage,          // 系统消息标识符

    WPARAM   wParam,        // 消息参数

    LPARAM   lParam          // 消息参数

      PBSMINFO pBSMInfo     // 接收到的附加信息

    );

     

    参数说明

    1 〉、dwFlags ,【in

    发送消息的方式,可取下列值的组合:

      BSF_FLUSHDISK :消息接收器处理消息之后清理磁盘。

      BSF_FORCEIFHUNG :继续广播消息,即使超时周期结束或一个目标已挂起。

      BSF_IGNORECURRENTTASK :不发送消息给属于当前任务的窗口,这样,应用程序就不会接收自己的消息。

      BSF_NOHANG :强制无反应的应用程序超时,如果一个接收器超时,就不再继续广播消息。

      BSF_NOTIMEOUTIFNOTHUNG :只要接收器没挂起,一直等待对消息的响应,且不会出现超时。

      BSF_POSTMESSAGE :发送消息,不能跟BSF_QUERY 混合使用。

    BSF_QUERY :每次发送消息给一个接受器,只有当前接受器返回TRUE 后,才能发送给下一个接受器。

    BSF_SENDNOTIFYMESSAGE :在Windows 2000/XP 中,以SendNotifyMessage 替代,不能跟BSF_QUERY 混合使用。

     

    2 〉、lpdwRecipients

    指向变量的指针,该变量包含接收消息的 消息接受器 的信息,或者叫做消息发送的目标。此变量可为下列值的组合:

    in 】,<BroadcastSystemMessage> 取值如下:

      BSM_ALLCOMPONENTS :广播到所有的系统组件。

      BSM_ALLDESKTOPSWindows NT 下,广播到所有的桌面。要求SE_TCB_NAME 特权。

      BSM_APPLICATIONS :广播到应用程序。

      BSM_INSTALLABLEDRIVERSWindows 95/98/ME 下,广播到安装驱动器。

      BSM_INTDRIVERWindows 95/98/ME 下,广播到网络驱动器。

    BSM_VXDS Windows 95/98/ME 下,广播到所有系统级设备驱动器。

    in, out 】,<BroadcastSystemMessageEx> 取值如下:

    BSM_ALLCOMPONENTS :广播到所有的系统组件。

      BSM_ALLDESKTOPSWindows NT 下,广播到所有的桌面。要求SE_TCB_NAME 特权。

    BSM_APPLICATIONS :广播到应用程序。

     

    当函数返回时,此变量接受上述值的组合,用于表示哪个接受器真正地接到了消息。如果此参数为NULL ,则将消息广播到所有的组件。

     

    3 〉、uiMessage ,【in

    系统消息标识符,也就是所谓的消息ID ,例如WM_LBUTTONWM_RBUTTONWM_KEY 等,都属于消息ID

    4 〉、Wparam ,【in

    消息参数之一,属于字消息,是对 uiMessage 指定的字信息,其意义取决于具体的 uiMessage 的值。

    5 〉、Iparam ,【in

    消息参数之一,属于值消息,是对 uiMessage 指定的值信息,其意义取决于具体的 uiMessage 的值,有时也称LPARAM 为事件。

    6> pBSMInfo,out

    针对函数BroadcastSystemMessageEx 的参数,是 BSMINFO 类型的指针,如果请求被拒绝或者传入的参数dwFlags 被设置为BSF_QUERY 时,函数所能接收到的附加信息。

     

    返回值

    函数调用成功,返回值为正;

    如果函数不能广播消息,返回值是-1

    如果参数dwFlagsBSF_QUERY 且至少一个接受器返回BROADCAST_QUERY_DENY 给对应的消息,则返回值是零。若想获得更多的错误信息,请调用GetLastError 函数。

     

    备注

    如果dwFlags 没有包含BSF_QUERY ,则函数向所有请求的接受器发送指定的消息,并忽略这些接受器返回的值。

     

    适用

    Windows NT 4.0 及以上版本:Windows95 及以上版本;Windows CE :不支持;头文件:winuser.h ;输入库:user32.libUnicode :在Windows NT 环境下以UnicodeANSI 方式实现。

     

    应用举例

    当设备被热插拔的时候(例如U 盘),WINDOWS 会向系统广播WM_DEVICECHANGE 消息。如果字消息(wParam )的值为 DBT_DEVICEARRIVAL ,则表示设备插入并且已经可用;如果字消息(wParam )的值为DBT_DEVICEREMOVECOMPLETE ,则表示设备已经移出。它们值消息(lParam )的值 为一个DEV_BROADCAST_HDR 类型的指针,DEV_BROADCAST_HDR 定义如下:

    typedef struct _DEV_BROADCAST_HDR

    {

    DWORD   dbch_size;

        DWORD dbch_devicetype;

        DWORD dbch_reserved;

    }   DEV_BROADCAST_HDR, *PDEV_BROADCAST_HDR;

    成员含义:

    dbch_size 结构体大小,以字节数衡量;如果所传递的事件属于用户自定义事件,则dbch_size 的值等于该结构体大小,再加上_DEV_BROADCAST_USERDEFINED 中其它变量的总长度。

    dbch_devicetype 设备类型,其值跟设备数据相关联,该关联具体如下:

    VALUE

    含义

    DBT_DEVTYP_DEVICEINTERFACE

    设备类,lParam 为一个指向DEV_BROADCAST_DEVICEINTERFACE 数据结构的指针

    DBT_DEVTYP_HANDLE

    文件系统处理,lParam 为一个指向DEV_BROADCAST_HANDLE 数据结构的指针

    DBT_DEVTYP_OEM

    OEM 或者IHV 定义的设备类型,lParam 为一个指向DEV_BROADCAST_OEM 数据结构的指针

    DBT_DEVTYP_PORT

    端口设备(串口或者并口),lParam 为一指向DEV_BROADCAST_PORT 数据结构的指针

    DBT_DEVTYP_VOLUME

    逻辑驱动器,lParam 为一指向DEV_BROADCAST_VOLUME 数据结构的指针

     

    例一,这段代码用于检测CD-ROM 中光盘的状态

    #include   <windows.h>

    #include   <dbt.h>

    #include   <strsafe.h>

     

    // 函数声明

    void   Main_OnDeviceChange(HWND hwnd, WPARAM wParam, LPARAM lParam);

     

    // 函数声明

    char   FirstDriveFromMask(ULONG unitmask);

     

    // 功能说明 Handles WM_DEVICECHANGE messages sent to the application's top-level window.

    void   Main_OnDeviceChange (HWND hwnd, WPARAM wParam, LPARAM lParam)

    {

         PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;

         char szMsg[80];

         switch (wParam)

         {

         case DBT_DEVICEARRIVAL:

             // Check whether a CD or DVD was inserted into a drive.

             if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)

             {

                 PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;

                 if (lpdbv -> dbcv_flags & DBTF_MEDIA)

                   {

                     StringCchPrintf(szMsg, 80, _T("Drive %c: Media has arrived./n" ),

                          FirstDriveFromMask(lpdbv ->dbcv_unitmask));

                     MessageBox (hwnd, szMsg, _T("WM_DEVICECHANGE" ), MB_OK);

                 }

             }

             break ;

         case DBT_DEVICEREMOVECOMPLETE:

             // Check whether a CD or DVD was removed from a drive.

            if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)

            {

                 PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;

                  if (lpdbv -> dbcv_flags & DBTF_MEDIA)

                   {

    StringCchPrintf(szMsg, 80, _T("Drive %c: Media was removed./n" ),

                       FirstDriveFromMask(lpdbv ->dbcv_unitmask));

                    MessageBox (hwnd, szMsg, _T("WM_DEVICECHANGE" ), MB_OK);

                 }

             }

             break ;

     

         default : // 处理其余WM_DEVICECHANGE 事件

             break ;

         }

    }

     

    //  功能说明 Finds the first valid drive letter from a mask of drive letters. The mask must be in the

    //    format bit 0 = A, bit 1 = B, bit 3 = C, etc. A valid drive letter is defined when the corresponding

    //    bit is set to 1.

    //  Returns the first drive letter that was found.

    char   FirstDriveFromMask (ULONG unitmask)

    {

         char i;

         for (i = 0; i < 26; ++i)

         {

             if (unitmask & 0x1)  break ;

             unitmask = unitmask >> 1;

         }

         return (i + 'A' );

    }

     

    例二,关闭IE 及其它应用程序

    // 关闭IE 及其它应用程序

    void   CloseAllApplication()

    {

    int   app = BSM_APPLICATIONS;

    unsigned long   bsm_app = (unsigned long)app;

    BroadcastSystemMessage (BSF_POSTMESSAGE, &bsm_app, WM_CLOSE, NULL, NULL);

    }

     


    最新回复(0)