Click here to Skip to main content
11,479,162 members (49,621 online)
Click here to Skip to main content

.NET LCD MatrixControl and GDI+

, 19 Jun 2004 67.2K 3.4K 57
Rate this:
Please Sign up or sign in to vote.
Implementation of a LCD User Control in .NET using C#.

Sample Image - LCDMatrixControl_screen.gif

Introduction

Once, it was required for me, a control similar to LCD, for data presentation. Having looked in the Internet, I found a nice realization from Nic Wilson. But the code was written in C++, and my project was in C#. Therefore, I decided to rewrite Nic's code, and at the same time I wanted to estimate how quick GDI+ works in .NET.

Using the code

In your project, you need to refer to the library with our control, then you should place the control in design time in your project.

After you finish with design time, start initializing our control in the constructor.

public Form1()
{
  InitializeComponent();
  BkColor = Color.FromArgb(R,G,B);
  OnColor = Color.FromArgb(R,G,B);
  OffColor = Color.FromArgb(R,G,B);
  //Set up initial text.
  this.matrixControl1.ScreenText = " Info Text ";
  //In this case pad symbol is empty.
  matrixControl1.SetAutoPadding(true,' ');
  //If you want immeditely start scrolling, 
  //please uncomment next line.
  //matrixControl1.DoScroll(1000, 
  //    MatrixLib.MatrixControl.ScrollDirection.Left);
}

The main "magic" occurs in a method OnPaint.

protected override void OnPaint(PaintEventArgs pea) 
{
  Rectangle m_rect = this.DisplayRectangle;
  //Create buffer image
  Bitmap _buffImage = new Bitmap(m_rect.Width,m_rect.Height);
  Graphics _buff = Graphics.FromImage(_buffImage);
  int x = 0, y = 0;
  int strlen = m_StrText.Length;
  if (strlen == 0)
    return;
  //Create array of color maps
  System.Drawing.Imaging.ColorMap []_ColorMap = 
            new System.Drawing.Imaging.ColorMap[3];
  _ColorMap[0] = new System.Drawing.Imaging.ColorMap();
  _ColorMap[1] = new System.Drawing.Imaging.ColorMap();
  _ColorMap[2] = new System.Drawing.Imaging.ColorMap();
  _ColorMap[0].OldColor = SEGM_COLORS[0];
  _ColorMap[0].NewColor = m_crOnColor;
  _ColorMap[1].OldColor = SEGM_COLORS[1];
  _ColorMap[1].NewColor = m_OffColor;
  _ColorMap[2].OldColor = SEGM_COLORS[2];
  _ColorMap[2].NewColor = m_crBackColor;
  
  //Obtain image attributes
  System.Drawing.Imaging.ImageAttributes bmpAttr = 
          new System.Drawing.Imaging.ImageAttributes();
  try
  {
    bmpAttr.SetRemapTable(_ColorMap);
  }
  catch(System.Exception ex)
  {
    Debug.Fail(ex.Message);
  }
  int charcount = 0;
  int linecount = 1;
  SolidBrush hbBkBrush = new SolidBrush(m_crBackColor);
  //Fill control rectangle 
  _buff.FillRectangle(hbBkBrush,m_rect);
  //Initialize two rectangeles
  Rectangle clipDstn = Rectangle.Empty;
  Rectangle clipSrc = Rectangle.Empty;

  //Now we will start main processing.
  for (int ix = 0; ix < strlen; ix++)
  {
    //This method calculates clip region for current char.
    GetCharBmpOffset((char)m_StrText[ix], ref clipSrc);
    //Initializes target clip.
    clipDstn = new Rectangle(x,y,clipSrc.Width,clipSrc.Height);
    //Draw current symbol in buffer
    _buff.DrawImage(m_ImageMatrix, clipDstn, clipSrc.X, 
              clipSrc.Y, clipSrc.Width, clipSrc.Height, 
              GraphicsUnit.Pixel, bmpAttr);

    x += m_CharWidth + m_XSpacing;
    charcount++;
    if ((charcount == m_MaxXChars) && m_MaxYChars == 1)
    {
      break;
    }
    else if ((charcount == m_MaxXChars) && m_MaxYChars > 1)
    {
      if (linecount == m_MaxYChars)
      {
        break;
      }
      x = charcount = 0;
      y += m_CharHeight + m_YSpacing;
      linecount++;
    }
  }
  //And finally draw our image on control surface.
  pea.Graphics.DrawImage(_buffImage,0,0); 
  //Next lines are necessary...
  hbBkBrush.Dispose();
  hbBkBrush= null;
  bmpAttr.Dispose();
  bmpAttr = null;
  _buff.Dispose();_buff = null;

  _buffImage.Dispose(); _buffImage = null;
}

Conclusion and current issues

The control works perfect, without flickering, but, if you will use the control without scrolling. If you will need scrolling, your application will consume 100% CPU!!!.

Probably, the following line causes the strong consumption of CPU time:

...

//Draw current symbol in buffer 
_buff.DrawImage(m_ImageMatrix, clipDstn, clipSrc.X, 
          clipSrc.Y, clipSrc.Width, clipSrc.Height, 
          GraphicsUnit.Pixel, bmpAttr);
...

It's really so... if you comment out this line, you will get 0% CPU usage.

Conclusion

For heavy operations, it is better to use native methods of API. You may try replacing this line with another one, and try using the API method:

