Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

.NET LCD MatrixControl and GDI+

0.00/5 (No votes)
19 Jun 2004 1  
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