Controls provide a paint event that is called at the end of their own paint
cycles. Handling this event and painting on the Graphics object provided
will ensure that whatever you paint is correctly timed to coincide with the
message driven architecture of Windows.
You can force the control to paint itself by calling the Invalidate method,
this initiates a paint cycle which will then kick off the Paint event where
you can do your own drawing.
For your own requirements you're a bit stuck because PictureBox doesn't do
internal double buffering and so invalidating the control at a rate that
would enable animation such as you require would also cause unacceptable
flickering. I don't think you'll get a good result with a transition engine
that writes over the contents of a PictureBox. PictureBox is a fairly
useless and much misused control anyway.
I would suggest creating a custom control to display an image and do the
transitions. Below my signature is a control I wrote for WellFormed that
does transitions. You may be able to modify that code to suit your purposes.
--
Bob Powell [MVP]
Visual C#, System.Drawing
Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/gdiplus_faq.htm
The GDI+ FAQ RSS feed:
http://www.bobpowell.net/faqfeed.xml
Windows Forms Tips and Tricks RSS:
http://www.bobpowell.net/tipstricks.xml
Bob's Blog:
http://bobpowelldotnet.blogspot.com/atom.xml
----------------------------------------------------------------------------
------------------
Imports System
Imports System.Componen tModel
Imports System.Drawing
Imports System.Drawing. Drawing2D
Imports System.Drawing. Imaging
Imports System.Threadin g
Imports System.Windows. Forms
Namespace WellFormed
'/ <summary>
'/ Summary description for ImageTransition Control.
'/ </summary>
Public Class ImageTransition Control
Inherits Control
Private t As System.Threadin g.Timer
Public Enum TransitionTypes
Fade
BarnDoor
Slide
Spin
Checker
Blinds
Iris
Spiral
End Enum 'TransitionType s
Private _transitionType As TransitionTypes = TransitionTypes .Fade
Public Property TransitionType( ) As TransitionTypes
Get
Return _transitionType
End Get
Set(ByVal Value As TransitionTypes )
_transitionType = value
End Set
End Property
Private _nHDivs As Integer = 3
Public Property HorizontalDivis ions() As Integer
Get
Return _nHDivs
End Get
Set(ByVal Value As Integer)
If value = 0 Then
value = 3
End If
_nHDivs = value
End Set
End Property
Private _nVDivs As Integer = 3
Public Property VerticalDivisio ns() As Integer
Get
Return _nVDivs
End Get
Set(ByVal Value As Integer)
If value = 0 Then
value = 3
End If
_nVDivs = value
End Set
End Property
Private _imageA As Image
Public Property ImageA() As Image
Get
Return _imageA
End Get
Set(ByVal Value As Image)
_imageA = value
End Set
End Property
Private _imageB As Image
Public Property ImageB() As Image
Get
Return _imageB
End Get
Set(ByVal Value As Image)
_imageB = value
End Set
End Property
Public Sub New()
SetStyle(Contro lStyles.AllPain tingInWmPaint Or ControlStyles.D oubleBuffer Or
ControlStyles.U serPaint Or ControlStyles.R esizeRedraw, True)
End Sub 'New
'Variables used in the timing system
Private _transitionTime As New TimeSpan(0, 0, 0, 1, 0)
Private _currentPercent age As Single = 0
Private _running As Boolean = False
Public Property TransitionTime( ) As Single
Get
Return CSng(_transitio nTime.TotalSeco nds)
End Get
Set(ByVal Value As Single)
_transitionTime = New TimeSpan(0, 0, 0, 0, CInt(1000 * value))
End Set
End Property
'The moment at which the transition begins
Private _startTime As DateTime
'Called to start the transition off
Public Sub Go()
t = New System.Threadin g.Timer(New TimerCallback(A ddressOf Tick), Nothing,
40, 40)
Me._currentPerc entage = 0
_running = True
_startTime = DateTime.Now
Invalidate()
End Sub 'Go
'Services the tick event and re-calculates the percentage done
Sub Tick(ByVal state As Object)
Dim ts As TimeSpan = DateTime.Now.Su btract(Me._star tTime)
_currentPercent age = CSng(100.0F / Me._transitionT ime.TotalSecond s *
ts.TotalSeconds )
If _currentPercent age > 100 Then
_currentPercent age = 100
End If
Invalidate()
End Sub 'Tick
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
If _imageA Is Nothing OrElse _imageB Is Nothing Then
Return
End If
Dim pth As GraphicsPath = Nothing
If _currentPercent age < 100 Then
e.Graphics.Draw Image(_imageA, Me.ClientRectan gle, 0, 0, _imageA.Width,
_imageA.Height, GraphicsUnit.Pi xel)
End If
Select Case Me.TransitionTy pe
Case TransitionTypes .Fade
If (True) Then
'This transition fades one image over the other
Dim ia As New ImageAttributes
Dim cm As New ColorMatrix
cm.Matrix33 = 1.0F / 255 * (255 * _currentPercent age / 100)
ia.SetColorMatr ix(cm)
e.Graphics.Draw Image(_imageB, Me.ClientRectan gle, 0, 0, _imageB.Width,
_imageB.Height, GraphicsUnit.Pi xel, ia)
ia.Dispose()
End If
Case TransitionTypes .BarnDoor
'has the effect of a barn door closing over the image
e.Graphics.Draw Image(_imageB, New Rectangle(0, 0, CInt(Me.Width *
_currentPercent age / 200), Me.Height), 0, 0, CInt(_imageB.Wi dth / 2),
_imageB.Height, GraphicsUnit.Pi xel)
e.Graphics.Draw Image(_imageB, New Rectangle(CInt( Me.Width - Me.Width *
_currentPercent age / 200), 0, CInt(Me.ClientR ectangle.Width *
_currentPercent age / 200), Me.ClientRectan gle.Height), CInt(_imageB.Wi dth /
2), 0, CInt(_imageB.Wi dth / 2), _imageB.Height, GraphicsUnit.Pi xel)
Case TransitionTypes .Iris
'use a path
pth = New GraphicsPath
'calculate the width and height of the ellipse
Dim w As Integer = CInt(Me.Width * 1.414F * _currentPercent age / 200)
Dim h As Integer = CInt(Me.Height * 1.414F * _currentPercent age / 200)
pth.AddEllipse( CInt(Me.Width / 2 - w), CInt(Me.Height / 2 - h), CInt(2 * w),
CInt(2 * h))
'use the path as a clipping region
e.Graphics.SetC lip(pth, CombineMode.Rep lace)
'Draw the image
e.Graphics.Draw Image(_imageB, ClientRectangle , 0, 0, _imageB.Width,
_imageB.Height, GraphicsUnit.Pi xel)
pth.Dispose()
Case TransitionTypes .Checker
pth = New GraphicsPath
Dim cw As Integer = CInt(Me.Width * _currentPercent age / 100) / _nHDivs
Dim ch As Integer = Me.Height / _nVDivs
Dim row As Integer = 0
Dim y As Integer
For y = 0 To (Me.Height) - ch Step ch
Dim x As Integer
For x = 0 To (Me.Width) - (Me.Width / _nHDivs) Step Me.Width / _nHDivs
Dim rc As New Rectangle(x, y, cw, ch)
If (row And 1) = 1 Then
rc.Offset(Me.Wi dth / (2 * _nVDivs), 0)
End If
pth.AddRectangl e(rc)
If _currentPercent age >= 50 AndAlso (row And 1) = 1 AndAlso x = 0 Then
rc.Offset(-(Me.Width / _nHDivs), 0)
pth.AddRectangl e(rc)
End If
Next x
row += 1
Next y
Dim r As New [Region](pth)
e.Graphics.SetC lip(r, CombineMode.Rep lace)
e.Graphics.Draw Image(_imageB, ClientRectangle , 0, 0, _imageB.Width,
_imageB.Height, GraphicsUnit.Pi xel)
r.Dispose()
pth.Dispose()
Case TransitionTypes .Slide
Dim mx As New Matrix(1, 0, 0, 1, Me.Width * _currentPercent age / 100 -
Me.Width, 0)
e.Graphics.Tran sform = mx
e.Graphics.Draw Image(_imageB, ClientRectangle , 0, 0, _imageB.Width,
_imageB.Height, GraphicsUnit.Pi xel)
Case TransitionTypes .Spin
' calculate the degrees of spin
Dim degrees As Single = 360 * _currentPercent age / 100
'and the origin (center of the client area
Dim ofsX As Single = Me.Width / 2
Dim ofsY As Single = Me.Height / 2
'calculate the scale at which the image will be drawn
Dim Scale As Single = 1 * _currentPercent age / 100
'catering for zero's which will cause an exception
If Scale = 0 Then
Scale = 0.0001F
End If 'create a matrix with the scale and origin
Dim rm As New Matrix(Scale, 0, 0, Scale, ofsX, ofsY)
'do the spin
rm.Rotate(degre es, MatrixOrder.Pre pend)
'use the matrix
e.Graphics.Tran sform = rm
'draw the image
e.Graphics.Draw Image(_imageB, New Rectangle(-Width / 2, -Height / 2, Width,
Height), 0, 0, _imageB.Width, _imageB.Height, GraphicsUnit.Pi xel)
rm.Dispose()
Case TransitionTypes .Spiral
If _currentPercent age < 100 Then
Dim percentageAngle As Double = _nHDivs * (Math.PI * 2) / 100
Dim percentageDista nce As Double = Math.Max(Width, Height) / 100
pth = New GraphicsPath(Fi llMode.Winding)
Dim cx As Single = Width / 2
Dim cy As Single = Height / 2
Dim pc1 As Double = _currentPercent age - 100
Dim pc2 As Double = _currentPercent age
If pc1 < 0 Then
pc1 = 0
End If
Dim a As Double = percentageAngle * pc2
Dim last As New PointF(CSng(cx + pc1 * percentageDista nce * Math.Cos(a)),
CSng(cy + pc1 * percentageDista nce * Math.Sin(a)))
a = percentageAngle * pc1
While pc1 <= pc2
Dim thisPoint As New PointF(CSng(cx + pc1 * percentageDista nce *
Math.Cos(a)), CSng(cy + pc1 * percentageDista nce * Math.Sin(a)))
pth.AddLine(las t, thisPoint)
last = thisPoint
pc1+=0.1
a+=percentageAn gle/10
End While
pth.CloseFigure ()
e.Graphics.SetC lip(pth, CombineMode.Rep lace)
pth.Dispose()
End If
e.Graphics.Draw Image(_imageB, ClientRectangle , 0, 0, _imageB.Width,
_imageB.Height, GraphicsUnit.Pi xel)
Case TransitionTypes .Blinds
Dim y As Integer
For y = 0 To _nHDivs - 1
Dim src As New Rectangle(0, y * (_imageB.Height / _nHDivs), _imageB.Width,
_imageB.Height / _nHDivs)
Dim drc As New Rectangle(0, y * (Height / _nHDivs), Width, CInt(Height /
_nHDivs * _currentPercent age / 100))
drc.Offset(0, Height / (_nHDivs * 2) - drc.Height / 2)
e.Graphics.Draw Image(_imageB, drc, src, GraphicsUnit.Pi xel)
Next y
End Select
If _currentPercent age = 100 Then
_running = False
If Not (t Is Nothing) Then
t.Dispose()
End If
t = Nothing
End If
MyBase.OnPaint( e)
End Sub 'OnPaint
End Class 'ImageTransitio nControl
End Namespace 'WellFormed
----------------------------------------------------------------------------
------------------
"rut" <ru*@discussion s.microsoft.com > wrote in message
news:20******** *************** ***********@mic rosoft.com...
If I have a picturebox with a background image and I want to
1. Display text atop of the background and
2. Have transistions between text; ie, when the text changes, the screen
can fade out/in or have a windowblind type transition,etc.
How do you create transitions in a picture box in conjunction with
displaying text?
(Using vb.net.