Windows XP 平板电脑版Visual Studio 6Windows VistaWindows 2003Win32Windows 2000设计 / 图形Visual C++ 6.0Windows XPMFC中级开发Visual StudioWindowsC++
七段数码管控件
从 CWnd 和 CStatic 派生的简单七段数码管控件
引言
这个控件就像数字时钟或嵌入式系统中的七段液晶显示器。
背景
我想创建一个简单的控件,通过在数字上拖动鼠标来快速设置日期/时间。很明显,要让它看起来像一个数字时钟。我还希望它易于使用和部署,例如,无需安装额外的字体,或为可执行文件进行特殊安装。

Using the Code
Clcd7
类是其核心。演示应用程序包含一个功能齐全的时间设置演示控件,其中液晶显示器可用于设置时间(应用程序本身只是将结果放入编辑框中)。
//
// The control is easy to use. Just create a Static Control in the Dialog Editor,
// rename its ID to something other then IDC_STATIC. Add a variable with class
// wizard and rename the declaration in your header from CStatic to Clcd7
//
Clcd7 hour1, hour2;
Clcd7 minute1, minute2;
In the IntDialog() function of the parent, you may set operational parameters such as:
m_lcd.SetBgColor(RGB(192, 192, 192));
m_lcd.SetFgColor(RGB(12, 12, 12)); //use your colors
// The LCD will send the following messages to your dialog (its parent)
#define WM_OVERFLOW (WM_USER + 1)
#define WM_UNDERFLOW (WM_USER + 2)
#define WM_TCHANGE (WM_USER + 3)
(make sure the messages are unique in your app, or us RegWndMsg)
To capture these messages use:
BEGIN_MESSAGE_MAP(CTimectrlDlg, CDialog)
//{{AFX_MSG_MAP(CTimectrlDlg)
......
ON_MESSAGE(WM_TCHANGE, lcd_change)
......
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
To capture the message:
void CTimectrlDlg::lcd_change(WORD wparam, LONG lparam)
{
TRACE("lcd change on %d\r\n", wparam);
}
wparam
包含发送消息的 LCD 的控件 ID。
关注点
我使用 Windows 消息机制在 LCD 发生更改时发送消息。这允许一个非常简单的代码来更新 UI 反馈并更新镜像当前数字的编辑框。
下溢或溢出消息可以用于非常简单地将多个 LCD 连接在一起。原理如下:
如果 LCD1 发送溢出消息 -> 递增 LCD2 .....
if(pMsg->message == WM_OVERFLOW)
{
TRACE("CTimectrlDlg::PreTranslateMessage WM_OVERFLOW on %d\r\n", pMsg->wParam);
if(pMsg->wParam == CONTROL_FOR_LOWER_DIGIT)
{
// m_lcd2 is the CONTROL_FOR_HIGHER_DIGIT
m_lcd2.num++;
m_lcd.Invaldate();
}
}
UNDERFLOW 也可以这样做。当调用 Invalidate()
时,如果发生溢出,控件可能会发送消息。这允许级联多个 LCD。
要将 LCD 设置为十六进制模式,请使用
// Hex Mode:
SetMinMax(0, 15);
// Dec Mode:
SetMinMax(0, 9);

我还安排了设置控件的参数,这对其 Windows 创建状态很敏感。这样,可以在预创建状态下设置参数,而不会因 ASSERT 而炸毁整个东西。
Here is a snippet how:
void Clcd7::SetBgColor(COLORREF col)
{
bg = col;
if(::IsWindow(m_hWnd))
Invalidate();
}
该控件演示的旧版本

历史
- 2008 年 1 月 16 日:首次发布
- 2008 年 1 月 18 日:添加了源代码的清理版本(清理了*.obj等)
值得注意的地方
我尝试使用 LCD 字体作为控件的显示。虽然显示字体很容易,但对字体进行点击测试、缩放和放大却更难。:(冒号)的位置不对,间隙没有像需要的那么好地放大,并且无法使线条变细或变粗。因此采用了自定义 LCD。一个很酷的副作用是它可以在透明环境中使用。
感谢阅读。