En tiedä miten yleinen ongelma tämä on, mutta jonkin verran googlettamalla löytyy vastaavasta kärsiviä. Vastusta vaan ei valitettavasti kukaan ole saanut.
Eli, kun ohjelmaan tekee PowerModeChanged -eventin, ei resume-eventti käynnisty koneen herätessä ennen kuin käyttäjä liikauttaa hiirtä tai painaa jotain nappia. Tämä lienee windowsin oma hienous tarkistaa onko käyttäjä oikeasti koneella vai heräsikö kone jostain syystä "turhaan".
Ongelma on se, että ohjelmani ei jatka normaalia toimintaa automaattisesti, tässä tapauksessa ei käynnistä musiikkisoitinta uudelleen koneen herätessä. Ajastimet juoksevat kyllä eli jonkinmoisen apinavirityksen voisi niiden avulla tehdä, mutta haluaisin selvittää onko tuohon mitään "oikeaa tapaa" korjata ongelma ja saada resume-eventti suoriutumaan AINA koneen herätessä ilman syötteitä.
Asiaa on puitu jonkun verran täällä:
http://www.codeproject.com/KB/system/OSEvents.
Kokeilinkin sieltä löytynyttä 'SetThreadExecutionState' API käskyä, mutta se ei tähän ongelmaan auttanut mitenkään.
Heippa sniiki!
kokeile viritellä näistä eväistä...
Imports System Imports System.IO Imports System.Reflection Imports System.Runtime.InteropServices Imports Microsoft.Win32.SafeHandles Public Partial Class MainForm Private Const PBT_APMQUERYSUSPEND As Integer = &H0 Private Const PBT_APMQUERYSTANDBY As Integer = &H1 Private Const PBT_APMQUERYSUSPENDFAILED As Integer = &H2 Private Const PBT_APMQUERYSTANDBYFAILED As Integer = &H3 Private Const PBT_APMSUSPEND As Integer = &H4 Private Const PBT_APMSTANDBY As Integer = &H5 Private Const PBT_APMRESUMECRITICAL As Integer = &H6 Private Const PBT_APMRESUMESUSPEND As Integer = &H7 Private Const PBT_APMRESUMESTANDBY As Integer = &H8 Private Const PBT_APMBATTERYLOW As Integer = &H9 Private Const PBT_APMPOWERSTATUSCHANGE As Integer = &Ha Private Const PBT_APMOEMEVENT As Integer = &Hb Private Const PBT_APMRESUMEAUTOMATIC As Integer = &H12 <StructLayout(LayoutKind.Sequential)> _ Public Class SYSTEM_POWER_STATUS Public ACLineStatus As Byte Public BatteryFlag As Byte Public BatteryLifePercent As Byte Public Reserved1 As Byte Public BatteryLifetime As Int32 Public BatteryFullLifetime As Int32 End Class Public Enum ACLineStatus As Byte Battery = 0 AC = 1 Unknown = 255 End Enum <FlagsAttribute> _ Public Enum BatteryFlag As Byte High = 1 Low = 2 Critical = 4 Charging = 8 NoSystemBattery = 128 Unknown = 255 End Enum <DllImport("Kernel32.DLL", CharSet := CharSet.Auto, SetLastError := True)> _ Private Shared Function GetSystemPowerStatus( _ SystemPowerStatus As SYSTEM_POWER_STATUS) As Boolean End Function <DllImport("Kernel32.DLL", CharSet := CharSet.Auto, SetLastError := True)> _ Private Shared Function GetDevicePowerState( _ hDevice As SafeFileHandle, ByRef fOn As Boolean) As Boolean End Function Public Sub New() Me.InitializeComponent() End Sub Sub MainFormLoad(sender As Object, e As EventArgs) Timer1.Interval = 250 Timer1.Enabled = True End Sub Sub Timer1Tick(sender As Object, e As EventArgs) label1.Text = ReportDiskStatus End Sub Protected Function ReportDiskStatus() As String Timer1.Enabled = False Dim status As String = String.Empty Dim fOn As Boolean = False Dim assembly__1 As Assembly = Assembly.GetExecutingAssembly() Dim files As FileStream() = assembly__1.GetFiles() If files.Length > 0 Then Dim hFile As SafeFileHandle = files(0).SafeFileHandle Dim result As Boolean = GetDevicePowerState(hFile, fOn) If result Then If fOn Then status = "Disk is powered up and spinning" Else status = "Disk is sleeping" End If Else status = "Cannot get Disk Status" End If End If Return status Timer1.Enabled = True End Function End Class
Heippa sniiki!
VB4/5/6 versio...
Dim exit_proc As Boolean Private Declare Sub Sleep Lib "kernel32" _ (ByVal dwMilliseconds As Long) Private Declare Function CreateFile Lib "kernel32.dll" _ Alias "CreateFileA" (ByVal lpFileName As String, _ ByVal dwDesiredAccess As Long, _ ByVal dwShareMode As Long, lpSecurityAttributes As Any, _ ByVal dwCreationDisposition As Long, _ ByVal dwFlagsAndAttributes As Long, _ ByVal hTemplateFile As Long) As Long Private Declare Function GetDevicePowerState Lib "kernel32.dll" _ (ByVal hDevice As Long, pfOn As Long) As Long Private Declare Function CloseHandle Lib "kernel32.dll" _ (ByVal hObject As Long) As Long Private Const GENERIC_READ = &H80000000 Private Const FILE_SHARE_READ = &H1 Private Const FILE_SHARE_WRITE = &H2 Private Const OPEN_EXISTING = 3 Option Explicit Private Sub Form_Load() exit_proc = False proc_mainloop End Sub Sub proc_mainloop() Do While Not exit_proc: DoEvents Sleep 250 Label1.Caption = ShowPowerStatus Loop End Sub Function ShowPowerStatus() As String Dim lHand As Long Dim lState As Long Dim lRet As Long Dim sDrive As String Dim status As String sDrive = "\\.\" & Environ("HOMEDRIVE") lHand = CreateFile(sDrive, GENERIC_READ, _ FILE_SHARE_READ Or FILE_SHARE_WRITE, _ ByVal vbNullString, OPEN_EXISTING, 0, 0) If lHand = -1 Then ShowPowerStatus = "Ei wörki!" Exit Function End If lRet = GetDevicePowerState(lHand, lState) CloseHandle lHand If lState = False Then status = "Offline" Else status = "Online" End If ShowPowerStatus = status End Function Private Sub Form_QueryUnload( _ Cancel As Integer, UnloadMode As Integer) exit_proc = True End Sub
Suuren suuret kiitokset Nea!
En tiedä miten olin missannut nuo msdn:n helpit jotka löysin noita antamiasi koodinpätkiä googlettamalla.
Tuo PBT_APMRESUMESUSPEND on se joka herää vasta kun "käyttäjä on paikalla" ja PBT_APMRESUMEAUTOMATIC näkyy heti kun kone herää, eikä siis vaadi hiiren liikuttelua/näppäinten painelua.
Private Const WM_POWERBROADCAST = &H218 Private Const PBT_APMQUERYSUSPEND As Integer = &H0 Private Const PBT_APMQUERYSTANDBY As Integer = &H1 Private Const PBT_APMQUERYSUSPENDFAILED As Integer = &H2 Private Const PBT_APMQUERYSTANDBYFAILED As Integer = &H3 Private Const PBT_APMSUSPEND As Integer = &H4 Private Const PBT_APMSTANDBY As Integer = &H5 Private Const PBT_APMRESUMECRITICAL As Integer = &H6 Private Const PBT_APMRESUMESUSPEND As Integer = &H7 Private Const PBT_APMRESUMESTANDBY As Integer = &H8 Private Const PBT_APMBATTERYLOW As Integer = &H9 Private Const PBT_APMPOWERSTATUSCHANGE As Integer = &HA Private Const PBT_APMOEMEVENT As Integer = &HB Private Const PBT_APMRESUMEAUTOMATIC As Integer = &H12 Protected Overrides Sub WndProc(ByRef m As Message) MyBase.WndProc(m) If m.Msg = WM_POWERBROADCAST Then Select Case m.WParam.ToInt32 Case PBT_APMQUERYSUSPEND TextBox1.Text &= "PBT_APMQUERYSUSPEND " & TimeOfDay & " " Case PBT_APMQUERYSTANDBY TextBox1.Text &= "PBT_APMQUERYSTANDBY " & TimeOfDay & " " Case PBT_APMQUERYSUSPENDFAILED TextBox1.Text &= "PBT_APMQUERYSUSPENDFAILED " & TimeOfDay & " " Case PBT_APMQUERYSTANDBYFAILED TextBox1.Text &= "PBT_APMQUERYSTANDBYFAILED " & TimeOfDay & " " Case PBT_APMSUSPEND TextBox1.Text &= "PBT_APMSUSPEND " & TimeOfDay & " " Case PBT_APMSTANDBY TextBox1.Text &= "PBT_APMSTANDBY " & TimeOfDay & " " Case PBT_APMRESUMECRITICAL TextBox1.Text &= "PBT_APMRESUMECRITICAL " & TimeOfDay & " " Case PBT_APMRESUMESUSPEND TextBox1.Text &= "PBT_APMRESUMESUSPEND " & TimeOfDay & " " Case PBT_APMRESUMESTANDBY TextBox1.Text &= "PBT_APMRESUMESTANDBY " & TimeOfDay & " " Case PBT_APMBATTERYLOW TextBox1.Text &= "PBT_APMBATTERYLOW " & TimeOfDay & " " Case PBT_APMPOWERSTATUSCHANGE TextBox1.Text &= "PBT_APMPOWERSTATUSCHANGE " & TimeOfDay & " " Case PBT_APMOEMEVENT TextBox1.Text &= "PBT_APMOEMEVENT " & TimeOfDay & " " Case PBT_APMRESUMEAUTOMATIC TextBox1.Text &= "PBT_APMRESUMEAUTOMATIC " & TimeOfDay & " " Case Else TextBox1.Text &= "jotain ihan muuta " & TimeOfDay & " " End Select End If End Sub
Aihe on jo aika vanha, joten et voi enää vastata siihen.