Results 1 to 12 of 12

Thread: [RESOLVED] Loop to detect when battery power status changes?

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Feb 2013
    Location
    Albania
    Posts
    101

    Resolved [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.

  2. #2
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Loop to detect when battery power status changes?

    VB6 comes with a SysInfo control that raises simple events on power status changes.

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Feb 2013
    Location
    Albania
    Posts
    101

    Re: Loop to detect when battery power status changes?

    Quote Originally Posted by dilettante View Post
    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.

  4. #4
    PowerPoster
    Join Date
    Aug 2011
    Location
    B.C., Canada
    Posts
    2,887

    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.
    Attached Files Attached Files

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Feb 2013
    Location
    Albania
    Posts
    101

    Re: Loop to detect when battery power status changes?

    Quote Originally Posted by Max187Boucher View Post
    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.

  6. #6
    PowerPoster
    Join Date
    Aug 2011
    Location
    B.C., Canada
    Posts
    2,887

    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.

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Feb 2013
    Location
    Albania
    Posts
    101

    Re: Loop to detect when battery power status changes?

    Thank you soo much. It worked perfectly. Thanks again for helping me and finding the time.

  8. #8
    PowerPoster
    Join Date
    Aug 2011
    Location
    B.C., Canada
    Posts
    2,887

    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%.

  9. #9
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    14,205

    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.

  10. #10
    PowerPoster
    Join Date
    Aug 2011
    Location
    B.C., Canada
    Posts
    2,887

    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.

  11. #11

    Thread Starter
    Lively Member
    Join Date
    Feb 2013
    Location
    Albania
    Posts
    101

    Re: Loop to detect when battery power status changes?

    Quote Originally Posted by Max187Boucher View Post
    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

  12. #12
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: Loop to detect when battery power status changes?

    Quote Originally Posted by kevinKZzaka View Post
    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:

    Quote 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
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width