I have pushed the envelop further by defining some helper functions which retrieves laptop specific information and some other as well, so without further introduction here's the unit that I've wrote, feel free to use it in commercial and/or personal applications AT YOUR OWN RISK of course, also if you find some flaws(high probability -- haven't tested enough) please feel free to drop a comment.
unit uDGMobileUtils;
interface
(*******************************************************************************
Author:
Dorin Duminica
Note:
That Parts of the code are Copyright© of Microsoft Corporation.
All Rights Reserved.
Disclaimer:
Using the following code represents your acknowledgement that YOU TAKE
FULL RESPONSABILITY of any damage it can and/or might cause to your
system, country, pets, etc.
Requirements:
According to Microsoft the following code should work starting from
Windows 2000 Professional and Server
*******************************************************************************)
uses
Windows;
{$Z4} // required in order to have 4 byte enumerated type
type
SYSTEM_POWER_STATE =(
PowerSystemUnspecified,
PowerSystemWorking,
PowerSystemSleeping1,
PowerSystemSleeping2,
PowerSystemSleeping3,
PowerSystemHibernate,
PowerSystemShutdown,
PowerSystemMaximum);
{$Z1} // restore enumerated type to 1 byte
const
SYSTEM_POWER_STATE_NAMES: array[SYSTEM_POWER_STATE] of string = (
'Unspecified',
'Working',
'Sleeping 1',
'Sleeping 2',
'Sleeping 3',
'Hibernate',
'Shutdown',
'Maximum');
type
BATTERY_REPORTING_SCALE = record
Granularity: ULONG;
Capacity: ULONG;
end;
PBATTERY_REPORTING_SCALE = ^BATTERY_REPORTING_SCALE;
type
SYSTEM_POWER_CAPABILITIES = record
// If this member is TRUE, there is a system power button.
PowerButtonPresent: Boolean;
// If this member is TRUE, there is a system sleep button.
SleepButtonPresent: Boolean;
// If this member is TRUE, there is a lid switch.
LidPresent: Boolean;
// for S1 —> S5 check microsoft site
SystemS1: Boolean;
SystemS2: Boolean;
SystemS3: Boolean;
SystemS4: Boolean;
SystemS5: Boolean;
// If this member is TRUE, the operating system supports power off state S5 (soft off).
HiberFilePresent: Boolean;
// If this member is TRUE, the system supports wake capabilities.
FullWake: Boolean;
// If this member is TRUE, the system supports video display dimming capabilities.
VideoDimPresent: Boolean;
// If this member is TRUE, the system supports APM BIOS power management features.
ApmPresent: Boolean;
// If this member is TRUE, there is an uninterruptible power supply (UPS).
UpsPresent: Boolean;
// If this member is TRUE, the system supports thermal zones.
ThermalControl: Boolean;
// If this member is TRUE, the system supports processor throttling.
ProcessorThrottle: Boolean;
// The minimum level of system processor throttling supported,
// expressed as a percentage.
ProcessorMinThrottle: UCHAR;
// The maximum level of system processor throttling supported,
// expressed as a percentage.
ProcessorMaxThrottle: UCHAR;
// If this member is TRUE, the system supports the hybrid sleep state.
// Windows Server 2003 and Windows XP: Hybrid sleep is not supported.
// Windows 2000: This member is not supported.
FastSystemS4: Boolean;
// reserved
spare2: array [0 .. 3] of UCHAR;
// If this member is TRUE, the system supports allowing the removal of power
// to fixed disk devices.
DiskSpinDown: Boolean;
// reserved
spare3: array [0 .. 7] of UCHAR;
// If this member is TRUE, there are one or more batteries in the system.
SystemBatteriesPresent: Boolean;
// If this member is TRUE, the system batteries are short-term.
// Short-term batteries are used in uninterruptible power supplies (UPS).
BatteriesAreShortTerm: Boolean;
// A BATTERY_REPORTING_SCALE structure that contains information about
// how system battery metrics are reported.
BatteryScale: array [0 .. 2] of BATTERY_REPORTING_SCALE;
// The lowest system sleep state (Sx) that will generate a wake event when
// the system is on AC power. This member must be one of the
// SYSTEM_POWER_STATE enumeration type values.
AcOnLineWake: SYSTEM_POWER_STATE;
// The lowest system sleep state (Sx) that will generate a wake event via
// the lid switch. This member must be one of the SYSTEM_POWER_STATE
// enumeration type values.
SoftLidWake: SYSTEM_POWER_STATE;
// To wake the computer using the RTC, the operating system must also
// support waking from the sleep state the computer is in when the RTC
// generates the wake event. Therefore, the effective lowest sleep state
// from which an RTC wake event can wake the computer is the lowest sleep
// state supported by the operating system that is equal to or higher than
// the value of RtcWake. To determine the sleep states that the operating
// system supports, check the SystemS1, SystemS2, SystemS3, and SystemS4 members.
RtcWake: SYSTEM_POWER_STATE;
// The minimum allowable system power state supporting wake events.
// This member must be one of the SYSTEM_POWER_STATE enumeration type values.
// Note that this state may change as different device drivers are
// installed on the system.
MinDeviceWakeState: SYSTEM_POWER_STATE;
// The default system power state used if an application calls
// RequestWakeupLatency with LT_LOWEST_LATENCY. This member must be one of
// the SYSTEM_POWER_STATE enumeration type values.
DefaultLowLatencyWake: SYSTEM_POWER_STATE;
end;
PSYSTEM_POWER_CAPABILITIES = ^SYSTEM_POWER_CAPABILITIES;
type
TACLineStatus = (
// battery
acsOffline = 0,
// plugged in
acsOnline = 1,
acsUnknown = 255);
type
TBatteryState = (
// High—the battery capacity is at more than 66 percent
bsHigh = 1,
// Low—the battery capacity is at less than 33 percent
bsLow = 2,
// Critical—the battery capacity is at less than five percent
bsCritical = 4,
bsCharging = 8,
bsNoSystemBattery = 128,
// Unknown status—unable to read the battery flag information
bsUnknown = 255);
TBatteryStatus = set of TBatteryState;
function GetPwrCapabilities(lpSystemPowerCapabilities: PSYSTEM_POWER_CAPABILITIES): Boolean; stdcall;
function IsAdminOverrideActive: Boolean; stdcall;
function IsPwrHibernateAllowed: Boolean; stdcall;
function IsPwrShutdownAllowed: Boolean; stdcall;
function IsPwrSuspendAllowed: Boolean; stdcall;
// utility
function IsLidPresent: Boolean;
function IsRunningMobile: Boolean;
function IsRunningOnBattery: Boolean;
function IsPowerBtnPresent: Boolean;
function IsApmPresent: Boolean;
function IsUpsPresent: Boolean;
function IsThermalControl: Boolean;
function GetACLineStatus: TACLineStatus;
function GetACLineStatusName(const AACLineStatus: TACLineStatus): string;
function GetBatteryStatus: TBatteryStatus;
function GetBatteryStateName(const ABatteryState: TBatteryState): string;
function GetBatteryStatusStr(const ABatteryState: TBatteryStatus;
const ADelimiter: Char = ','): string;
function GetBatteryLifePercent: Byte;
function GetBatteryLifeTime: DWORD;
function GetBatteryLifeTimeFull: DWORD;
function GetNumberOfProcessors: DWORD;
function GetSystemPowerStateName(const ASystemPowerState: SYSTEM_POWER_STATE): string;
implementation
uses
SysUtils,
Classes;
const
powrproflib = 'powrprof.dll';
function GetPwrCapabilities(lpSystemPowerCapabilities: PSYSTEM_POWER_CAPABILITIES): Boolean; external powrproflib name 'GetPwrCapabilities';
function IsAdminOverrideActive: Boolean; external powrproflib name 'IsAdminOverrideActive';
function IsPwrHibernateAllowed: Boolean; external powrproflib name 'IsPwrHibernateAllowed';
function IsPwrShutdownAllowed: Boolean; external powrproflib name 'IsPwrShutdownAllowed';
function IsPwrSuspendAllowed: Boolean; external powrproflib name 'IsPwrSuspendAllowed';
function IsLidPresent: Boolean;
var
LSYSTEM_POWER_CAPABILITIES: SYSTEM_POWER_CAPABILITIES;
begin
Result := GetPwrCapabilities(@LSYSTEM_POWER_CAPABILITIES);
if Result then
Result := LSYSTEM_POWER_CAPABILITIES.LidPresent;
end;
function IsRunningMobile: Boolean;
begin
Result := IsLidPresent or IsRunningOnBattery;
end;
function IsRunningOnBattery: Boolean;
begin
Result := (GetACLineStatus = acsOffline);
end;
function IsPowerBtnPresent: Boolean;
var
LSYSTEM_POWER_CAPABILITIES: SYSTEM_POWER_CAPABILITIES;
begin
Result := GetPwrCapabilities(@LSYSTEM_POWER_CAPABILITIES);
if Result then
Result := LSYSTEM_POWER_CAPABILITIES.PowerButtonPresent;
end;
function IsApmPresent: Boolean;
var
LSYSTEM_POWER_CAPABILITIES: SYSTEM_POWER_CAPABILITIES;
begin
Result := GetPwrCapabilities(@LSYSTEM_POWER_CAPABILITIES);
if Result then
Result := LSYSTEM_POWER_CAPABILITIES.ApmPresent;
end;
function IsUpsPresent: Boolean;
var
LSYSTEM_POWER_CAPABILITIES: SYSTEM_POWER_CAPABILITIES;
begin
Result := GetPwrCapabilities(@LSYSTEM_POWER_CAPABILITIES);
if Result then
Result := LSYSTEM_POWER_CAPABILITIES.UpsPresent;
end;
function IsThermalControl: Boolean;
var
LSYSTEM_POWER_CAPABILITIES: SYSTEM_POWER_CAPABILITIES;
begin
Result := GetPwrCapabilities(@LSYSTEM_POWER_CAPABILITIES);
if Result then
Result := LSYSTEM_POWER_CAPABILITIES.ThermalControl;
end;
function GetACLineStatus: TACLineStatus;
var
LSystemPowerStatus: TSystemPowerStatus;
begin
Result := acsUnknown;
if GetSystemPowerStatus(LSystemPowerStatus) then
Result := TACLineStatus(LSystemPowerStatus.ACLineStatus);
end;
function GetACLineStatusName(const AACLineStatus: TACLineStatus): string;
begin
Result := 'Unknown';
case AACLineStatus of
acsOffline: Result := 'Offline';
acsOnline: Result := 'Online';
end; // case AACLineStatus of
end;
function GetBatteryStatus: TBatteryStatus;
var
LSystemPowerStatus: TSystemPowerStatus;
procedure CheckState(const ABatteryState: TBatteryState);
begin
if (LSystemPowerStatus.BatteryFlag and Ord(ABatteryState)) = Ord(ABatteryState) then
Include(Result, ABatteryState);
end; // procedure CheckState(const ABatteryState: TBatteryState);
begin
Result := [];
if GetSystemPowerStatus(LSystemPowerStatus) then begin
CheckState(bsHigh);
CheckState(bsLow);
CheckState(bsCritical);
CheckState(bsCharging);
CheckState(bsNoSystemBattery);
CheckState(bsUnknown);
end else
Result := [bsUnknown];
end;
function GetBatteryStateName(const ABatteryState: TBatteryState): string;
begin
case ABatteryState of
bsHigh: Result := 'High';
bsLow: Result := 'Low';
bsCritical: Result := 'Critical';
bsCharging: Result := 'Charging';
bsNoSystemBattery: Result := 'No system battery';
bsUnknown: Result := 'Unknown';
end; // case ABatteryState of
end;
function GetBatteryStatusStr(const ABatteryState: TBatteryStatus;
const ADelimiter: Char): string;
var
LBatteryState: TBatteryState;
LNames: TStringList;
begin
Result := EmptyStr;
LNames := TStringList.Create;
try
LNames.Delimiter := ADelimiter;
for LBatteryState in ABatteryState do
LNames.Add(GetBatteryStateName(LBatteryState));
Result := LNames.DelimitedText;
finally
FreeAndNil(LNames);
end; // tryf
end;
function GetBatteryLifePercent: Byte;
var
LSystemPowerStatus: TSystemPowerStatus;
begin
Result := 0;
if GetSystemPowerStatus(LSystemPowerStatus) then
// The percentage of full battery charge remaining.
// This value in the range 0 to 100 or 255 if status is unknown.
Result := LSystemPowerStatus.BatteryLifePercent;
end;
function GetBatteryLifeTime: DWORD;
var
LSystemPowerStatus: TSystemPowerStatus;
begin
Result := DWORD(-1);
if GetSystemPowerStatus(LSystemPowerStatus) then
// The number of seconds of battery life remaining,
// or –1 if remaining seconds are unknown.
Result := LSystemPowerStatus.BatteryLifeTime;
end;
function GetBatteryLifeTimeFull: DWORD;
var
LSystemPowerStatus: TSystemPowerStatus;
begin
Result := DWORD(-1);
if GetSystemPowerStatus(LSystemPowerStatus) then
// The number of seconds of battery life when at full charge,
// or –1 if full battery lifetime is unknown.
Result := LSystemPowerStatus.BatteryFullLifeTime;
end;
function GetNumberOfProcessors: DWORD;
var
LSystemInfo: TSystemInfo;
begin
GetSystemInfo(LSystemInfo);
// number of processor means number of threads
// i.e. a processor with 4 cores can have 8 threads
Result := LSystemInfo.dwNumberOfProcessors;
end;
function GetSystemPowerStateName(const ASystemPowerState: SYSTEM_POWER_STATE): string;
begin
Result := SYSTEM_POWER_STATE_NAMES[ASystemPowerState];
end;
end.
How to use it:a) drop a memo and a button on the form, rename the memo to "edInfo"
b) double-click the button and copy-paste the following code
procedure TForm1.Button1Click(Sender: TObject);
procedure AddBool(const s: string; const Value: Boolean);
begin
edInfo.Lines.Add(Format('%s = %s', [s, BoolToStr(Value, True)]));
end; // procedure AddBool(const s: string; const Value: Boolean);
procedure AddString(const s, Value: string);
begin
edInfo.Lines.Add(Format('%s = %s', [s, Value]));
end; // procedure AddString(const s, Value: string);
procedure AddPercent(const s: string; const Value: Byte);
begin
edInfo.Lines.Add(Format('%s = %d%%', [s, Value]));
end; // procedure AddPercent(const s: string; const Value: Byte);
procedure AddSeconds(const s: string; const Value: DWORD);
begin
edInfo.Lines.Add(Format('%s = %d sec.', [s, Value]));
end; // procedure AddSeconds(const s: string; const Value: DWORD);
procedure AddDWord(const s: string; const Value: DWORD);
begin
edInfo.Lines.Add(Format('%s = %d', [s, Value]));
end; // procedure AddDWord(const s: string; const Value: DWORD);
begin
edInfo.Clear;
AddBool('IsLidPresent', IsLidPresent);
AddBool('IsRunningMobile', IsRunningMobile);
AddBool('IsRunningOnBattery', IsRunningOnBattery);
AddBool('IsPowerBtnPresent', IsPowerBtnPresent);
AddBool('IsApmPresent', IsApmPresent);
AddBool('IsUpsPresent', IsUpsPresent);
AddBool('IsThermalControl', IsThermalControl);
AddString('GetACLineStatus', GetACLineStatusName(GetACLineStatus));
AddString('GetBatteryStatusStr', GetBatteryStatusStr(GetBatteryStatus));
AddPercent('GetBatteryLifePercent', GetBatteryLifePercent);
// if GetBatteryLifeTime = -1 it means that laptop is either plugged in OR
// it is running on battery for a few seconds -- Windows did NOT detect
// yet or it can't tell for certain how many seconds left
// also the value might increase in a couple of seconds
AddSeconds('GetBatteryLifeTime', GetBatteryLifeTime);
// in my tests GetBatteryLifeTimeFull retrieves only -1 it might have something
// to do with the fact that my laptop is only a couple of days old
// or something fails -- I'm NOT 100% sure on this, please feel free to comment
AddSeconds('GetBatteryLifeTimeFull', GetBatteryLifeTimeFull);
AddDWord('GetNumberOfProcessors', GetNumberOfProcessors);
end;
c) and last but not least HAVE FUN!!
No comments:
Post a Comment