Bubble Screen Saver






3.46/5 (10 votes)
This project shows user how to create a screen saver Bubbles (Windows 7) in VB.NET.
Introduction
Many users have questions about creating screensavers for their projects. And many users wish to create splash screens which are shaped the same as a transparent PNG, GIF, etc. This project is a Bubbles screensaver in Windows 7. Users can also use this code to make transparent forms.
Background
Earlier, I had tried to create a Super Bar like the Windows 7 Super Bar. That's when I got the code to make a form transparent. Then, I decided to create this amazing screensaver using that code.
Using the Code
First, I will talk about creating a transparent from. I have used the PerPixelFrom
library from Sbar
on CodePlex to create a transparent form.
PerPixelAlphaForm.vb
Imports System.Windows.Forms
Imports system.Runtime.InteropServices
Imports Screen_Saver.Win32
Public Class PerPixelAlphaForm
Inherits Form
Public StartLeft As Integer
Public StartTop As Integer
Public Ang As Double
Public WithEvents tim As New Timer
' Methods
Public Sub New()
MyBase.FormBorderStyle = Windows.Forms.FormBorderStyle.None
MyBase.ShowInTaskbar = False
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
MyBase.Dispose(disposing)
GC.Collect()
GC.WaitForPendingFinalizers()
End Sub
Public Sub SetBitmap(ByVal bitmap As Bitmap)
Me.SetBitmap(bitmap, &HFF)
GC.Collect()
GC.WaitForPendingFinalizers()
End Sub
Public Sub SetBitmap(ByVal bitmap As Bitmap, ByVal opacity As Byte)
If (bitmap.PixelFormat <> Imaging.PixelFormat.Format32bppArgb) Then
Throw New ApplicationException("The bitmap must be 32ppp with alpha-channel.")
End If
Dim screenDc As IntPtr = Win32.GetDC(IntPtr.Zero)
Dim memDc As IntPtr = Win32.CreateCompatibleDC(screenDc)
Dim hBitmap As IntPtr = IntPtr.Zero
Dim oldBitmap As IntPtr = IntPtr.Zero
Try
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0))
oldBitmap = Win32.SelectObject(memDc, hBitmap)
Dim size As New Size(bitmap.Width, bitmap.Height)
Dim pointSource As New Point(0, 0)
Dim topPos As New Point(MyBase.Left, MyBase.Top)
Dim blend As New BLENDFUNCTION
blend.BlendOp = 0
blend.BlendFlags = 0
blend.SourceConstantAlpha = opacity
blend.AlphaFormat = 1
Win32.UpdateLayeredWindow(MyBase.Handle, screenDc, (topPos), _
(size), memDc, (pointSource), 0, (blend), 2)
Finally
Win32.ReleaseDC(IntPtr.Zero, screenDc)
If (hBitmap <> IntPtr.Zero) Then
Win32.SelectObject(memDc, oldBitmap)
Win32.DeleteObject(hBitmap)
End If
Win32.DeleteDC(memDc)
Win32.DeleteDC(screenDc)
Win32.DeleteObject(oldBitmap)
Win32.DeleteObject(screenDc)
Win32.DeleteObject(memDc)
GC.Collect()
GC.WaitForPendingFinalizers()
End Try
End Sub
' Properties
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = (cp.ExStyle Or &H80000)
cp.ExStyle = (cp.ExStyle Or &H80)
Return cp
End Get
End Property
End Class
For any form, we can use this code to make it transparent:
Dim frm As New PerPixelAlphaForm
frm.SetBitmap(My.Resources.Blue)
frm.Show()
This code makes frm
(Form
) transparent like the blue bubble image (as shown in the above image).
Now we will talk about how to show different colors of bubbles. I have used different images to show different colored bubbles.
First, I have defined a random number. Then according to it, we can set different images to bubbles. When Timer1
ticks, a random number is generated and a bubble comes out. I have combined them to close the screensaver when the cursor moves in timer1_tick
code.
Timer1_tick
Private Sub Timer1_Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Timer1.Tick
If MposL <> System.Windows.Forms.Cursor.Position.X Or _
MposT <> System.Windows.Forms.Cursor.Position.Y Then
Timer1.Enabled = False
Me.Close()
Exit Sub
End If
k = New PerPixelAlphaForm
Dim a As New System.Random
Select Case a.NextDouble
Case Is < 0.1
k.SetBitmap(My.Resources.Blue)
Case Is < 0.2
k.SetBitmap(My.Resources.Green)
Case Is < 0.3
k.SetBitmap(My.Resources.Orange)
Case Is < 0.4
k.SetBitmap(My.Resources.Other1)
Case Is < 0.5
k.SetBitmap(My.Resources.Other2)
Case Is < 0.6
k.SetBitmap(My.Resources.Pink)
Case Is < 0.7
k.SetBitmap(My.Resources.Red)
Case Is < 0.8
k.SetBitmap(My.Resources.Violate)
Case Else
k.SetBitmap(My.Resources.Yellow)
End Select
If TotalBub < txtBubbles.Text Then
k.Ang = 1.57 * a.NextDouble
k.Show()
TotalBub += 1
End If
k = Nothing
End Sub
Now the difficulty was how to send bubbles in different directions and get them to move back when they collide with the edge of the screen. Again, I used a random number and some math functions to send them in different angles and when the position becomes beyond the screen width, they go in other directions. I have added a Timer
to get the position and angle in PerPixelAlphaForm.vb.
Editing in PerPixelAlphaForm.vb
Private Sub Timer1_Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles tim.Tick
If Me.Left < 0 Or Me.Top < 0 Or Me.Left > _
Screen.PrimaryScreen.WorkingArea.Width - _
185 Or Me.Top > Screen.PrimaryScreen.WorkingArea.Height - 185 Then
Ang += 1.57 * Date.Now.Millisecond / 1000
If Me.Left < 0 Then Me.Left = 0
If Me.Top < 0 Then Me.Top = 0
If Me.Right > Screen.PrimaryScreen.WorkingArea.Width Then Me.Left = _
Screen.PrimaryScreen.WorkingArea.Width - 185
If Me.Bottom > Screen.PrimaryScreen.WorkingArea.Height Then Me.Top = _
Screen.PrimaryScreen.WorkingArea.Height - 185
Else
Me.Left += Math.Cos(Ang) * 10
Me.Top -= Math.Sin(Ang) * 10
End If
End Sub
I have set timer1.interval
to 2
to give speed and reality to bubbles when they load.
Private Sub PerPixelAlphaForm_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
tim.Enabled = True
tim.Interval = 2
Me.Top = Screen.PrimaryScreen.WorkingArea.Height - 200
Me.Left = 0
End Sub
History
- 22nd May, 2011: First release