65.9K
CodeProject 正在变化。 阅读更多。
Home

MFC/GDI+ LCD 控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (109投票s)

2011 年 1 月 25 日

CPOL

9分钟阅读

viewsIcon

215531

downloadIcon

18683

基于 CStatic 和 GDI+ 库的 7/16 段 LCD 控件

annim.gif

引言

我是一名工业开发软件主管;因此,我需要能够清晰显示值的控件。7 段或 16 段控件非常适合这一点。我基于 GDI+ 库创建了这个控件,原因有二:我想要一个漂亮的 GUI,并且我对学习这个库很感兴趣。

CodeProject 的许多文章帮助我编写了这个控件(我记不清所有文章了)。非常感谢整个 CodeProject 社区,特别感谢 Ambalavanar Thirugnanam 他优秀的 Aqua Gauge 文章。

我希望这篇文章能对您未来的项目有所帮助。欢迎任何修改、衍生作品或任何能够改进此控件的事物,请告知我。

特点

  • 绘制边框
  • 支持 256 个字符的字体矩阵
  • 完全可调整大小的控件
  • 显示数字(有符号或无符号)或文本值
  • 光泽和灯光效果(为了获得漂亮的外观)
  • 双缓冲(无闪烁)
  • 绘制透明
  • 闪烁
  • 段(或点)大小可调

使用 CIsiLcdDispaly 控件

步骤 1。此控件使用 GDI+ 库。在使用它之前,您必须初始化此库。如果您的应用程序使用了另一个 GDI+ 组件,您可能已经完成了此操作;否则,您可以使用以下宏来方便地初始化 GDI+ 库。

在您的 CWinApp 派生类头文件中,添加 DECLARE_GDI_PLUS 宏,如下所示:

class MyApp : public CWinApp
{
private :
 DECLARE_GDI_PLUS;
//…//

步骤 2。实现控件

