表的内容
- 动机
- 环境使用
- 将LED按钮文件和资源添加到项目中
- 一个简单的LED按钮
- 一个多状态LED按钮
- 活动LED按钮
- A条件LED按钮
- 文本属性
- 工具提示
- 代码文档
- 提供文件
- 免责声明
- 使用条款
- 更新日志
动机
写这个CLedButton控件的动机是有一个LED控件,即:
- 只读了控制。
- 能够处理传统的两国关系之外的问题。
- 能够发出“活动”信号(在可控超时后自动关闭)。
- 能够控制从一种状态到另一种状态的转换。(从一种状态到另一种状态的转换由外部控制。)
- 使用从资源文件加载的LED图标。
- 无闪烁的控制。
两年前,我在CodeProject和SourceForge中寻找一个可以满足我的五个需求的静态控件或按钮控件,但是我没有找到,所以我决定自己构建一个。
我从这个伟大的网站上展示的以下控件中获得了灵感:
- 第一个候选是Benjamin Mayrargue[^]发布的CLedButton[^],它给了我使用复选框(CBbutton作为基类)作为控件的想法。
- 然后我看到了VGirish的动态LED控制,但也缺少一些我想要的功能。
- 保罗·梅西纳(Paolo Messina)的COddButton给了我使用自画按钮的想法。
- 然后Davide Calabro[^]在他的神奇的CButtonST[^]中为我提供了实现LED按钮控制所需的其余背景。
有了这个背景,两年前我开始定制我自己的CLedButton控件。从一个项目到另一个项目,代码得到了增强和简化,直到它变得成熟和健壮,可以在这里发布。
环境使用
LED按钮最初是用VC 6.0 (Visual Studio c++ 6.0)开发的,现在我用的是VC 7.1 (Visual Studio c++ . net 2003)。我将“尝试”提供适用于这两个版本的说明。
将LED按钮文件和资源添加到项目中
确保你有以下文件:
- 此控件的来源:LedButton.h和LedButton。cpp,将它们复制到项目目录中。
- 您想要使用的LED图标文件。(你可以使用我提供的演示中的那些。)将它们复制到项目资源目录(res子目录)。
在您的开发环境中打开您的项目,并遵循以下步骤:
- 将LedButton.h和LedButton.cpp文件添加到项目中。
- 使用资源编辑器,在对话框中添加一个复选框,将其ID更改为IDC_LED_CHECK。你也可以改变这个复选框的属性,相关的属性是:左文本,多行,水平对齐,垂直对齐,右对齐文本。
- 使用资源编辑器导入图标文件,将id分别命名为IDI_GRAY_ICON、IDI_GREEN_ICON、IDI_YELLOW_ICON、IDI_RED_ICON和IDI_BLUE_ICON。
- 使用ClassWizard添加名为m_ledCtrl的成员变量作为控制变量。(生成的类型为CButton,稍后会更改)。
- 在对话框头文件中将LED按钮控件的类型从CButton更改为CLedButton。
- 添加预处理器#include“LedButton”。h"的头文件,以及。
对话头文件应该包含:
... #include "LedButton.h" ... class DemoDlg : public CDialog { ... private: ... CLedButton m_ledCtrl; };
对话框实现文件应该包含:
void CDemoDlg::DoDataExchange(CDataExchange* pDX) { ... DDX_Control(pDX, IDC_LED_CHECK, m_ledCtrl); ... }
现在是初始化和配置LED按钮的时候了。
一个简单的LED按钮
默认情况下,创建的CLedButton控件有两个LedStates,你只需要设置图标,每个状态一个,然后根据你的需要设置LedState。
为了方便起见,可以定义用于描述每种状态的枚举类型。关闭状态的整数值为0,打开状态的值为1,或使用Afx FALSE和TRUE #定义,或使用LED按钮自己预定义的值LED_BUTTON_STATE_OFF或LED_BUTTON_STATE_ON。
在InitDialog()方法中添加以下代码:
... m_ledCtrl.SetIcons(IDI_GRAY_ICON, IDI_YELLOW_ICON); ...
LED按钮的默认状态是LED_BUTTON_STATE_OFF。
如果你想改变图标的默认大小,你不能使用SetIcons(),相反,调用SetIcon()方法为每个LED状态:
... m_ledCtrl.SetIcon(LED_BUTTON_STATE_OFF, IDI_GRAY_ICON, 14,14); m_ledCtrl.SetIcon(LED_BUTTON_STATE_ON, IDI_YELLOW_ICON, 14,14); ...
每次您想要改变LED的颜色时,只需调用SetLedState()方法来显示新的LED状态。
... // Turn the Led ON m_ledCtrl.SetLedState(LED_BUTTON_STATE_ON); ...
如果你不想要一个更复杂的LED按钮,这就是全部。
如果在与LED当前显示的LED状态相同的情况下调用该方法,则SetLedState()不会执行任何操作。(这样做是为了减少闪烁)
一个多状态LED按钮
多状态LED按钮就像一个简单的LED,但有两个以上的LED状态。
定义一个枚举类型来表示每个LED状态可能是符合逻辑的,尽管这不是强制性的。
在本文档中,让我们定义一个名为EMyLedState的枚举类型,用于多状态LED按钮,如下所示:
... enum EMyLedState { GRAY_LED_STATE = LED_BUTTON_STATE_ON, // Initial LedState GREEN_LED_STATE, YELLOW_LED_STATE, RED_LED_STATE, BLUE_LED_STATE, MY_LED_STATES_SENTINEL // Not to be used as a EMyLedState. }; ...
MY_LED_STATES_SENTINEL是我们将使用的LED状态的数量。
多状态LED按钮的初始化要求在为每个状态设置图标之前,调用SetLedStatesNumber()方法来设置LED状态的最大数量。
InitDialog()中的代码变成:
... m_ledCtrl.SetLedStatesNumber(MY_LED_STATES_SENTINEL); m_ledCtrl.SetIcon(GRAY_LED_STATE, IDI_GRAY_ICON); m_ledCtrl.SetIcon(GREEN_LED_STATE, IDI_GREEN_ICON); m_ledCtrl.SetIcon(YELLOW_LED_STATE, IDI_YELLOW_ICON); m_ledCtrl.SetIcon(RED_LED_STATE, IDI_RED_ICON); m_ledCtrl.SetIcon(BLUE_LED_STATE, IDI_BLUE_ICON); ...
状态设置与以前相同,但是现在可能的值是从GRAY_LED_STATE到BLUE_LED_STATE。
活动LED按钮
Activity LED按钮是在可控一段时间后自动关闭的LED按钮,这样用户就不用负责管理关闭时间了。
活动时间由一个内部计时器控制,当LED按钮被设置为除LED_BUTTON_STATE_OFF之外的任何状态时,它就会被触发。当定时器计时结束时,LED按钮关闭。(当定时器计时结束时,LED将停止活动。)
因为计时器是一个有限的全局资源,要激活一个LED按钮,用户应该提供一个timerId来识别计时器。这样,两个或多个Activity LED按钮可以在同一个应用程序中共存,每个按钮都有不同的计时器标识。
要停用一个活动计时器,只需提供一个空的timerId。计时器也被释放时,LED按钮窗口被销毁。
首先,你可能想要管理所有的计时器你使用的代码在一个单独的地方,因此,在一些可见的头文件,定时器标识符:
... #define MY_ACTIVITY_LED_TIMER_ID (WM_USER + 0x123) ...
然后InitDialog()中的代码变成:
... // Simple Led with Activity detection m_ledCtrl.SetIcons(IDI_GRAY_ICON, IDI_YELLOW_ICON); m_ledCtrl.SetLedActivityTimer(MY_ACTIVITY_LED_TIMER_ID, 123); ...
上面的代码将LED设置为持续时间123毫秒的活动LED。
一个简单的,多状态或条件LED按钮也可以是一个活动LED按钮。
A条件LED按钮
为了更好地理解条件LED的状态,让我们来看看下面的情况:
- LED按钮控件能够显示两种以上的状态。
- LED按钮用作故障检测器。
- 一个线程将高速从硬件读取一些数据,等待一些信号的改变。当需要时,它将向GUI发送带有更改通知的通知。
- 当变化为“缓慢”变化时,LED应在“开”和“关”之间正常改变颜色。但是,如果在不到50秒的时间内连续发生两次变化,则LED应该以不同的颜色显示“开”或“关”状态。
下面的状态机可能提供更好的画面:
当LED按钮状态依赖于两个(或更多)输入时,则LED按钮成为条件LED。
对于“故障检测器”,输入如下:
- 当前领导国家。
- 被请求的新LED状态。
- 自上次更换LED以来的经过时间。
为了设置条件LED,您应该从派生自CLedStateCondition(在LedButton.h头文件中定义的一个类)的类中创建一个派生对象。
子类应该覆盖ChangeState()虚方法。
ChangeState()方法接收三个参数:
- newLedState,被请求的新LedState。
- oldLedState,转换前的当前LedState。
- isForcedChange,指示强制转换到newLedState的布尔标志。派生类应该修复它的私有FSM,以反映这种强制更改,并返回newLedState。
ChangeState()应该包含决定LED按钮将进入的新LED状态的所有逻辑。(我不会在这里提供故障检测器的代码,因为我想关注条件LED。)
您可以在某些头文件中定义以下枚举类型来处理故障检测器:
... enum EGlitchDetectorState { OFF_STATE = LED_BUTTON_STATE_ON, // Green LED, ON_STATE, // Yellow LED, GLITCH_OFF_STATE, // Blue LED, GLITCH_ON_STATE, // Red LED, IDLE_STATE, // No LED Icon, GLITCH_DETECTOR_STATES_SENTINEL // Not to be used as a EGlitchDetectorState. }; ...
硬件通知将分别为TRUE和FALSE。
对于本例,CLedStateCondition派生类的名称将是CGlitchDetector。将这个CGlitchDetector的一个实例放在CDemoDlg中,并调用它m_glitchDetector。
对话框InitDialog()的代码可以是:
... // // 1) Initialize the m_glitchDetector as required (code not shown here) // 2) Set the led as a multi-state led. // 3) Add the Glitch Detector to the Led Button. // 4) Set the initial state as IDLE_STATE. (Force this state) // m_ledCtrl.SetLedStatesNumber(GLITCH_DETECTOR_STATES_SENTINEL); m_ledCtrl.SetIcon(OFF_STATE, IDI_GREEN_ICON); m_ledCtrl.SetIcon(ON_STATE, IDI_YELLOW_ICON); m_ledCtrl.SetIcon(GLITCH_ON_STATE, IDI_RED_ICON); m_ledCtrl.SetIcon(GLITCH_OFF_STATE, IDI_BLUE_ICON); m_ledCtrl.SetIcon(IDLE_STATE, 0,0,0); // No Icon on purpose. m_ledCtrl.SetLedStateCondition(&m_glitchDetector); m_ledCtrl.SetLedState(IDLE_STATE, true); // Force IDLE_STATE. ...
在接收硬件通知的代码中,我们将分别使用OFF_STATE或ON_STATE值调用SetLedState()方法。
afx_msg LONG CDemoDlg::OnHWUpdate(WPARAM wparam, LPARAM /*lparam*/) { ... LedState ledState = (TRUE == wparam) ? ON_STATE : OFF_STATE; m_ledCtrl(ledState); ... }
一个简单的,多状态或活动的LED按钮也可以是一个条件LED按钮。
文本属性
可以为每个LED状态更改文本前景色或/和按钮背景色。默认情况下,文本前景色为::GetSysColor(COLOR_BTNTEXT),按钮背景色为::GetSysColor(COLOR_BTNFACE)。
控制LED状态颜色的方法如下:
- SetTextForeground (): 为特定的LED状态设置文本前景色。
- GetTextForeground (): 获取特定LED状态的文本前景色。
- SetTextBackground (): 为特定的LED状态设置文本背景颜色。
- GetTextBackground (): 获取特定LED状态的文本背景颜色。
- SetTextColors (): 为特定的LED状态设置文本前景色和按钮背景色。
- RestoreDefaultColors (): 恢复所有LED状态的默认颜色,请小心使用。
工具提示
这个LED按钮控件可以显示一个“工具提示”,一个小的弹出窗口,显示一些描述LED用途的文本。工具提示在大多数情况下是隐藏的,只有当用户将光标放在LED按钮上并让它停留半秒时才会出现。工具提示出现在光标附近,当用户单击鼠标按钮或将光标移离工具时消失。
以下方法控制工具提示:
- SetTooltipText (): 从资源字符串或提供的文本设置工具提示文本。
- ActivateTooltip (): 激活/禁用工具提示。
在当前版本中,只支持“矩形”工具提示。
代码文档
代码中包含Doxygen注释,用于生成HTML文档的代码。我强烈建议你直接或间接地使用这些工具。
Doxygen是一个针对c++, C, Java, Objective-C, IDL (CORBA和微软风格)的文档系统,在某种程度上,也适用于PHP, c#和d。
辅助帮助文件是使用KingsTools [^] Visual Studio . net插件通过SteveKing[^]生成的。此外接程序包含您可能希望在开发环境中集成的几个有用工具。(Doxygen、代码统计、语法着色等)
感谢SteveKing提供了这个工具,以及我在代码中使用的他的免责声明。
提供文件
在源代码和演示项目中提供了以下文件,您可以在自己的项目上使用:
源文件:LedButton.h和LedButton.cppLED图标文件:13个不同颜色的LED图标。(LedButton_src.zip)灯泡文件:LightBulbOff。ico, LightBulbOn。ico, LightBulbBroken.ico(在演示项目中)免责声明
本代码和随附文件是“按原样”提供的,没有明示或默示保证。不负责可能的损害,或其功能的副作用。用户必须承担使用此代码的全部风险。如果它对你的电脑造成任何损害,使你的宠物生病,使你的秃顶增加,或使你的汽车在你启动它时发出奇怪的噪音,作者不承担责任。这段代码没有bug,只是没有文档化的特性!
使用条款
此代码对于个人使用或免费软件应用程序是免费的。如果您计划在商业或共享软件应用程序中使用此代码,请与作者联系以获得他的许可。
更新日志
DateRev.Description2004/Jan/161.1无闪烁更新(感谢Iain Clarke[^])2004 / 12月/ 251.0在CodeProject上亮相2002 / 8月16——创建后记
希望这个LED控制对你有用。
为了帮助其他使用CodeProject的用户,请对本文进行评价:)
本文转载于:http://www.diyabc.com/frontweb/news14508.html