MFC/GDI+ LCD 控件






4.97/5 (109投票s)
基于 CStatic 和 GDI+ 库的 7/16 段 LCD 控件

引言
我是一名工业开发软件主管;因此,我需要能够清晰显示值的控件。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。实现控件
- 将所有 .h 和 .cpp 文件插入到您的项目中。
- 将 Font5x7.bmp 文件作为位图资源插入。
- 在您的对话框资源中添加一个静态控件。
- 为此静态控件添加一个成员变量。
- 修改变量声明。
更改此项
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 矩阵文件格式
矩阵存储在位图文件中。我选择此格式是因为 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)(白色),则禁用光泽效果。
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()
方法。
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
,此方法将不起作用。
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
,则立即重绘控件。
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:无边框
BoderStyle GetStyle();
返回当前的边框样式。
void SetShape(BorderShape Shape, int round = 0);
Shape
:设置边框的形状。- Rectangle
- 圆
- 椭圆
- RoundRect
round
:圆角控件。此参数仅用于RoundRect
样式。边框的大小(像素)。如果为0
,则不绘制边框。
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(未测试)兼容。
历史
- 版本 1.0
- 初始版本
- 版本 1.1
- 添加了边框
- 字体矩阵支持 256 个字符
- 版本 1.2
- VC6 兼容
- 静态 DLL 项目兼容
- 修复了
SetWindowText
的错误