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!