Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I wrote a simple screen saver app that cycles through all the pictures in a folder. I have 1 question and 2 bugs that I need help with.

 

Public bFirstMove As Boolean
Public Pics() As String
Public position As Int16

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) ;
Handles MyBase.Load

       Me.CenterToScreen()

       picBox.Height = Me.Height
       picBox.Width = Me.Width

       bFirstMove = True

       Pics = Directory.GetFiles("C:\Fractals")
       position = 0
       picBox.Image = Drawing.Bitmap.FromFile(Pics(position))

End Sub

Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) ;
Handles MyBase.KeyUp

       Me.Close()

End Sub

Private Sub picBox_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) ;
Handles picBox.MouseMove

       If Not bFirstMove Then
           Me.Close()
       Else
           bFirstMove = False
       End If

End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) ;
Handles Timer1.Tick

       position += 1
       If position = UBound(Pics) Then position = 0

       picBox.Image = Drawing.Bitmap.FromFile(Pics(position))

End Sub

 

1. How do I pass the capture of the mouse move to the underlying form? Since the pic box is sized to = the form I have to put the mouse move event in the picBox control. This probably does not matter but I am curious how it is done.

 

2. If I hit run (F5) from inside the .net developer, it always picks up a mouse move event and shuts down the program. That is the reason for the bFirstMove form global. Is there a way to flush the mouse move buffer?

 

3. I compiled this and tested it out and it works as a screen saver (changed .exe to .scr). After about a 1/2 hour of continuous running I get a "System out of Memory" fault that crashes the program. Do I need to set the picBox.image to nothing to flush memory or something?

 

 

Thanks

Brian

"Beer is proof that God loves us and wants us to be happy."

-Benjamin Franklin

  • *Experts*
Posted

1) Look at the [api]SetCapture[/api] API.

 

2) Not that I'm aware of (though I don't totally understand why you would need this... if you just ignore the event it will go away on its own).

 

3) Not sure why that is happening... Perhaps you should try loading all the images into an array of Image objects at load, and simply cycling through those, rather than continuously loading the images from the HDD.

 

 

Also, instead of

UBound(Pics)

you should use the .NET CLR way

Pics.GetUpperBound(0)

Posted

In short, the answers to your questions are:

1. As far as I know, you have to use something outside of the .NET framework to do so.

2. I do not believe there is a way to do this. Windows sends mouse messages whether you want them or not.

3. Use the Bitmap's Dispose method before it goes out of scope or is set to a new Bitmap.

 

 

At length, the answers to your questions are:

The following should give you something else to think about:

 

Remove the PictureBox

Set Form1.FormBorderStyle to None

Try this:

 

Private Pics() As String

Private position As Int16

Private bmpCurrent, bmpOld As Bitmap

 

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Me.CenterToScreen()

 

Pics = System.IO.Directory.GetFiles("C:\Fractals")

position = 0

 

bmpCurrent = Bitmap.FromFile(Pics(position))

End Sub

 

Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyUp

Me.Close()

End Sub

 

Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove

Static bCaughtMove As Boolean

 

If bCaughtMove Then

Me.Close()

Else

bCaughtMove = True

End If

End Sub

 

Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint

e.Graphics.DrawImage(bmpCurrent, 0, 0)

End Sub

 

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

position += 1

If position = Pics.GetUpperBound(0) Then position = 0

 

bmpOld = bmpCurrent

bmpCurrent = Bitmap.FromFile(Pics(position))

bmpOld.Dispose()

 

Me.Refresh()

End Sub

 

 

This is what I did:

 

I changed the global variables to Private instead of Public. Just a good habit.

 

1. I moved all of the Painting/Pictures directly to the form. No need to worry about mouse events on the PictureBox anymore.

 

2. Put the MouseChecking variable into the Mouse Event Handler. It's a bit cleaner that way. As far as I know there is no way to flush it.

 

3. Now the bitmap is drawn during the Form's Paint event. When updating the picture what I did was set bmpOld to whichever bitmap was currently being used. I then set bmpCurrent to the new pic about to be displayed. I then call Dispose on bmpOld. This is why you had a memory leak.

 

Any Class that implements the IDisposable Interface (quickest way to check is to just see if it has a Dispose Method) does not clean itself up automatically. You have to call the Dispose method to get it to clean up internal resources (in this case an HBITMAP Windows API Structure).

 

The reason I didn't simply call bmpCurrent.Dispose and then set it to the new one is because that might cause problems if the form's Paint event went off while it was loading the new one.

 

4. Sorry if I was a bit lengthy, but I like to espouse good coding practices whenever possible. The more people who code in a clean, structured (possibly Object Oriented) manner, the more code there will be around for others to see and understand.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...