2017-03-09 243 views
0

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

根据该文件,我应该到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

'if(Val.DataLength> = SizeOf(TGUID))和IsEqualGUID(GUID_MIN_POWER_SAVINGS,PGUID(@ Val.Data [0])^)then ... –

+0

@ondrej您可以有用地省略[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,其以类似的方式处理。