tags:

views:

397

answers:

3

Hi. How to detect (from Delphi) when the laptop is running on batteries (or AC)?

+2  A: 

There's a WINAPI function that I believe does this, GetSystemPowerStatus, which I believe you can execute from Delphi.

mrduclaw
+12  A: 

To be notified when the status changes on Vista and Windows 7 you can use RegisterPowerSettingNotification.

For Windows 2000 and later, look at GetSystemPowerStatus, or go to MSDN and read about Power Management.

(Someone always posts while I am typing :-( )

function GetBattery : Boolean;
var
  SysPowerStatus: TSystemPowerStatus;
begin
  Win32Check(GetSystemPowerStatus(SysPowerStatus));
  case SysPowerStatus.ACLineStatus of
    0: Result := False;
    1: begin
      Result := True;
      // You can return life with
      // String := Format('Battery power left: %u percent.', SysPowerStatus.BatteryLifePercent]);
    end;
    else
      raise Exception.Create('Unknown battery status');
  end;
end;
Reallyethical
@Reallyethical: Yep, that's the nature of SO. That's even harder when your native english isn't english (my case). You just have to get used to it :-). I remember a discussion in meta http://meta.stackoverflow.com/questions/73/is-the-fastest-gun-in-the-west-solved/93#93 to avoid being so "desperate" in posting something fast.
GmonC
Just tested that code on Windows 7 and it WORKS!! that was a supprise.
Reallyethical
@GmonC your right I should calm down, but to be frank I am getting used to the speed of this site. It almost seems pointless in posting as others have the same idea as I do.
Reallyethical
Are you trying to code in Brainf*ck's syntax? Why not just Result := not Boolean(SysPowerStatus.ACLineStatus). You test a condition for True then return False... O_o
Fabio Gomes
As the entire point is it can be switched to a procedure or function can change to return str etc within a few tiny changes. its an example not a full solution!!
Reallyethical
ACLineStatus is documented to have **three** possible values, so don't type-cast it to Boolean. Just check for the values 0 and 1, and let everything else be an error. Also, please check the return value of GetSystemPowerStatus. I've edited the answer accordingly.
Rob Kennedy
It works on WinXP - Tested and confirmed. Thanks Reallyethical. (please add more confirmations if you have test it on a different OS).
Altar
+1  A: 

Here part of code that detect when laptop is running on batteries (if not it triggers some event):

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  WTSSessionNotification, StdCtrls, MediaPlayer, Buttons, ShellAPI, Settings,
  ExtCtrls;

const
  WM_ICONTRAY = WM_USER + 1;

type
  TSettingsForm = class(TForm)
    OpenDialog: TOpenDialog;
    pnl1: TPanel;
    InfoLabel: TLabel;
    grp1: TGroupBox;
    AlarmSoundLabel: TLabel;
    lbl1: TLabel;
    checkIfLocked: TCheckBox;
    Filename: TEdit;
    Browse: TBitBtn;
    TestSound: TBitBtn;
    btn1: TBitBtn;
    lbl2: TLabel;
    procedure Minimize(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure TestSoundClick(Sender: TObject);
    procedure BrowseClick(Sender: TObject);
    procedure checkIfLockedClick(Sender: TObject);
    procedure OpenHomepage(Sender: TObject);
    procedure btn1Click(Sender: TObject);
  private
    TrayIconData: TNotifyIconData;
    procedure CheckForAC;
  protected
    procedure WndProc(var Message: TMessage); override;
  public
    { Public declarations }
  Function SecuredLockWorkStation : Boolean ;
  end;

var
  SettingsForm: TSettingsForm;

implementation

{$R *.DFM}
{$R WindowsXP.RES}

var
   MPlayer: TMPlayer;
   mySettings: TSettings;
   isLocked: boolean = false;

// true if A/C is connected, false if not
function ACConnected: boolean;
var PowerStatus: TSystemPowerStatus;
begin
 GetSystemPowerStatus(PowerStatus);
 result := (PowerStatus.ACLineStatus = 1);
end;

// handles application.minimize; do not really
// minimize, but hide settings window
procedure TSettingsForm.Minimize(Sender: TObject);
begin
 Application.Restore;
 self.Hide;
end;

// processes window messages (notification about
// power status changes, locking of workstation and
// tray icon activity)
procedure TSettingsForm.WndProc(var Message: TMessage);
begin
  case Message.Msg of
    WM_WTSSESSION_CHANGE:
      begin
        if Message.wParam = WTS_SESSION_LOCK then
         isLocked := true;
        if Message.wParam = WTS_SESSION_UNLOCK then
        begin
         isLocked := false;
         if MPlayer.isPlaying then
          MPlayer.Close;
        end;
      end;
    WM_POWERBROADCAST:
      begin
       if (isLocked) or (checkIfLocked.checked=false) then
        CheckForAC;
      end;
    WM_ICONTRAY:
      begin
         case Message.lParam of
          WM_LBUTTONDOWN:
            begin
              if SettingsForm.visible then
               SettingsForm.Hide
              else
               SettingsForm.Show;
            end;
          WM_RBUTTONUP:
            begin
              if SettingsForm.visible then
               SettingsForm.Hide
              else
               SettingsForm.Close;
            end;
         end;
      end;
  end;
  inherited;
end;
volvox