Screensaver Interaction

dpatfield66

Well-known member
Joined
Apr 6, 2006
Messages
136
Programming Experience
5-10
Can anyone tell me how .NET would interact with a screensaver that kicks in, or how it would know that a screensaver was kicking in?
 
One way to do this is to create a class that implements the imessageFilter. Example below...

VB.NET:
Public Class ScreenSaverListener
Implements IMessageFilter
 
    Private Const WM_SYSCOMMAND As Int32 = &H112
    Private Const SC_SCREENSAVE As Int32 = &HF140
 
    Public Event ScreensaverStarted(ByVal sender As Object, ByVal e EventArgs)
 
 Private Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
        If m.Msg = WM_SYSCOMMAND AndAlso m.WParam.ToInt32() = SC_SCREENSAVE Then
            RaiseEvent ScreensaverStarted(Me, New 'Create your own event args here')
            Return True
        End If
    End Function
End Class
 
Screensaver reply

Forgive my ignorance, but could explain this in (I'm a dummy) terms?
I'm slowly learning classes and object oriented programming.

Will I be able to use this to create an event call when the Screensaver kicks in? And how (once again, from an I'm a dummy perspective)?
 
Actually, I should have said I was new to event args.

I see the constants, and most of your code.
But I'm not sure how I would implement my event arg, for example.

Would I call a function/sub that I want to run from here?

Or could I simplify this to be:

When Screensaver kicks in, call blah-blah??
 
The event args aren't necessary if you are not planning to send any additional information to the class that catches the event. I just put it in there beacuse it may be usful to put the message into a new eventargs object. But first you need to create a new eventargs object.

VB.NET:
Public Class ScreenSaverListenerEventArgs
Inherits EventArgs
 
public Sub new(byref Msg as Message)
_Message = msg
End Sub
 
Private _Message as message
 
Public ReadOnly Property MyMessage as Message
Get
Return me._message
End Get 
End Property
 
End Class
So what we've done here is created a new event args object that can hold our message, that we want to pass to the event catcher.

VB.NET:
Public Event ScreensaverStarted(ByVal sender As Object, ByVal e ScreenSaverListenerEventArgs)
 
Private Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
        If m.Msg = WM_SYSCOMMAND AndAlso m.WParam.ToInt32() = SC_SCREENSAVE Then
 
'Pass the message that activated the screen saver to our new event args object)
            RaiseEvent ScreensaverStarted(Me, New ScreenSaverListenerEventArgs(m))
            Return True
        End If
    End Function
Then to use this you would declare in your class a new object of the listener class

VB.NET:
Public WithEvents MyListenerEventCatcher as new ScreenSaverListener


Then Open the event handler for this new object and do whatever processing you want to do. The message that raised the event will now be in the e parameter. Have i just confused things even more?
 
LOL...you have "kind-of" confused things for me, but I'm tryin'!!!

Is the <ScreenSaverListenerEventArgs> class the one that delivers a message? In other words, if the screensave kicks in, I get a pop-up from .NET that says..."Hey, screensaver just kicked in"

What do you mean by "Message?"

Is RaiseEvent ScreensaverStarted, something that I'm creating, or is it a default?

I'm trying to avoid adding unnessecary objects to my project. Where could I put these, or am I stuck having to create two classes?

will something have to go in each of my forms that the user is using? I have 3 forms that I need to use this with. Where is it going? And WHAT is going there? I see your listener code...does that go in a class. Listener.vb for example? Does the Public Event go in my forms?

Sorry to sound so ignorant, but Like I said, I'm new at where these things get implemented and how.

I learned in Java how to do classes, but it was the basic of basics.

Get & Set in the Employee Class for example., and the Sub Main, or whatever...I actually forget the syntax.
 
Ok, I've created 2 classes. Saver.vb and SaverListener.vb

Public Class ScreenSaverListenerEventArgs
Inherits EventArgs
Public Sub New(ByRef Msg As Message)
_Message = Msg
End Sub
Private _Message As Message
Public ReadOnly Property MyMessage() As Message
Get
Return Me._Message
End Get
End Property
End
Class
=========================================
Public Class ScreenSaverListener
Implements IMessageFilter
Private Const WM_SYSCOMMAND As Int32 = &H112
Private Const SC_SCREENSAVE As Int32 = &HF140
Public Event ScreensaverStarted(ByVal sender As Object, ByVal e EventArgs)
Private Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
If m.Msg = WM_SYSCOMMAND AndAlso m.WParam.ToInt32() = SC_SCREENSAVE Then
RaiseEvent ScreensaverStarted(Me, New 'Create your own event args here')
Return True
End If
End Function
End
Class
============================================

The Public Event is giving me problems - I'm getting an error message on my ByVal e EventArgs

And what do I put for 'Create your own event args here' ?

And where do I call this from...my 3 forms? Let's just take my Admit form first...where, or what do I code in this form that will use these 2 classes?

And lastly, is there some way to have these 2 classes integrated into one object, rather than have 2 class objects called this.vb and that.vb?

Kind of like I have all calculations in my modCalculation.vb module?
 
I think I answered one of my own questions, by putting both of these classes into one .vb object. There doesn't seem to be any errors generating by doing so. Except of course for the previous errors I mentioned.
 
Ok,let me try to explain this properly.

First you don't have to use a custom eventargs class, i just thought it would be handy to know what message raised the event.
As you correctly assumed this is the class that passes the message to the e parameter of our event.
VB.NET:
Public Class ScreenSaverListenerEventArgs
Inherits EventArgs
 
public Sub new(byref Msg as Message)
_Message = msg
End Sub
 
Private _Message as message
Public ReadOnly Property MyMessage as Message
Get
Return me._message
End Get 
End Property
End Class

Our event that uses our new custom eventargs class
VB.NET:
Public Event ScreensaverStarted(ByVal sender As Object, ByVal e ScreenSaverListenerEventArgs)

This part is our message filter object. It does exactly as it says, filters all the messages in
your applications message loop. We've got it checking for a message that tells us that the screen
saver is about to start. The If statement checks the message if the message meets our requirements
then our ScreenSaverStarted Event is raised and we pass in our new eventargs object. As below..
VB.NET:
Private Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
If m.Msg = WM_SYSCOMMAND AndAlso m.WParam.ToInt32() = SC_SCREENSAVE Then
RaiseEvent ScreensaverStarted(Me, New ScreenSaverListenerEventArgs(m))
Return True
End If
End Function



Then when you want to use this class to filter the messages and check for the screensaver starting
you declare this in a class using the withevent varaible..


VB.NET:
Public Class IWantToDetectIfTheScreenSaverStarted
Implements IDisposable
 
' Add The Message Filter To The Applications Message Loop In The Classes Constrcuctor
Public Sub New 
Application.AddMessageFilter(MyMessageFilter)
End Sub
 
'Remove It In The Dispose Method
Public Sub Dispose() Implements.....
Application.RemoveMessageFilter(MyMessageFilter)
End Sub
 
'Instantiate A Object Of The Class That Implements The Message Filter And Declare It WithEvents 
So It Can Catch The Event That We Raised In The PreFilterMessage Sub
 
 
Private WithEvents MyMessageFilter As New ScreenSaverListener
Then Click The Top Left Combo And Select MyMessageFilter, click the righthand combo And Click
ScreenSaverStarted. This will open up the event handler for the event we raised.

The reason you got an error here...

VB.NET:
Public Event ScreensaverStarted(ByVal sender As Object, ByVal e EventArgs)

Is because you havent used the new eventargs class. So it should be.....

VB.NET:
Public Event ScreensaverStarted(ByVal sender As Object, ByVal e ScreenSaverListenerEventArgs)

Using our new ScreenSaverEventArgs Class


Any Clearer?
 
What vis781 is talking about is best practices and industry (MS?) standards conformance/compliance.

You can define the event any way you like.

The simplest event declaration possible is EVENT MYEVENT, which you raise with code RAISEEVENT MYEVENT.

You don't have to pass any parameters with an event, one could argue that an event that doesn't provide any additional information should not give impression that is does so by specifying event parameters.

That aside, think OOP, when you create a good VB.Net class (myclass) all the developers using it may create many instances of it, and they can handle the event of all instances of myclass with one event handler. But even if all the event is saying is that it 'did happen', the developer may want to know which of the objects that raised the event, that is what the standard sender parameter if for. And instead of creating event signatures with loads of parameters when needed it is good OOP to create different kinds of arguments classes. So the event need only pass two parameters:
sender: the objects that raised it, and
e, the compounds of the arguments encapsuled in an eventarguments class.

You might see that the events of all .Net framework classes follow this standard, you might also find this page very interesting; Events in Visual Basic http://msdn2.microsoft.com/en-us/library/ms172877.aspx
 
ScreenSaver Event

Ok, I've just revisited all this after a short break.

Here's what I want to do.

We have a screensaver called "AutoLogOff". It does just that...logs the user off from an app called <PatientManager>.

If the user opened up a form, and the screensaver kicked in "before" they had a chance to "save the form," I want the program to save the form, and incidentally, the record that the user was working in.

I also want the <LastUpdateBy> variable to read the User's Name + "(AutoLogoff)" to indicate that the user didn't save the record, the program did as a result of the logoff.

In LAYMEN'S terms, or for Dummies (ME) can someone please explain EVERYTHING, step by step, that I need to do to assure this happens?

You can leave out the code for Save form, set LastUpdatedBy variable, Save form and Close form, just let me know where I place that code.

I'm pretty smart, but I'll tell ya, if you start using any froo-froo language, I'll get lost...just tell me what I need to type, what I need to create.

I know, that's alot to ask, but it's the best way for me to figure out what I'm doing. If you start saying, "Pass the this into that, and rectify the ramifier with this and that, and make sure the bliggity-blong is this and that, I'll get LOST...L-O-S-T! I know, I don't deserver to be a programmer, but hey...I'll take any help, please.
 
Back
Top