2013-07-27 48 views
0

我有以下代码:事件处理程序“错误”使用VB.NET与窗口形成

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) 

    Const WM_SYSCOMMAND As Integer = &H112 
    Const SC_SCREENSAVE As Integer = &HF140 

    MyBase.WndProc(m) 
    If bloqueado = 0 Then 
     If m.Msg = WM_SYSCOMMAND AndAlso m.WParam.ToInt32 = SC_SCREENSAVE Then 
      Timer2.Start() 
      inicio = Now 
      pausa = pausa + 1 
      AddHandler Application.Idle, AddressOf Application_Idle 
     End If 
    End If 
End Sub 

Private Sub Application_Idle(ByVal sender As Object, ByVal e As EventArgs) 
    Dim newitem As ListViewItem 
    Dim diferença As TimeSpan 

    'MsgBox(Now.ToString)' 
    Debug.Print(Now.ToString) 
    fim = Now 
    diferença = fim - inicio 
    Timer2.Stop() 
    newitem = New ListViewItem 
    newitem.Text = pausa 
    newitem.SubItems.Add(inicio.ToLongTimeString) 
    newitem.SubItems.Add(fim.ToLongTimeString) 
    newitem.SubItems.Add(diferença.ToString.Substring(0, 8)) 
    ListView1.Items.Add(newitem) 
    parcial = parcial & pausa & vbTab & vbTab & inicio.ToLongTimeString & vbTab & vbTab & fim.ToLongTimeString _ 
     & vbTab & vbTab & diferença.ToString.Substring(0, 8) & vbTab & vbTab & " screensaver" & System.Environment.NewLine 
    RemoveHandler Application.Idle, AddressOf Application_Idle 
End Sub 

基本上,当屏幕保护程序激活,并创建一个application.idle事件处理程序和第二部分的第一部分检测,当活动检测到一堆代码正在运行并且处理程序被删除。

这是除了一个点的所有工作正常:

正如你可以看到我有INICIO =现在,当屏幕变得活跃和FIM =现在检测到活动时(当屏幕保护程序变为无效),所以我应该有2个不同的时间,但如果我有它像我贴2日期时间将是相同的。如果你注意到我有一个msgbox显示现在(当屏幕保护程序停止)评论,如果我把它从评论2日期时间将是differente和正确的(我用天文台确保结果)

现在我的问题: 为什么它需要更新now的消息框,为什么它不工作debug.print?

有没有办法解决这个问题/更新now变种,而无需使用一个消息框的方式(我不希望对应用有弹出消息)

,如果我真的要使用为此,msgbox是否有办法让它不发送弹出窗口或自动点击OK,以便立即消失?

编辑:

我一直在寻找,我发现这个代码:

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long 
    Public Function IsSNRunning() As Boolean 
     IsSNRunning = (FindWindow("WindowsScreenSaverClass", vbNullString) <> 0) 
    End Function 

    Private Sub Timer3_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer3.Tick 
     If IsSNRunning() Then 
      'Screen Saver Is Running 
     Else 
      Timer3.Stop() 
      code 
     End If 
End Sub 

我在捕获屏幕保护程序的开始部分时使用Timer3.Start(),我的想法是,如果我开始计时当我知道屏幕保护程序如果打开,那么当我得到IsSNRunning为false是当屏幕保护程序停止运行,但它不工作,任何想法为什么?

+0

* FIM =检测到活动现在当*如何'Application.Idle'活动的警惕吗? *为什么它需要现在更新的消息框,为什么它不能工作呢debug.print?*假设消息框直接运行(Application.Idle是一个非常普遍的事情),但阻止代码继续直到您移动鼠标,清除屏幕保护程序并看到消息框。当你关闭消息框时,'Debug.Print'代码以当前时间运行。 –

+0

application_idle是与活动相关的事件 – Newbie

+0

它与应用程序有关将变为“空闲”,因此没有活动......使您的事件处理程序发出嘟嘟声而不是显示消息框。 –

回答

0

首先,我要感谢你们的帮助,像你说的application.idle不工作,你帮我得到这个解决方案,我VB:由于计时器只开始运行

Imports System 
Imports Microsoft.Win32 
Imports System.Windows.Forms 
Imports System.Runtime.InteropServices 

<DllImport("user32.dll", CharSet:=CharSet.Auto)> Public Shared Function SystemParametersInfo(uAction As UInteger, _ 
    uParam As UInteger, ByRef lpvParam As Boolean, fWinIni As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 
' Check if the screensaver is busy running.' 
Public Shared Function IsScreensaverRunning() As Boolean 
    Const SPI_GETSCREENSAVERRUNNING As Integer = 114 
    Dim isRunning As Boolean = False 

    If Not SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, isRunning, 0) Then 
     ' Could not detect screen saver status...' 
     Return False 
    End If 

    If isRunning Then 
     ' Screen saver is ON.' 
     Return True 
    End If 

    ' Screen saver is OFF.' 
    Return False 
End Function 


Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) 

    Const WM_SYSCOMMAND As Integer = &H112 
    Const SC_SCREENSAVE As Integer = &HF140 

    MyBase.WndProc(m) 
    If bloqueado = 0 Then 
     If m.Msg = WM_SYSCOMMAND AndAlso m.WParam.ToInt32 = SC_SCREENSAVE Then 
      Timer2.Start() 
      Timer3.Enabled = True 
      Timer3.Start() 
      'here we that that the screensaver started running so we start a timer' 
     End If 
    End If 
End Sub 

Private Sub Timer3_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer3.Tick 

    If IsScreensaverRunning() Then 
     'Screen Saver Is Running' 
    Else 
     Timer3.Stop() 
     Timer3.Enabled = False 
     'Screen Saver Is not Running' 
    End If 

End Sub 

当屏幕保护程序运行我们知道,当你得到timer3.stop是当屏幕保护程序停止运行

重要的是,不要把msgbox之前的计时器停止,因为它不会工作,弹出窗口会显示,它不会到达停止这么无数的弹出窗口会出现(是啊...我犯了那个错误:S)

再次,感谢帮助我,并希望这将帮助别人的未来

1

对Application.Idle做任何事情都是一个失败的原因。屏幕保护程序激活后,您的应用程序不仅会立即空闲,还会在运行时永远停止空闲。屏幕保护程序将活动桌面切换到专用安全桌面,所有正在运行的程序都不会得到任何输入,直到它停用。

您可以观察桌面切换,SystemEvents.SessionSwitch事件触发。

请注意,这样的代码在实际应用上相当缺乏实用性。好奇心好,但总是有很多东西需要学习。屏幕保护程序应该位于列表的底部。