Introduction
Developing programs can be a drag sometimes, especially if you must do that for a living, and even more so when certain projects are just plain boring. Luckily, I’ve got my articles to provide some color and excitement to my life as developer.
Today, I will show you how to create a scrolling text user control. It is a lot of work, so let’s jump right in.
Create a new VB.NET or C# Windows Forms application with Visual Studio.
Add a class library to your project. This will be used as the user control. Name it something funky; keep in mind that my names may differ from yours.
Open the code file for the class that you have just created, and ensure that you inherit from UserControl, as shown next:
C#
public class clsScroll_C : System.Windows.Forms.UserControl
VB.NET
Public Class clsScroll_VB
Inherits System.Windows.Forms.UserControl
This adds the capabilities of a UserControl, which you can override or use whenever developing controls for your forms. Add the next few Namespaces.
C#
using System.Drawing;
using System.Windows.Forms;
VB.NET
Imports System.Drawing
Imports System.Windows.Forms
Now you have added Drawing capabilities to your UserControl, as well as added ordinary Windows Forms features.
Add the following fields to your class.
C#
private int intWidth;
private bool[,] blnDisplay = new bool[400, 200];
private SolidBrush sbColor = new SolidBrush(Color.Aqua);
private bool[,] blnText;
private int intSpeed = 8;
private string strText = "Example";
private System.Timers.Timer T = new System.Timers.Timer();
private Font fFont = new Font("Arial", 10);
private Graphics grpGraphics;
private Bitmap bmpGrp = new Bitmap(400, 300);
private Graphics grpG;
VB.NET
Private intWidth As Integer
Private blnDisplay As Boolean(,) = New Boolean(399, 199) {}
Private sbColor As SolidBrush = New SolidBrush(Color.Aqua)
Private blnText As Boolean(,)
Private intSpeed As Integer = 8
Private strText As String = "Example"
Private T As System.Timers.Timer = New System.Timers.Timer()
Private fFont As Font = New Font("Arial", 10)
Private grpGraphics As Graphics
Private bmpGrp As Bitmap = New Bitmap(400, 300)
Private grpG As Graphics
Most of the fields above are quite self-explanatory. A few highlights are the Display array for the grid window, the size of the Graphic bitmap, and then some settings such as speed, text, color, and font. These could be used later to create separate properties to be customized by the user. Perhaps in a Part 2 of this article, this could be covered.
Add the following Properties.
C#
public new Font ScrollFont
{
get
{
return fFont;
}
set
{
fFont = value;
CreateArray(strText);
}
}
public int ScrollSpeed
{
get
{
return intSpeed;
}
set
{
if (value < 11)
{
intSpeed = value;
switch (value)
{
case 1:
T.Interval = 1000;
break;
case 2:
T.Interval = 900;
break;
case 3:
T.Interval = 750;
break;
case 4:
T.Interval = 600;
break;
case 5:
T.Interval = 400;
break;
case 6:
T.Interval = 200;
break;
case 7:
T.Interval = 100;
break;
case 8:
T.Interval = 50;
break;
case 9:
T.Interval = 25;
break;
case 10:
T.Interval = 1;
break;
}
}
}
}
public string ScrollText
{
get
{
return strText;
}
set
{
strText = value;
CreateArray(value);
}
}
public override Color ForeColor
{
get
{
return sbColor.Color;
}
set
{
sbColor = new SolidBrush(value);
}
}
VB.NET
Public Overloads Property ScrollFont As Font
Get
Return fFont
End Get
Set(ByVal value As Font)
fFont = value
CreateArray(strText)
End Set
End Property
Public Property ScrollSpeed As Integer
Get
Return intSpeed
End Get
Set(ByVal value As Integer)
If value < 11 Then
intSpeed = value
Select Case value
Case 1
T.Interval = 1000
Case 2
T.Interval = 900
Case 3
T.Interval = 750
Case 4
T.Interval = 600
Case 5
T.Interval = 400
Case 6
T.Interval = 200
Case 7
T.Interval = 100
Case 8
T.Interval = 50
Case 9
T.Interval = 25
Case 10
T.Interval = 1
End Select
End If
End Set
End Property
Public Property ScrollText As String
Get
Return strText
End Get
Set(ByVal value As String)
strText = value
CreateArray(value)
End Set
End Property
Public Overrides Property ForeColor As Color
Get
Return sbColor.Color
End Get
Set(ByVal value As Color)
sbColor = New SolidBrush(value)
End Set
End Property
Add the methods to create the scrolling text and to create the display blocks.
C#
private void CreateArray(string strTemp)
{
Graphics g;
Bitmap bmpImage = new Bitmap(400, 200);
g = Graphics.FromImage(bmpImage);
intWidth = (int)g.MeasureString(strTemp, fFont).Width;
intWidth += 20;
if (intWidth < 400) intWidth = 400;
bmpImage = new Bitmap(intWidth, 200);
g = Graphics.FromImage(bmpImage);
g.DrawString(strTemp, fFont, Brushes.Blue, 0, 0);
blnText = new bool[intWidth, 200];
for (int x = 0; x < intWidth; x++)
{
for (int y = 0; y < 200; y++)
{
if (bmpImage.GetPixel(x, y).ToArgb() != 0)
{
blnText[x, y] = true;
}
else
{
blnText[x, y] = false;
}
}
}
g.Dispose();
}
private void StepArray()
{
bool[] arrTemp = new bool[200];
for (int x = 0; x < 200; x++)
{
arrTemp[x] = blnText[0, x];
}
for (int x = 1; x < intWidth; x++)
{
for (int y = 0; y < 200; y++)
{
blnText[x - 1, y] = blnText[x, y];
}
}
for (int x = 0; x < 200; x++)
{
blnText[intWidth - 1, x] = arrTemp[x];
}
for (int x = 0; x < 400; x++)
{
for (int y = 0; y < 200; y++)
{
blnDisplay[x, y] = blnText[x, y];
}
}
ScrollRefresh();
}
private void T_Tick(object sender,
System.Timers.ElapsedEventArgs e)
{
if (DesignMode != true) StepArray();
}
private void ScrollRefresh()
{
grpG = Graphics.FromImage(bmpGrp);
for (int x = 0; x < 400; x++)
{
for (int y = 0; y < 200; y++)
{
if (blnDisplay[x, y])
{
grpG.FillRectangle(sbColor, new Rectangle((5 * x)
+ 1, (5 * y) + 1, 4, 4));
}
else
{
grpG.FillRectangle(Brushes.Wheat,
new Rectangle((5 * x) + 1, (5 * y) + 1, 4, 4));
}
}
}
grpGraphics.DrawImage(bmpGrp, 0, 0);
}
VB.NET
Private Sub CreateArray(ByVal strTemp As String)
Dim g As Graphics
Dim bmpImage As Bitmap = New Bitmap(400, 200)
g = Graphics.FromImage(bmpImage)
intWidth = CInt(g.MeasureString(strTemp, fFont).Width)
intWidth += 20
If intWidth < 400 Then intWidth = 400
bmpImage = New Bitmap(intWidth, 200)
g = Graphics.FromImage(bmpImage)
g.DrawString(strTemp, fFont, Brushes.Blue, 0, 0)
blnText = New Boolean(intWidth - 1, 199) {}
For x As Integer = 0 To intWidth - 1
For y As Integer = 0 To 200 - 1
If bmpImage.GetPixel(x, y).ToArgb() <> 0 Then
blnText(x, y) = True
Else
blnText(x, y) = False
End If
Next
Next
g.Dispose()
End Sub
Private Sub StepArray()
Dim arrTemp As Boolean() = New Boolean(199) {}
For x As Integer = 0 To 200 - 1
arrTemp(x) = blnText(0, x)
Next
For x As Integer = 1 To intWidth - 1
For y As Integer = 0 To 200 - 1
blnText(x - 1, y) = blnText(x, y)
Next
Next
For x As Integer = 0 To 200 - 1
blnText(intWidth - 1, x) = arrTemp(x)
Next
For x As Integer = 0 To 400 - 1
For y As Integer = 0 To 200 - 1
blnDisplay(x, y) = blnText(x, y)
Next
Next
ScrollRefresh()
End Sub
Private Sub T_Tick(ByVal sender As Object, ByVal e As _
System.Timers.ElapsedEventArgs)
If DesignMode <> True Then StepArray()
End Sub
Private Sub ScrollRefresh()
grpG = Graphics.FromImage(bmpGrp)
For x As Integer = 0 To 400 - 1
For y As Integer = 0 To 200 - 1
If blnDisplay(x, y) Then
grpG.FillRectangle(sbColor, New Rectangle((5 * x) _
+ 1, (5 * y) + 1, 4, 4))
Else
grpG.FillRectangle(Brushes.Wheat, New _
Rectangle((5 * x) + 1, (5 * y) + 1, 4, 4))
End If
Next
Next
grpGraphics.DrawImage(bmpGrp, 0, 0)
End Sub
Add the last few methods to set up and create the control.
C#
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Black, new Rectangle(0, 0,
base.Width - 1, base.Height - 1));
if (DesignMode)
{
for (int x = 0; x < 400; x++)
{
for (int y = 0; y < 200; y++)
{
if (blnDisplay[x, y])
{
e.Graphics.FillRectangle(sbColor, new
Rectangle((5 * x) + 1, (5 * y) + 1, 4, 4));
}
else
{
e.Graphics.FillRectangle(Brushes.Black, new
Rectangle((5 * x) + 1, (5 * y) + 1, 4, 4));
}
}
}
}
e.Graphics.DrawRectangle(Pens.White, 0, 0, 400, 200);
e.Graphics.DrawRectangle(Pens.WhiteSmoke, 0, 0, 401, 201);
}
public clsScroll_C()
{
InitializeComponent();
CreateArray(ScrollText);
ScrollSpeed = 8;
T.Elapsed += new System.Timers.ElapsedEventHandler(T_Tick);
T.Start();
base.SetStyle(ControlStyles.DoubleBuffer, true);
base.SetStyle(ControlStyles.UserPaint, true);
base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
base.SetStyle(ControlStyles.ResizeRedraw, true);
base.UpdateStyles();
this.Size = new System.Drawing.Size(401, 201);
grpGraphics = base.CreateGraphics();
}
private void InitializeComponent()
{
//
// ScrollText
//
this.Name = "Example";
this.ForeColor = ForeColor
this.Size = new System.Drawing.Size(401, 201);
this.ScrollSpeed = ScrollSpeed;
this.Text = ScrollText;
}
VB.NET
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
e.Graphics.FillRectangle(Brushes.Black, New Rectangle(0, 0, _
MyBase.Width - 1, MyBase.Height - 1))
If DesignMode Then
For x As Integer = 0 To 400 - 1
For y As Integer = 0 To 200 - 1
If blnDisplay(x, y) Then
e.Graphics.FillRectangle(sbColor, New +
Rectangle((5 * x) + 1, (5 * y) + 1, 4, 4))
Else
e.Graphics.FillRectangle(Brushes.Black, New _
Rectangle((5 * x) + 1, (5 * y) + 1, 4, 4))
End If
Next
Next
End If
e.Graphics.DrawRectangle(Pens.White, 0, 0, 400, 200)
e.Graphics.DrawRectangle(Pens.WhiteSmoke, 0, 0, 401, 201)
End Sub
Public Sub New()
InitializeComponent()
CreateArray(ScrollText)
ScrollSpeed = 8
AddHandler T.Elapsed, New System.Timers.ElapsedEvent _
Handler(AddressOf T_Tick)
T.Start()
MyBase.SetStyle(ControlStyles.DoubleBuffer, True)
MyBase.SetStyle(ControlStyles.UserPaint, True)
MyBase.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
MyBase.SetStyle(ControlStyles.ResizeRedraw, True)
MyBase.UpdateStyles()
Me.Size = New System.Drawing.Size(401, 201)
grpGraphics = MyBase.CreateGraphics()
End Sub
Private Sub InitializeComponent()
Me.Name = "Example"
Me.ForeColor = ForeColor
Me.Size = New System.Drawing.Size(401, 201)
Me.ScrollSpeed = ScrollSpeed
Me.Text = ScrollText
End Sub
Build your Solution. If all went well, and there are no errors, open the Form in Design View and find the newly created control in the Toolbox.
Conclusion
In a future piece, I could perhaps take the properties for this control a bit further and extend them. Until then, happy coding!