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

使用WTL的时间轴控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.56/5 (16投票s)

2003年5月24日

3分钟阅读

viewsIcon

208771

downloadIcon

4242

选择日期范围的另一种方法。

Screen shot

引言

CTimeLineCtrl 提供了一种选择定期重复日期范围的替代方法。

特点

  • 以不同的粒度(例如,周、月、年)单击选择日期范围
  • 突出显示今天日期
  • 年份数字保持可见
  • 显示n个所需顺序的“日期范围带”
  • 可以设置滚动限制

在 WTL 应用程序中使用 CTimeLineCtrl

此控件是使用 VS.NET、WTL 7 和 2003 年 2 月的 Platform SDK 开发的。 它只在 WindowsXP 下测试过。

在你的应用程序中使用 CTimeLineCtrl

  1. 将以下文件复制到你的应用程序目录:
    • atlgdix.h (它包含在 zip 文件中,但你也可以从这里下载)
    • TimeLineScroll.h
    • TimeLineCtrl.cpp
    • TimeLineCtrl.h
    • TimeLineBand.cpp
    • TimeLineBand.h

    如果要使用YearMonthWeek带,还要添加以下文件:
    • TimeLineBandImpl.cpp
    • TimeLineBandImpl.h
       
  2. 将这些文件添加到你的项目。
  3. 如果尚未在使用它们,请将 <atlcomtime.h> 和 <atltypes.h> 添加到你的 <stdafx.h> 文件。
  4. 在父窗口类定义之前插入 #include "TimeLineCtrl.h"
  5. 向父窗口类添加一个新的成员变量。 类将是 CTimeLineCtrl - 随意命名。
  6. 在适当的位置(例如 OnCreateOnInitDialog)添加代码以创建控件窗口。
这是一个如何创建控件的示例。
LRESULT
CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, 
LPARAM /*lParam*/, BOOL& /*bHandled*/) { ... m_wndTimeLine.Create(m_hWnd, 0, 0, WS_CHILD | WS_VISIBLE | WS_HSCROLL, WS_EX_STATICEDGE, IDC_TIMELINE); m_wndTimeLine.AutoPosition(); // Position the control at the
// bottom of the parent window.
... }

你也可以将 m_wndTimeLine.AutoPosition() 添加到你的 OnSize 处理程序中,以使控件保持在父窗口的顶部或底部。

实现细节

此控件是使用几个类的组合来实现的

CTimeLineScroll<T>

这是一个 mix-in 类,用于处理 WM_HSCROLL 消息。 如果你需要管理通过一系列日期的滚动,你可以单独使用这个类。 例如

class CMyWindow :
    public CWindowImpl<CMyWindow>
    public CTimeLineScroll<CMyWindow>
{
    ...
    BEGIN_MSG_MAP(CMyWindow)
      ...
      CHAIN_MSG_MAP(CTimeLineScroll<CMyWindow>)
    END_MSG_MAP()
    ...
    // Handle the scroll request here.

    void DoScroll(int cxDelta);
};

CTimeLineBand

这是 CTimeLineCtrl 用于处理日期范围渲染和选择的抽象基类。

我包含了年、月和周范围的实现(即 CTimeLineYearBandCTimeLineMonthBandCTimeLineWeekBand)。 如果你想添加自己的自定义日期范围带,这些有望为你提供一个良好的起点。

请注意,在这个设计中,这些类是内部实现类,供 CTimeLineCtrl 使用。 CTimeLineCtrl 的用户无需知道它们的存在。

CTimeLineCtrl

这是一个 CWindowImpl 派生类,它充当 CTimeLineBand 派生类的实例的宿主。 它混合了 CTimeLineScroll 以处理 WM_HSCROLL,并将渲染请求委托给其带的集合。

带的集合保存在 std::deque 中。 带在控件中显示的顺序遵循此集合中带的排序。

顺便说一句,在这个实现中,我选择在堆上创建不同的带(更喜欢将带的实现细节对控件的用户隐藏)。 稍作更改,你可以将它们作为此(或派生)控件的成员变量。 如果你这样做,请确保修改 OnDestroy 中的内存管理代码。

这是一个向 CTimeLineCtrl 添加带的示例

LRESULT
CTimeLineCtrl::OnCreate(LPCREATESTRUCT /*lpcs*/)
{
    ...
    AddBand(new CTimeLineWeekBand(*this));
    ...
}

尽情享用!

致谢

  • Bjarke Viksoe - atlgdix.h (用于无闪烁绘图)
© . All rights reserved.