  1. 将所有 .h.cpp 文件插入到您的项目中。
  2. Font5x7.bmp 文件作为位图资源插入。
  3. 在您的对话框资源中添加一个静态控件
  4. 为此静态控件添加一个成员变量。
  5. 修改变量声明。

更改此项

CStatic m_MyLcdCtrl

变为这样:

CIsiLcdDisplay m_MyLcdCtrl
  • 不要忘记在包含文件的顶部添加 #include
#include "IsiLcdDisplay.h".

步骤 2B。动态创建

如果您想动态创建此控件,请在 OnInitDialog() 方法中插入以下代码:

// CIsiLcdDisplay m_MyLcdCtrl CRect lCRect(x,y,dx,dy); 
//Size and position of the control in the dialog 
if ( !m_MyLcdCtrl.Create(_T(“”),WS_CHILD|WS_VISIBLE, lCRect, this, -1 ) ) 
{ 
    ASSERT( 0 );
    // Something wrong 
}

步骤 3。设置控件的外观

OnInitDialog() 方法中,根据所需设计添加以下行:

m_CIsiLcdSample14.LoadMatrix( IDB_MATRIX5x7 );      	// Load 5x7 matrix
m_CIsiLcdSample14.SetNbSegment( MatrixDot, FALSE );   	// Select matrix mode 
                               // (dot)
m_CIsiLcdSample14.SetValueNbDigit( 6,2 );         	// 6 Digits, precision 2
m_CIsiLcdSample14.ShowSign( TRUE );             	// Show sign
m_CIsiLcdSample14.SetColor( RGB(0,150,0) );         	// Set green color (~50%)

步骤 4。更新要显示的值

如果启用了 StringMode ,您必须使用 SetWindowText( _T(“New test”) ); 方法来更新控件;否则,请使用 SetValue( dNewVal ) 方法。

m_CIsiLcdSample14.SetValue( 2.35 );             // Set value to be displayed

//CIsiLcdSample14.SetTextmode( TRUE );
m_CIsiLcdSample14.SetWindowText( _T(“My text”);     // Set value to be displayed

X*Y 矩阵文件格式

Image1.jpg

矩阵存储在位图文件中。我选择此格式是因为 5 x 7 矩阵包含 256 个字符,手动编辑过于庞大(看看 16 段数组,您可以想象 20x20 矩阵的尺寸)。位图是一个很好的文件格式,因为您可以找到许多编辑器,并且可以直接在 Visual Studio 中进行编辑。创建新的字体矩阵不必开发专门的编辑器。您可以使用 2、16、256 或真彩色位图,但 16 色位图似乎是最佳格式,因为我们只需要 3 种不同的颜色(2 种颜色足够,但使用 3 种颜色编辑矩阵更方便)。一种颜色用于识别 OFF 像素,一种用于 ON 像素,最后一种用于区分每个字符。位图的组织方式是 8 行 32 个字符,您必须遵守此结构。最大字符尺寸固定为 20x20,因为我需要一个限制以避免在位图分析过程中崩溃。

位图是如何分析的?第一个可打印字符是空格字符。此字符的所有像素都应为 OFF,因此第一个像素(位置 0,0)必须是背景色。之后,我需要知道字符矩阵的大小(您不受 5 x 7 矩阵的限制)。我解析第一行,直到找到背景色。我使用相同的技术来计算字体矩阵的高度。

创建您的矩阵

步骤 1:创建一个新的位图(宽度 = x * 32 + 32,高度 = y * 8 + 8),或者编辑我的。x、y 是每个字符的尺寸。对于 5*7 矩阵,位图大小为 192*64。如果位图不符合此公式,LoadMatrix() 方法将失败。

步骤 2:绘制线条分隔符。

步骤 3:绘制字符。

步骤 4:使用 LoadMatrix 方法加载您的新矩阵。

看点

光泽效果使控件具有漂亮的外观(据我个人观点;如果您不喜欢这种效果,可以禁用它)。要做到这一点非常简单。

步骤 1:创建填充段路径,使用 ON 段颜色。

步骤 2:稍微放大段路径,以创建辉光效果路径。

//  PointF SegmentH[ 6 ];  // Horizontal segment
//////////////////////////////////////////////////
  Matrix MatrixGlowH;    
  MatrixGlowVH.Scale( GLOW_SCALE_Y,GLOW_SCALE_X );
  // Create vertical segment path ///////////////////////////////////////////////
  m_pathSegmentH.AddPolygon(SegmentH, 6);        // Create segments path
  m_pathSegmentH_Glow.AddPolygon(SegmentH, 6);   // Create glow segments path (the same)
  m_pathSegmentH_Glow.Transform( &MatrixGlowV ); // Scale the path

步骤 3:创建基于辉光效果路径的线性画笔。

// Set blend factors and positions for the path gradient brush.
REAL fac[] = {
 0.0f,  // 0  percent
 0.25f,     // 25 percent
 0.4f,      // 40 percent 
 1.0f}; 
REAL posfac[] = {
 0.0f,   // 50 percent
 0.5f,   // 50 percent
 0.8f,   // 80 percent
1.0f};
// Create glow brush //////////////////////////////////////////////
 PathGlow->Transform( &TmpMatrix );
 PathGradientBrush PathBrushGlow( PathGlow );
 PathBrushGlow.SetCenterColor( Clr(GetGlowColor()).value);
 Color OutColor(0,0,0,0);
 int iNbColor = 1;
 PathBrushGlow.SetSurroundColors( &OutColor, &iNbColor );
 PathBrushGlow.SetBlend(fac, posfac, 4);

步骤 4:使用画笔填充路径。

pGraphics->FillPath( &PathBrushGlow, PathGlow);

CIsiLcdDisplay 继承自 CIsiCompBase 吗?

步骤 1:绘制背景
您必须重载 RebuildGDIbkGnd() 方法。

///////////////////////////////////////////////////////////////////////////////////
// Draw the back ground or your control in the pGraphics object.
// You can draw a complex image (and take lot of time) because this method is call 
// only when the control is moved, resized, or displayed for the first time.
// Usually this method is called only one time.
// CRect &WindowRect provides to you the size of you control
// You should update the WindowRect rect if you draw a border. (otherwise you risk
// to erase it in the OnPaint() method. You could also manage this case yourself.
///////////////////////////////////////////////////////////////////////////////////
virtual BOOL RebuildGDIbkGnd(Graphics* pGraphics, CRect &WindowRect)
{
   m_bReGenBackGnd = FALSE; 
   return TRUE; 
}

步骤 2。绘制指针、条形或其他用于显示控件值的元素。

////////////////////////////////////////////////////////////////////////////////////
// This function is called when the WM_PAINT message occurred, 
// the background is already painted.
// Just draw the mobiles part of your control.
// At the end, you should add the glossiness if your control has this option.
////////////////////////////////////////////////////////////////////////////////////
virtual void OnPaint(Graphics* pGraphics, CRect &WindowRect ) = 0;

文档

类方法

void SetBlink( int iPeriod );

设置闪烁周期(毫秒)。如果此参数为 0(默认值),控件将不会闪烁。

int GetBlink();

返回当前的闪烁周期。

void ShowOffSegment(BOOL bShow, BOOL bRedraw = TRUE);
  • bShow:指定是显示还是隐藏 OFF 段。如果此参数为 TRUE,则显示 OFF 段。如果参数为 FALSE,则隐藏 OFF 段。默认值为 TRUE。
  • bRedraw:如果为 TRUE,则立即重绘控件。
int IsShowOffSegmentVisible();

如果显示 OFF 段,则返回 TRUE;否则返回 FALSE

void StringMode(BOOL bString, BOOL bRedraw = TRUE);
  • bString:如果控件必须使用 SetWindowText() 方法更新,则为 TRUE。如果控件必须使用 SetValue() 方法更新,则为 FALSE。默认值为 FALSE
  • bRedraw:如果为 TRUE,则立即重绘控件。
BOOL IsStringMode();

返回当前模式。

void ShowSign(BOOL bShow, BOOL bRedraw = TRUE);
  • bShow:指定是显示还是隐藏符号。如果此参数为 TRUE,则显示 OFF 符号。如果参数为 FALSE,则隐藏 OFF 符号。默认值为 FALSE。如果启用了 StringMode() ,则此方法无效。
  • bRedraw:如果为 TRUE,则立即重绘控件。
BOOL ISShowSign();

如果显示符号,则返回 TRUE;否则返回 FALSE

void HexMode(BOOL bHex, BOOL bRedraw = TRUE);
  • bHex:指定值是否必须以十六进制格式显示。如果此参数为 TRUE,则值以十六进制模式显示;否则使用十进制。默认值为 FALSE。如果启用了 StringMode(),则此方法无效。
  • bRedraw:如果为 TRUE,则立即重绘控件。
BOOL IsHexMode();

如果值以十六进制格式显示,则返回 TRUE;否则返回 FALSE

void EnableValue( BOOL bEnable );
  • bEnable:指定当前值是否有效。如果此参数为 FALSE,则所有段都为 OFF。默认值为 TRUE
BOOL IsEnableValue();

如果当前值已启用,则返回 TRUE

BOOL SetSegmentSize( float fSize, BOOL bRedraw = TRUE );
  • fSize:段缩放因子。0.5f 表示 50%,1.5f 表示 150%... 默认值为 1.0f。
  • bRedraw:如果为 TRUE,则立即重绘控件。
    此方法允许您调整段的大小。
float GetSegmentSize( );

返回当前的段缩放因子。

void SetColor (COLORREF cOn,COLORREF cOff = 0, COLORREF cGlow = 0);
  • cOn:段为 ON 时的颜色。
  • cOff:段为 OFF 时的颜色。如果此参数为 0,则 OFF 颜色将从 ON 颜色自动计算。
  • cGlow:光泽效果的颜色。如果此参数为 0,则颜色将从 ON 颜色自动计算。如果此参数为 RGB(255,255,255)(白色),则禁用光泽效果。

Image3.jpg

COLOREEF GetColorSegmentOn( );

返回段为 ON 时的颜色。

COLOREEF GetColorSegmentOff( );

返回段为 OFF 时的颜色。

COLOREEF GetColorSegmentGlow( );

返回光泽效果的颜色。

vois SetSegmentStyle( SegmentStyle Style, BOOL bRedraw = TRUE );
  • Style:设置段的样式。
    • Segment7:7 段样式
    • Segment16:16 段样式
    • MatrixDot X*Y 点矩阵(默认 5x7)
    • MatrixSquare X*Y 方形矩阵(默认 5x7)
  • bRedraw:如果为 TRUE,则立即重绘控件。

重要:在使用 MatrixDot MatrixSquare 样式时,必须先加载字体矩阵。请参阅下面的 LoadMatrix() 方法。

Image4.jpg

SegmentsStyle GetSegmentStyle();

返回当前的段样式。

void SetScrollSpeed( int iSpeed );
  • iSpeed:每次移动之间的延迟(毫秒)。如果此参数为 0,则禁用滚动。
int GetScrollSpeed();

返回当前滚动速度。

BOOL LoadMatrix ( UINT uiRes);
  • uiRes:包含位图矩阵资源的 ID。
    成功则返回非零值,否则返回 0
BOOL LoadMatrix ( LPCTSTR lpzFileName);
  • lpzfileName:一个 string ,是矩阵位图文件的路径。
    成功则返回非零值,否则返回 0
BOOL LoadMatrix( CBitmap *pBitmap);
  • *pBitmap:一个 CBitmap 对象,是要加载的矩阵。
    成功则返回非零值,否则返回 0

基类方法

void SetValueNbDigit (int iNbDigit, int iPrecision, BOOL bRedraw= TRUE);
  • iNbDigit:要显示的数字总数。
  • iPrecision:小数点后的数字位数。
  • bRedraw:如果为 TRUE,则立即重绘控件。
void SetValueNbDigit (int iNbDigit, int iPrecision, BOOL bRedraw= TRUE);
  • iNbDigit:要显示的数字总数。
  • iPrecision:小数点后的数字位数。
  • bRedraw:如果为 TRUE,则立即重绘控件。

重要:如果启用了 StringMode ,此方法将不起作用。

Image5.jpg

int GetValueNbDigit ();

返回显示的数字数量。

int GetValuePrecision ();

返回控件的当前精度。

void Transparent( BOOL bTransparent, BOOL bRedraw= TRUE);
  • Tranparent:如果此参数为 TRUE,则不绘制控件的背景。默认值为 FALSE
  • bRedraw:如果为 TRUE,则立即重绘控件。
BOOL GetTransparent( );

返回当前的透明绘制模式。

void ShowGlass( BYTE bShow, BOOL bRedraw= TRUE);
  • bShow:玻璃效果的级别 [0;255]。如果此参数为 0,则禁用玻璃效果。
  • bRedraw:如果为 TRUE,则立即重绘控件。

Image6.jpg

BYTE GetShowGlass();

返回当前的玻璃效果级别。

void SetRoundBorder(int iRound, BOOL bRedraw = TRUE);
  • iRound:控件的圆角。
  • bRedraw: 如果为 TRUE,则立即重绘控件。
int GetRoundBorder( );

返回当前的圆角边框值。

void SetBkgndColor (COLORREF c, BOOL bRedraw = TRUE);
  • c:背景颜色。当绘制透明时,此参数无效。
  • bRedraw:如果为 TRUE,则立即重绘控件。
COLORREF GetBkgndColor ( );

返回背景颜色。

新功能

现在控件可以绘制边框了。边框样式由 CGdiBorder 类提供。要修改边框的外观,您应该调用 GetBorder() 方法来检索指向边框对象的指针。根据需要修改边框的设计(参见下方)。完成后,您应该调用 InvalidateBorder() 方法来更新控件。

边框类方法

void SetSize(int size);
  • size:边框的大小(像素)。如果为 0,则不绘制边框。
int GetSize();

返回当前的边框大小。

void SetStyle(BorderStyle Style);
  • Style:设置边框的样式。
    • Chrome:见下方
    • Lower:见下方
    • Raised:见下方
    • Both:见下方
    • Bump:见下方
    • None:无边框

Image7.jpg

BoderStyle GetStyle();

返回当前的边框样式。

void SetShape(BorderShape Shape, int round = 0);
  • Shape:设置边框的形状。
    • Rectangle
    • 椭圆
    • RoundRect
  • round:圆角控件。此参数仅用于 RoundRect 样式。边框的大小(像素)。如果为 0,则不绘制边框。

Image8.jpg

BoderShape GetShape();


返回当前的边框形状。

int GetShapeRound ();

返回当前的边框圆角值。仅应与 RoundRect 形状样式一起使用。

void SetColor( Color col, int iIndex);
  • col:颜色。当绘制透明时,此参数无效。
  • iIndex:要设置的颜色的索引。必须是 GDIBORDER_COLOR_START GDIBORDER_COLOR_END。请参阅 SetBorderStyle
    如果使用 chrome 样式,此方法无效。
Color GetColor( int iIndex );

返回当前的边框颜色。

  • iIndex:要设置的颜色的索引。必须是 GDIBORDER_COLOR_START GDIBORDER_COLOR_END。请参阅 SetBoderStyle

兼容性

此控件是在 VS2005 下开发的,但应与 VS6 以及 VS20008 和 2010 兼容。

操作系统兼容性

此控件与 Windows 2000、Windows XP、Windows Vista、Windows 7(已测试)兼容,并应与 Window Mobile 6(未测试)兼容。

重要:在 Windows 2000 下,您必须将 GdiPlus.dll 文件复制到程序目录。您可以在网上轻松找到此 DLL。

历史

  • 版本 1.0
    • 初始版本
  • 版本 1.1
    • 添加了边框
    • 字体矩阵支持 256 个字符
  • 版本 1.2
    • VC6 兼容
    • 静态 DLL 项目兼容
    • 修复了 SetWindowText 的错误
© . All rights reserved.