You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
    

二、你的代码错误分析

  1. 变量l的跨分支污染问题
    在GUID_POWERSCHEME_PERSONALITY分支中,你未给变量l赋值,但后续直接执行If l = 0判断。此时l的值可能是内存垃圾值或初始默认的0,导致启动时误触发“显示器关闭”的断言。另外,GUID_POWERSCHEME_PERSONALITY对应的Data是16字节的GUID,根本不适合用4字节的l来接收。

  2. 判断条件未限定范围
    你的If l = 0判断放在所有GUID分支之外,意味着不管是哪种电源设置变更,只要l碰巧为0就会触发断言,这完全不符合逻辑——只有GUID_CONSOLE_DISPLAY_STATE或GUID_MONITOR_POWER_ON对应的Data为0时,才代表显示器关闭。

三、准确追踪显示器因用户无活动关闭的方法

  1. 监听正确的电源GUID
    需重点关注以下两个GUID的状态变更:

    • GUID_CONSOLE_DISPLAY_STATE:控制台显示状态,Data值含义:
      • 0:显示器关闭
      • 1:显示器开启
      • 2:显示器变暗(节电模式)
    • GUID_MONITOR_POWER_ON:主显示器电源状态,Data值含义:
      • 0:显示器关闭
      • 1:显示器开启
  2. 修正后的代码示例

    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
    
  3. 区分初始状态与变更事件
    首次注册电源通知时,系统会立即推送当前所有电源设置的状态。启动时收到的l=0可能是显示器当前的初始状态(比如启动时显示器已关闭),而非用户无活动触发的关闭事件。若需区分,可记录初始状态,后续仅处理从“开启(1)”变为“关闭(0)”的状态变更。

内容的提问来源于stack exchange,提问作者tmighty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 00:00:08