如何从GUID_POWERSCHEME_PERSONALITY设置中获取TGUID?

时间:2017-03-09 17:42:42

标签: delphi guid windows-messages

我一直致力于打包完整的WM_POWERBROADCAST Windows消息,并将其封装在事件驱动的组件中。其中大部分工作正常,我还进一步捕获了所有PBT_POWERSETTINGCHANGE setting GUID's - 除了一个GUID_POWERSCHEME_PERSONALITY

根据文档,我应该将Data成员翻译为TGUID ...

  

有源电力计划的个性发生了变化。所有电源方案都映射到其中一个人物。 数据成员是一个GUID,用于指示新的有效电源方案个性

问题在于提供的数据类型如下:

Data: packed array[0..0] of UCHAR;

如何从此TGUID成员中获取Data

以下是捕获PBT_POWERSETTINGCHANGE事件后我正在捕获其余设置的方法......

procedure TPowerMonitor.HandlePowerSetting(const Val: PPowerBroadcastSetting);
var
  VDWord: DWORD;
  function IsVal(G: String): Boolean;
  begin
    Result:= Assigned(Val);
    if Result then
      Result:= IsEqualGUID(StringToGUID(G), Val.PowerSetting);
  end;
begin
  if IsVal('{5d3e9a59-e9D5-4b00-a6bd-ff34ff516548}') then begin
    //GUID_ACDC_POWER_SOURCE
    VDWord:= DWORD(Val.Data[0]);
    if Assigned(Self.FOnSourceChange) then
      FOnSourceChange(Self, TPowerSource(VDWord));
  end else
  if IsVal('{a7ad8041-b45a-4cae-87a3-eecbb468a9e1}') then begin
    //GUID_BATTERY_PERCENTAGE_REMAINING
    VDWord:= DWORD(Val.Data[0]);
    if Assigned(Self.FOnBatteryPercent) then
      FOnBatteryPercent(Self, VDWord);
  end else
  if IsVal('{6fe69556-704a-47a0-8f24-c28d936fda47}') then begin
    //GUID_CONSOLE_DISPLAY_STATE
    VDWord:= DWORD(Val.Data[0]);
    if Assigned(FOnConsoleDisplayState) then
      FOnConsoleDisplayState(Self, TPowerDisplayState(VDWord));
  end else
  if IsVal('{786E8A1D-B427-4344-9207-09E70BDCBEA9}') then begin
    //GUID_GLOBAL_USER_PRESENCE
    VDWord:= DWORD(Val.Data[0]);
    if Assigned(FOnGlobalUserPresence) then
      FOnGlobalUserPresence(Self, TPowerUserPresence(VDWord));
  end else
  if IsVal('{515c31d8-f734-163d-a0fd-11a08c91e8f1}') then begin
    //GUID_IDLE_BACKGROUND_TASK
    if Assigned(FOnIdleBackgroundTask) then
      FOnIdleBackgroundTask(Self);
  end else
  if IsVal('{02731015-4510-4526-99e6-e5a17ebd1aea}') then begin
    //GUID_MONITOR_POWER_ON
    VDWord:= DWORD(Val.Data[0]);
    if Assigned(FOnMonitorPower) then
      FOnMonitorPower(Self, TPowerDisplayState(VDWord));
  end else
  if IsVal('{E00958C0-C213-4ACE-AC77-FECCED2EEEA5}') then begin
    //GUID_POWER_SAVING_STATUS
    VDWord:= DWORD(Val.Data[0]);
    if Assigned(FOnPowerSavingStatus) then
      FOnPowerSavingStatus(Self, TPowerSavingStatus(VDWord));
  end else
  if IsVal('{245d8541-3943-4422-b025-13A784F679B7}') then begin
    //GUID_POWERSCHEME_PERSONALITY
    //TODO: How to read "Data" as a TGUID?
    //GUID_MIN_POWER_SAVINGS (8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c)
    //GUID_MAX_POWER_SAVINGS (a1841308-3541-4fab-bc81-f71556f20b4a)
    //GUID_TYPICAL_POWER_SAVINGS (381b4222-f694-41f0-9685-ff5bb260df2e)
  end else
  if IsVal('{2B84C20E-AD23-4ddf-93DB-05FFBD7EFCA5}') then begin
    //GUID_SESSION_DISPLAY_STATUS
    VDWord:= DWORD(Val.Data[0]);
    if Assigned(FOnSessionDisplayState) then
      FOnSessionDisplayState(Self, TPowerDisplayState(VDWord));
  end else
  if IsVal('{3C0F4548-C03F-4c4d-B9F2-237EDE686376}') then begin
    //GUID_SESSION_USER_PRESENCE
    VDWord:= DWORD(Val.Data[0]);
    if Assigned(FOnSessionUserPresence) then
      FOnSessionUserPresence(Self, TPowerUserPresence(VDWord));
  end else
  if IsVal('{98a7f580-01f7-48aa-9c0f-44352c29e5C0}') then begin
    //GUID_SYSTEM_AWAYMODE
    VDWord:= DWORD(Val.Data[0]);
    if Assigned(FOnAwayMode) then
      FOnAwayMode(Self, TPowerAwayMode(VDWord));
  end else begin
    //Unrecognized GUID
    //TODO: Handle error
  end;
end;

1 个答案:

答案 0 :(得分:3)

这里记录在案:

POWERBROADCAST_SETTING structure

结构就是所谓的“可变长度结构”。最终成员可能比实际申报的时间更长。 DataLength成员会告诉您Data成员中实际存在多少数据。例如,您可以通过调用System.Move()来阅读它。

如果有效负载确实是GUID,则检查DataLength是否为GUID的大小,并将数据复制到GUID变量中。

var
  GUID: TGUID;
.... 
// check that DataLength = SizeOf(TGUID) 
Move(Data, GUID, DataLength);

其他电源方案GUID的数据通常为DWORD,以类似的方式处理。