PBT_POWERSETTINGCHANGE(32787)及lParam=206730400含义与显示器休眠检测问题
问题解答
一、PBT_POWERSETTINGCHANGE(32787)与lParam=206730400的含义
- PBT_POWERSETTINGCHANGE(数值32787)是Windows系统发送的电源设置变更通知消息,当系统的电源相关配置(如电源方案、显示器状态、睡眠模式等)发生变化时,会向注册了电源通知的窗口推送该消息。
lParam=206730400是一个内存地址,指向POWERBROADCAST_SETTING结构体的起始位置,本身无直接业务含义,需解析该结构体获取具体变更信息:typedef struct { GUID PowerSetting; // 标识具体变更的电源设置类型 DWORD DataLength; // 后续数据的长度 UCHAR Data[1]; // 变更的具体数据,长度由DataLength决定 } POWERBROADCAST_SETTING, *PPOWERBROADCAST_SETTING;
二、你的代码错误分析
变量l的跨分支污染问题
在GUID_POWERSCHEME_PERSONALITY分支中,你未给变量l赋值,但后续直接执行If l = 0判断。此时l的值可能是内存垃圾值或初始默认的0,导致启动时误触发“显示器关闭”的断言。另外,GUID_POWERSCHEME_PERSONALITY对应的Data是16字节的GUID,根本不适合用4字节的l来接收。判断条件未限定范围
你的If l = 0判断放在所有GUID分支之外,意味着不管是哪种电源设置变更,只要l碰巧为0就会触发断言,这完全不符合逻辑——只有GUID_CONSOLE_DISPLAY_STATE或GUID_MONITOR_POWER_ON对应的Data为0时,才代表显示器关闭。
三、准确追踪显示器因用户无活动关闭的方法
监听正确的电源GUID
需重点关注以下两个GUID的状态变更:- GUID_CONSOLE_DISPLAY_STATE:控制台显示状态,Data值含义:
- 0:显示器关闭
- 1:显示器开启
- 2:显示器变暗(节电模式)
- GUID_MONITOR_POWER_ON:主显示器电源状态,Data值含义:
- 0:显示器关闭
- 1:显示器开启
- GUID_CONSOLE_DISPLAY_STATE:控制台显示状态,Data值含义:
修正后的代码示例
Select Case wParam Case PBT_POWERSETTINGCHANGE CopyMemory pbs, ByVal lParam, Len(pbs) Dim settingGuid As String settingGuid = GuidToString(pbs.PowerSetting) Select Case settingGuid Case GUID_POWERSCHEME_PERSONALITY CopyMemory g, ByVal lParam + Len(pbs), 16 DebugPrint "New power scheme: " & GuidToString(g) Case GUID_SESSION_DISPLAY_STATUS CopyMemory l, ByVal lParam + Len(pbs), 4 DebugPrint "Display status: " & l Case GUID_MONITOR_POWER_ON CopyMemory l, ByVal lParam + Len(pbs), 4 DebugPrint "Primary Monitor state: " & l ' 仅在该GUID下判断显示器关闭状态 If l = 0 Then DebugPrint "Monitor turned off due to inactivity" ' 此处添加显示器关闭的处理逻辑 End If Case GUID_CONSOLE_DISPLAY_STATE CopyMemory l, ByVal lParam + Len(pbs), 4 DebugPrint "Console Display state: " & l ' 仅在该GUID下判断显示器关闭状态 If l = 0 Then DebugPrint "Console display turned off due to inactivity" ' 此处添加显示器关闭的处理逻辑 End If End Select End Select区分初始状态与变更事件
首次注册电源通知时,系统会立即推送当前所有电源设置的状态。启动时收到的l=0可能是显示器当前的初始状态(比如启动时显示器已关闭),而非用户无活动触发的关闭事件。若需区分,可记录初始状态,后续仅处理从“开启(1)”变为“关闭(0)”的状态变更。
内容的提问来源于stack exchange,提问作者tmighty
相关产品推荐
相关产品推荐

