我正在制作一个应用程序,当系统空闲时,即当用户没有与系统交互时,我正在实现自动监视器关闭。
我找到了一个链接:http://www.codeproject.com/KB/system/SystemIdleTimerComponent.aspx
它确实提供了解系统何时空闲的组件。但是当我包括:
Public WM_SYSCOMMAND As Integer = &H112
Public SC_MONITORPOWER As Integer = &Hf170
<DllImport("user32.dll")> _
Private Shared Function SendMessage(hWnd As Integer, hMsg As Integer, wParam As Integer, lParam As Integer) As Integer
End Function
Private Sub button1_Click(sender As Object, e As System.EventArgs)
SendMessage(Me.Handle.ToInt32(), WM_SYSCOMMAND, SC_MONITORPOWER, 2)
End Sub
它显示以下错误:跨线程操作无效:控制从其创建的线程以外的线程访问的“Form1”。
答案 0 :(得分:3)
它显示此错误:跨线程操作无效:控制从其创建的线程以外的线程访问的“Form1”。
不要从另一个线程访问Form1。阅读Invoke模式。
答案 1 :(得分:2)
我通过使用计时器每500毫秒检索一次,使LastInputInfo在我的应用程序中工作, 代码如下所示:
Private ATimer As DispatcherTimer
Public Sub New()
....
ATimer = New DispatcherTimer
AddHandler ATimer.Tick, AddressOf Me.ATimer_Tick
ATimer.Interval = TimeSpan.FromMilliseconds(500) 'Checks for idle every 500ms
ATimer.Start()
End Sub
Public Structure LASTINPUTINFO
Public cbSize As Integer
Public dwTime As Integer
End Structure
Private Declare Function GetTickCount Lib "kernel32" () As Long
Public Declare Function GetLastInputInfo Lib "User32.dll" _
(ByRef lii As LASTINPUTINFO) As Boolean
Private Sub ATimer_Tick(ByVal sender As Object, ByVal e As EventArgs)
MyLastInputInfo = New LASTINPUTINFO
MyLastInputInfo.cbSize = Runtime.InteropServices.Marshal.SizeOf(MyLastInputInfo)
' get last input info from Windows
If GetLastInputInfo(MyLastInputInfo) Then ' if we have an input info
' compute idle time
Dim sysIdleTime_ms As Integer = (GetTickCount() - MyLastInputInfo.dwTime)
End if
... Now you have the idle time in ms, do whatever you want with it :=)
这种做事方式的限制是,由于时间存储在32位整数内的刻度中,因此它“仅”在上次重新启动计算机后工作50天(...)。 我的猜测是,当TickCount包装时,TickCount和dwTime都将换行,因此没有问题,但无法测试。
答案 2 :(得分:0)
您可以尝试使用GetLastInputInfo()进行监控吗? http://msdn.microsoft.com/en-us/library/ms646302.aspx
答案 3 :(得分:0)
试
CheckForIllegalCrossThreadCalls = False
它通常适用于我使用其他线程的控件,即使它不是最有效的正确方式,但它确实帮助你,直到你找到一个替代