2017-03-09 95 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,其以類似的方式處理。