CRangeSlider - 用于选择范围或间隔的控件





5.00/5 (16投票s)
您是否曾寻找一种便捷的方式来选择一个区间中的子范围?这可能是您想要的解决方案。
引言
您是否曾寻找一种便捷的方式来选择一个区间中的子范围?是的?您是否阅读过 Ben Shneiderman 的《Designing the user Interface》或见过 Spotfire?没有?好吧,那也没关系,因为这个控件就像其中描述和使用的一样。
用户可以通过滑动左右箭头来限制 [Min, Max] 区间内的范围,或者通过单击并拖动区间本身来选择一个区间。
此外,该控件还可以显示另一个区间,该区间用黄色绘制在主区间内,例如,显示您实际在其他地方显示的值的范围。
您可以水平或垂直方向使用该控件,为了更灵活,您可以交换左右箭头的含义。
通用用法
0. 添加源文件
作为第 0 步,将必要的源文件添加到您的项目中。RangeSlider.h
RangeSlider.cpp
MemDC.h
1. 创建成员变量
然后在您的某个项目类中创建一个成员变量。CRangeSlider c_RangeSlider;in one of your projects classes.
2. 初始化和创建
在您的对话框或窗体视图模板中添加一个“自定义控件”。使用“MFCRangeSlider”作为窗口类(不带引号)。您需要在类的DoDataExchange
中添加一行代码:DDX_Control(pDX, IDC_YOURID, c_RangeSlider);
在 OnInitialUpdate
或 OnInitDialog
中添加代码来初始化控件。
// Set Minimum and Maximum. c_RangeSlider.SetMinMax(m_Min,m_Max); // Set Left and Right Arrows c_RangeSlider.SetRange(m_Left,m_Right); // Set "Visual" range. c_RangeSlider.SetVisualMinMax(m_VisualMin, m_VisualMax);
或者,您也可以在 OnInitDialog
或 OnInitialUpdate
中创建和定位控件。
CRect rc (10,10,300,30); c_RangeSlider.Create(WS_CHILD |WS_VISIBLE|PBS_SMOOTH| WS_TABSTOP , rc, this, IDC_YOURID);
3. 响应更改
如果用户更改了箭头的位置,父窗口将收到一个已注册的窗口消息RANGE_CHANGED
,因此请将以下代码添加到父窗口的消息映射中:ON_REGISTERED_MESSAGE(RANGE_CHANGED, OnRangeChange)并在消息处理程序中读出新的位置。
LRESULT CRangeCtrlDlg::OnRangeChange(WPARAM /* wParam */, LPARAM /* lParam */) { c_RangeSlider.GetRange(m_Left, m_Right); // // Do what you have to do. // ... // return static_cast<LRESULT>(0); }
CRangeSlider API
void Create(DWORD dwStyle, const RECT &rect, CWnd *pParentWnd, UINT nID, CCreateContext *pContext = NULL);
在给定的位置、父窗口等创建窗口(所有这些都是 CWnd::Create
的功能)。
// Intervall [Min, Max] of Slider. void SetMinMax(double min, double max); // Set Interval void GetMinMax(double &min, double &max); // Get Interval double GetMin(void); // Read out Min double GetMax(void); // Read out Max设置或读取控件左右边缘的值,即箭头位置将在此区间内。请注意,如果提供的顺序错误,控件会自动交换它们(因此
min
应小于 max
)。如果箭头位置不适合给定的区间,它们的设置值将发生改变。// Intervall [Left, Right] of Slider void SetRange(double left, double right); // Set selected Range in [min, max] double GetLeft(void); // Get Position of Left arrow double GetRight(void); // Get Position of Right arrow void GetRange(double &left, double &right); // Get Left and Right
设置箭头的位置。调用此函数后,位置将有效,即如果您提供 left > right
的值,则位置将被设置为有效值;如果您提供超出 [min, max] 的值,则值将被限制在此区间内。
读出左右箭头的当前位置。
// Intervall [VisualMin, VisualMax] void SetVisualMinMax(double VisualMin, double VisualMax); // Set Intervall double GetVisualMinMax(double &VisualMin, double &VisualMax); // Read Intervall double GetVisualMin(void); // Read VisualMin double GetVisualMax(void); // Read VisualMax
设置“可视”范围的值。如果您提供的区间不在 [min, max] 内,“可视”范围将进行调整。请注意,您必须通过调用 SetVisualMode
来启用显示。
读出“可视”范围的值。请注意,您必须通过调用 SetVisualMode
来启用“可视”范围的显示。
调式
// Visual Mode void SetVisualMode(BOOL bVisualMinMax = TRUE); BOOL GetVisualMode(void) { return m_bVisualMinMax; };设置和读取“VisualMode”的状态。切换可视范围的显示。
// Vertical Mode void SetVerticalMode(BOOL bVerticalMode = TRUE); BOOL GetVerticalMode(void);设置垂直模式,如果滑块应显示为垂直(类似于水平或垂直的
ProgressCtrl
)。您需要自行处理窗口的位置和方向。// Inverted Mode void SetInvertedMode(BOOL bInvertedMode = TRUE); BOOL GetInvertedMode(void); If you set InvertedMode, Left and Right of the Control will be exchanged. So the Left button then controls the value of "right" and vice versa.
RANGE_CHANGED
消息
lParam
未使用。在 wParam
中,您将获得以下枚举值之一:
enum _RangeMessages {
RS_LEFTCHANGED,
RS_RIGHTCHANGED,
RS_BOTHCHANGED,
};
指示哪个位置已更改。如果您在消息处理程序中调用 SetMinMax
,可能会向父窗口发送新的 RANGE_CHANGED
消息,因此请注意无限循环和堆栈溢出。如果您调用 SetRange
,则不会发送此消息。通常,您应该更新显示并设置新的“可视”范围。待办事项
- 将所有颜色设置为配置选项。
- 目前,整个窗口都被控件填充。它应该将其限制在一个合理的深度内。
许可证
您可以选择使用 BSD 许可证(不包含广告条款)或 GPL V2 或更高版本(参见 CRangeSlider.cpp)。历史
日期 |
更改 |
---|---|
2002-04-05 | 在演示中,反馈和可视范围模式现在默认启用。 |
2002-03-18 | 在第一次按下鼠标左键时进行拖动。(感谢 AnthonyJ)。更改了键盘交互算法(现在可以达到 Min 或 Max)。 |
2002-03-11 | 修复了键盘处理中的错误。3D 按钮现在处于按下状态。有一个反馈循环演示了 VisualRange。 |
2002-03-08 | 添加了垂直模式。箭头宽度已计算。您可以反转左右箭头。箭头现在是 3D 的。 |
2002-03-07 | 支持资源编辑器中的“自定义控件”。键盘交互。 |
2002-03-06 | 在 OnPaint 中移除了(?)资源分配问题。 |
2002-02-28 | 首次发布到 codeproject。 |
致谢
此代码使用了 Keith Rule 的CMemDC
类进行无闪烁绘图(它在 CMemDC.h 中)。