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

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);

}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值