[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, // handle to destination DC
int nXDest, // x-coord of dest upper-left corner
int nYDest, // y-coord of dest upper-left corner
int nWidth, // width of destination rectangle
int nHeight, // height of destination rectangle
IntPtr hdcSrc, // handle to source DC
int nXSrc, // x-coord of source upper-left corner
int nYSrc, // y-coord of source upper-left corner
System.Int32 dwRop // raster operation code
);

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Mikhail Cholokhov
Web Developer
Germany Germany
No Biography provided

Comments and Discussions

 
Questionpositioning Pin
dano215-Nov-12 11:30
memberdano215-Nov-12 11:30 
QuestionI need your some help ! Pin
painterargon30-Aug-12 1:29
memberpainterargon30-Aug-12 1:29 
SuggestionI just tried Pin
cyprussun25-Aug-12 0:28
membercyprussun25-Aug-12 0:28 
Hi Mikhail, it's all there!
Drop a Picture Box, a Timer, a Button, a TextBox on a Form.
Assign the Button and TimerEvent. Set the timer interval to 50, Enabled = false.
Set the PictureBox BackgroundColor, perhaps play with settings in the code.
Enter any text in the Textbox (even at runtime).
Click the Button and enjoy.
(ProcessTime? I could not see much. System Idle 99.5 - 100%,
CPU Usage 0.8% (over all, App running in debug mode & lots in memory)),
on a PC from this century!
Flickering & flashing? Once in a blue moon! It's drawn in the memory
before shoved up to the picturebox.

Q: Is a LCD/LED Panel build up with a dot array, pixels switched on individually to display text or
with text intercepted by same regular occurring lines?
A: (Einstein remembered!)

// expand and alter the code as desired, no license need
int yPos = 0; Font fo;
private void button1_Click(object sender, EventArgs e)
{
Bitmap bm; int i, n; Color textColor = new Color(); Point pt1 = new Point();
// Playplay settings besides BackColor of the PictureBox on the Form (RoyalBlue)
// Consider dark lines darken the overall impression considerably
int matrix = 2;
fo = new Font(textBox1.Font.Name, 35, FontStyle.Regular);
using (SolidBrush brush = new SolidBrush(pictureBox1.BackColor))
{
Pen pen;
pen = new Pen(brush);
pen.Color = Color.Black;
textColor = Color.Yellow;// LightBlue;

StringFormat textFormat = new StringFormat(StringFormatFlags.NoClip | StringFormatFlags.NoWrap);
bm = new Bitmap(pictureBox1.Bounds.Width, pictureBox1.Bounds.Height);
pt1.X = pictureBox1.Bounds.Width;
pt1.Y = pictureBox1.Bounds.Height;

Graphics gr = Graphics.FromImage(bm);
gr.FillRectangle(brush, new Rectangle(0, 0, bm.Width, bm.Height));
textFormat.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show;
textFormat.Alignment = StringAlignment.Center;
textFormat.LineAlignment = StringAlignment.Center;

gr.DrawString(textBox1.Text, fo, new SolidBrush(textColor),
new RectangleF(0, yPos, pictureBox1.Bounds.Width, fo.SizeInPoints), textFormat);

i = 0; n = 0;
while (i < pictureBox1.Height)
{
gr.DrawLine(pen, new Point(0, n * matrix), new Point(pictureBox1.Width, n * matrix));
i += matrix; n++;
}
i = 0; n = 0;
while (i < pictureBox1.Width)
{
gr.DrawLine(pen, new Point(n * matrix, 0), new Point(n * matrix, pictureBox1.Height));
i += matrix; n++;
}
}
pictureBox1.Image = bm;
if (!timer1.Enabled)
timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
if (fo == null)
return;
if (yPos == 0 - fo.SizeInPoints)
yPos = pictureBox1.Height;
yPos--;
button1_Click(null, null);
} Smile | :)
Questionmatrix.size ? Pin
davor_saguaro20-Aug-07 1:50
memberdavor_saguaro20-Aug-07 1:50 
GeneralFull CharSet... Pin
Razorino29-Nov-04 22:57
memberRazorino29-Nov-04 22:57 
GeneralGerman character Pin
westfale4-Aug-04 21:44
memberwestfale4-Aug-04 21:44 
GeneralRe: German character Pin
Mikhail Cholokhov7-Aug-04 3:39
memberMikhail Cholokhov7-Aug-04 3:39 
GeneralRe: German character Pin
westfale18-Aug-04 2:31
memberwestfale18-Aug-04 2:31 
GeneralRe: German character Pin
loizzi19-Jun-05 17:18
memberloizzi19-Jun-05 17:18 
GeneralWrong Characters being displayed Pin
garythom_usa22-Jun-04 1:39
membergarythom_usa22-Jun-04 1:39 
GeneralRe: Wrong Characters being displayed Pin
Razorino..15-Oct-04 4:36
memberRazorino..15-Oct-04 4:36 
GeneralRe: Wrong Characters being displayed Pin
Gary Thom15-Oct-04 5:56
memberGary Thom15-Oct-04 5:56 
GeneralCPU usage Pin
Ray Hayes21-Jun-04 1:42
memberRay Hayes21-Jun-04 1:42 
GeneralRe: CPU usage Pin
Mikhail Cholokhov21-Jun-04 12:28
memberMikhail Cholokhov21-Jun-04 12:28 
GeneralRe: CPU usage Pin
ch3ckmat315-Aug-04 11:37
memberch3ckmat315-Aug-04 11:37 
GeneralSystem.Security.Policy.PolicyException Pin
Joel Holdsworth20-Jun-04 10:13
memberJoel Holdsworth20-Jun-04 10:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150520.1 | Last Updated 20 Jun 2004
Article Copyright 2004 by Mikhail Cholokhov
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid