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 ClassHeippa 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 SubSuuren 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 SubAihe on jo aika vanha, joten et voi enää vastata siihen.