[RESOLVED] Loop to detect when battery power status changes?
I want to detect when the battery power status of a PC (ex.: a laptop) changes. I am using GetSystemPowerStatus API to get battery life percentage. What I want to do is to detect if the battery life percentage changes. The easy way to do this would be using a timer but that would lag my app. I was thinking about a 'recursive' loop.
It would go kind of like this:
Code:
Do Until batteryLifePercentageChanges
checkIfBatteryLifePercentageChanges
Loop
and then return the new battery life percentage.
Here is the code to find the battery power percentage:
Code:
Private Declare Function GetSystemPowerStatus Lib "kernel32" (lpSystemPowerStatus As _
SYSTEM_POWER_STATUS) As Long
Private Type SYSTEM_POWER_STATUS
ACLineStatus As Byte
BatteryFlag As Byte
BatteryLifePercent As Byte
Reserved1 As Byte
BatteryLifeTime As Long
BatteryFullLifeTime As Long
End Type
Private Sub Command1_Click()
Dim MyStatus As SYSTEM_POWER_STATUS
Dim MyLifeTime As Double
GetSystemPowerStatus MyStatus
MyLifeTime = MyStatus.BatteryLifeTime
If MyLifeTime = -1 Then
MsgBox "Using AC Power"
Else
MsgBox "I have " & MyLifeTime / 3600 & " hours remaining on battery."
End If
End Sub
I am not really good with loops. They can really confuse me sometimes. For example I remember once that when I was working with loops a lot, I asked myself "How does a loop know when to begin?" and stupid stuffs like that. LoL
Any help would be appreciated. Thank you
Last edited by kevinKZzaka; Aug 6th, 2013 at 07:14 PM.
Re: Loop to detect when battery power status changes?
Originally Posted by dilettante
VB6 comes with a SysInfo control that raises simple events on power status changes.
I know about SysInfo but I don't want to use that because I want my app to be a standalone without the need of the sysinfo.ocx . For example, in Windows 7 there is no sysinfo.ocx and I need to download it and put it in the system32 dir.
Re: Loop to detect when battery power status changes?
Here is an OLD project I have from when I started programming with VB6 couple year ago.
Do what you need with this... it is a bit slow maybe but I haven't changed anything, you might be able to make it faster I don't know.
I don't have time to play with it right now.
Re: Loop to detect when battery power status changes?
Originally Posted by Max187Boucher
Here is an OLD project I have from when I started programming with VB6 couple year ago.
Do what you need with this... it is a bit slow maybe but I haven't changed anything, you might be able to make it faster I don't know.
I don't have time to play with it right now.
Thank you so much for your help but as I said, I didn't want to use a timer. I wanted to do this without a timer and possibly using a loop. I just want a warkwaround of the timer version, but without using the timer control.
Re: Loop to detect when battery power status changes?
Sorry did not read properly (or maybe too fast)
Remove the timer from my project and replace all the code in the form by this one
Code:
Private Declare Function GetSystemPowerStatus Lib "kernel32" (lpSystemPowerStatus As SYSTEM_POWER_STATUS) As Long
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Private Type SYSTEM_POWER_STATUS
ACLineStatus As Byte
BatteryFlag As Byte
BatteryLifePercent As Byte
Reserved1 As Byte
BatteryLifeTime As Long
BatteryFullLifeTime As Long
End Type
Private QuitForm As Boolean
Private Sub Form_Load()
Me.Show
Battery_FakeTimer
End Sub
Private Sub Battery_FakeTimer()
Do While QuitForm = False
DoEvents
Sleep 1
Call Update_Battery_Info
Sleep 1
DoEvents
Loop
End Sub
Private Sub Update_Battery_Info()
lbl_BatteryLife.Caption = BatteryLife
Battery_PBar BatteryLife ' Additional Sub for battery life (progressbar)
End Sub
Private Sub Battery_PBar(strBatteryInfo As String) 'Additional not needed!
Static Enable_Timer As Boolean
If strBatteryInfo = "Plugged" Then
ProgressBar1.Value = 100
Exit Sub
End If
If Left(strBatteryInfo, 3) = "100" Then
ProgressBar1.Value = 100
Else
ProgressBar1.Value = Left(strBatteryInfo, 2)
End If
If Enable_Timer = True Then
Exit Sub
Else
Enable_Timer = True
End If
End Sub
Private Function BatteryLife() As String
Dim BatteryTime As String
Dim BatteryStatus As SYSTEM_POWER_STATUS
GetSystemPowerStatus BatteryStatus
If BatteryStatus.ACLineStatus = 1 Then
BatteryLife = "Plugged"
Else
BatteryTime = Format((BatteryStatus.BatteryLifeTime / 60) / 60, "0.00")
BatteryLife = BatteryStatus.BatteryLifePercent & "% - " & Left(BatteryTime, 1) & "h" & Format(Right(BatteryTime, 3) * 60, "00") & "m"
End If
End Function
Private Sub Form_Unload(Cancel As Integer)
QuitForm = True
End Sub
Again... this is just some fast code, please take a good look and modify it to your needs.
Re: Loop to detect when battery power status changes?
No problem, I hope you saw that I (quickly) edited my post, it was not exiting the program properly so I added a boolean QuitForm (in the unload event)... just to let you know.
It did seem to work good so far, the Sleep Api keeps the CPU usage stay low (0 - 2%).. with the Doevents only it was at 50%.
Re: Loop to detect when battery power status changes?
I would strongly recommend a timer rather than a loop and I would say that the interval should be set no lower than 200. What you have there is going to be testing up to 500 times a second and there is no way it needs to happen that often. No doubt if a timer doing this would cause your program to lag [doubtful] this would cause it to lag much worse and would also drain the battery faster due to the fact that it would be making this call 500 times a second when your program is idle.
Re: Loop to detect when battery power status changes?
Ya I would use a timer too.. but OP wanted to know if possible without a timer.
You could use an API Timer, so you would not have to add a timer to the form...
The thing is it works (the loop) good now, but what if the program becomes very big with lots of loops?
I would also recommend using timer or API Timer.
I was just trying to show him that is is POSSIBLE, but might not be the best way of course.
Re: Loop to detect when battery power status changes?
Originally Posted by Max187Boucher
No problem, I hope you saw that I (quickly) edited my post, it was not exiting the program properly so I added a boolean QuitForm (in the unload event)... just to let you know.
It did seem to work good so far, the Sleep Api keeps the CPU usage stay low (0 - 2%).. with the Doevents only it was at 50%.
I did see that. I implemented the code in my project and there was a problem with the form. It wouldn't complete the other actions in the form_load event. I tried to workwaround it but nothing. I think I'm going to follow DataMiser's advice and use a timer because I used your method with three other tasks and now it is full of do...loops and just sucks. But as you said I wanted to know that it was possible. I will keep it in mind for another time. Thank you both
Re: Loop to detect when battery power status changes?
Originally Posted by kevinKZzaka
I want to detect when the battery power status of a PC (ex.: a laptop) changes. I am using GetSystemPowerStatus API to get battery life percentage. What I want to do is to detect if the battery life percentage changes. The easy way to do this would be using a timer ...
You may want to consider doing it the "proper way". From System Power Status:
Originally Posted by MSDN
Power information is retrieved by registering for power setting notifications through the RegisterPowerSettingNotification function. This function allows applications to register for specific power settings and be notified when they change.
Windows Server 2003 and Windows XP: Power status information is retrieved by using the GetSystemPowerStatus function, which copies information about the power supply and battery status to a SYSTEM_POWER_STATUS structure. This structure indicates whether the system has a battery, and if it does, whether the battery is being used, and what percentage of the charge remains. The system broadcasts the PBT_APMPOWERSTATUSCHANGE event to all applications when the power status changes. When your application receives this event, it should call GetSystemPowerStatus again to determine what changed.
Note that the proper way involves subclassing.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
→ The Comprehensive Guide to Cloud Computing
A complete overview of Cloud Computing focused on what you need to know, from selecting a platform to choosing a cloud vendor.