Reputation: 352
I'm taking my first steps in Delphi, I've created a small program that uses the GetSystemPowerStatus
function to get battery status information.
To load the function, I used the Winapi.Windows
unit.
Everything worked fine, but the EXE file after compilation took up 150 kb.
From what I understand from this post, using the Winapi.Windows
unit is the cause of the increase, but I have not found how to access the GetSystemPowerStatus
function without using the unit.
Is this possible, and how can it be done?
Well, after Remy Lebeau's answer I did it like this:
program GetBatteryData;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
type
TSystemPowerStatus = record
ACLineStatus: Byte;
BatteryFlag: Byte;
BatteryLifePercent: Byte;
SystemStatusFlag: Byte;
BatteryLifeTime: UInt32;
BatteryFullLifeTime: UInt32;
end;
var
PowerState: TSystemPowerStatus;
Param: String;
function GetSystemPowerStatus(var lpSystemPowerStatus: TSystemPowerStatus): LongBool; stdcall; external 'Kernel32';
procedure ShowHelp;
begin
Writeln('Usage:');
Writeln(#32#32'GetBatteryData <query>'#10#13);
Writeln('queries:'#10#13);
Writeln(#32#32'ACState'#9'Get State of AC power');
Writeln(#32#32'LeftPercent'#9'Get the left percent on battery');
Writeln(#32#32'StateFlag'#9'Get the system flag of battery');
end;
function BatteryStateACPower(ACState: Byte): String;
begin
case ACState of
0: Result := 'Not Charged';
1: Result := 'Charged';
255: Result := 'Unknown battery state';
end;
end;
function BatteryStatePercent(LeftPercent: Byte): String;
begin
case LeftPercent of
0..100: Result := IntToStr(LeftPercent);
255: Result := 'Unknown battery state';
end;
end;
function BatteryStateFlags(Flag: Byte): String;
begin
case Flag of
1: Result := 'High';
2: Result := 'Low';
4: Result := 'Critical';
8: Result := 'Charged';
128: Result := 'No battery in system';
255: Result := 'Unknown battery state';
end;
end;
begin
try
Param := '';
if ParamCount = 0 then
begin
Writeln('No Parameter'#10#13);
ShowHelp;
end else
begin
Param := Uppercase(ParamStr(1));
GetSystemPowerStatus(PowerState);
if Param = 'ACSTATE' then
Write(BatteryStateACPower(PowerState.ACLineStatus))
else
if Param = 'LEFTPERCENT' then Write(BatteryStatePercent(PowerState.BatteryLifePercent))
else
if Param = 'STATEFLAG' then Write(BatteryStateFlags(PowerState.BatteryFlag))
else
begin
Writeln('Invalid Parameter'#10#13);
ShowHelp;
end;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
But still, after compiling the exe file takes up over 230 kb. Is this the final size, or might it be possible to reduce its size?
Upvotes: 0
Views: 1994
Reputation: 598029
If you don't want to use the Winapi.Windows
unit, you will just have to declare the function in your own code. See Importing Functions from Libraries in Delphi's documentation.
For example:
type
SYSTEM_POWER_STATUS = record
ACLineStatus: Byte;
BatteryFlag: Byte;
BatteryLifePercent: Byte;
SystemStatusFlag: Byte;
BatteryLifeTime: UInt32;
BatteryFullLifeTime: UInt32;
end;
function GetSystemPowerStatus(var lpSystemPowerStatus: SYSTEM_POWER_STATUS): LongBool; stdcall; external 'Kernel32';
This is similar (but different) to how the Winapi.Windows
unit declares the function. The main differences being:
interface
and implementation
sections of the unitunit Winapi.Windows;
...
interface
...
type
PSystemPowerStatus = ^TSystemPowerStatus;
_SYSTEM_POWER_STATUS = record
ACLineStatus : Byte;
BatteryFlag : Byte;
BatteryLifePercent : Byte;
Reserved1 : Byte;
BatteryLifeTime : DWORD;
BatteryFullLifeTime : DWORD;
end;
{$EXTERNALSYM _SYSTEM_POWER_STATUS}
TSystemPowerStatus = _SYSTEM_POWER_STATUS;
SYSTEM_POWER_STATUS = _SYSTEM_POWER_STATUS;
{$EXTERNALSYM SYSTEM_POWER_STATUS}
function GetSystemPowerStatus(var lpSystemPowerStatus: TSystemPowerStatus): BOOL; stdcall;
{$EXTERNALSYM GetSystemPowerStatus}
...
const
...
kernel32 = 'kernel32.dll';
...
...
implementation
...
function GetSystemPowerStatus; external kernel32 name 'GetSystemPowerStatus';
...
end.
Upvotes: 2