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

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (16投票s)

2002年2月28日

CC (ASA 3U)

4分钟阅读

viewsIcon

209148

downloadIcon

5287

您是否曾寻找一种便捷的方式来选择一个区间中的子范围?这可能是您想要的解决方案。

Sample Image - CRangeSlider.gif

引言

您是否曾寻找一种便捷的方式来选择一个区间中的子范围?是的?您是否阅读过 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);

OnInitialUpdateOnInitDialog 中添加代码来初始化控件。

    // 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);

或者,您也可以在 OnInitDialogOnInitialUpdate 中创建和定位控件。

  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 中)。
© . All rights reserved.