0

私は次のコードを持っています:

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 イベント ハンドラーを作成し、2 番目の部分はアクティビティが検出されたときに一連のコードを実行してハンドラーを削除します。

1 つの点を除いて、すべて正常に動作します。

ご覧のとおり、スクリーンセーバーがアクティブになったときは inicio = now であり、アクティビティが検出されたとき (スクリーンセーバーが非アクティブになったとき) は fim = now です。同じ。コメントに現在 (スクリーンセーバーが停止したとき) を表示する msgbox があることに気付いた場合は、コメントを外すと、2 つの日時が異なり、正確になります (結果を確認するためにクロノメーターを使用しました)。

ここで私の質問: なぜメッセージ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 として取得すると、スクリーンセーバーの実行が停止したときですが、機能しません。 、理由はありますか?

4

2 に答える 2

1

Application.Idle で何かをすることは、失われた原因です。スクリーン セーバーがアクティブになった直後にアプリがアイドル状態になるだけでなく、実行中にアイドル状態が停止することもありません。スクリーン セーバーは、アクティブなデスクトップを専用の安全なデスクトップに切り替えます。非アクティブ化するまで、実行中のプログラムは入力を取得しません。

デスクトップの切り替え、SystemEvents.SessionSwitch イベントの発生を確認できます。

このようなコードの実際的な有用性がかなり欠如していることに注意してください。好奇心は大丈夫ですが、学ぶべきことは常にたくさんあります。スクリーン セーバーはリストの一番下にあるはずです。

于 2013-07-27T10:51:21.103 に答える