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

七段数码管控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (11投票s)

2008年1月16日

CPOL

2分钟阅读

viewsIcon

88519

downloadIcon

6023

从 CWnd 和 CStatic 派生的简单七段数码管控件

引言

这个控件就像数字时钟或嵌入式系统中的七段液晶显示器。

背景

我想创建一个简单的控件,通过在数字上拖动鼠标来快速设置日期/时间。很明显,要让它看起来像一个数字时钟。我还希望它易于使用和部署,例如,无需安装额外的字体,或为可执行文件进行特殊安装。

new-4.jpg

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);
new-3.jpg

我还安排了设置控件的参数,这对其 Windows 创建状态很敏感。这样,可以在预创建状态下设置参数,而不会因 ASSERT 而炸毁整个东西。

Here is a snippet how:

void Clcd7::SetBgColor(COLORREF col)
{
    bg = col;

    if(::IsWindow(m_hWnd))
        Invalidate();
}

该控件演示的旧版本

new-2.jpg

历史

  • 2008 年 1 月 16 日:首次发布
  • 2008 年 1 月 18 日:添加了源代码的清理版本(清理了*.obj等)

值得注意的地方

我尝试使用 LCD 字体作为控件的显示。虽然显示字体很容易,但对字体进行点击测试、缩放和放大却更难。:(冒号)的位置不对,间隙没有像需要的那么好地放大,并且无法使线条变细或变粗。因此采用了自定义 LCD。一个很酷的副作用是它可以在透明环境中使用。

感谢阅读。

七段 LCD 控制 - CodeProject - 代码之家
© . All rights reserved.