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

来源:互联网 发布:编辑网络大赛 编辑:程序博客网 时间:2024/04/30 19:34

01BroadcastSystemMessageBroadcastSystemMessageEx

功能说明

广播特定消息给特定的接收器,接收器可以是应用程序、或者是安装的驱动器、网络驱动器、系统级设备驱动器、或这些系统组件的任何组合。常见于系统将一条系统级消息广播给系统中所有的活动窗口,例如:系统检测到有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_VXDSWindows 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 NT4.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);

}

原创粉丝点击