MS Outlook 风格的日期重复模式






4.93/5 (20投票s)
具有类似于 MS Outlook 的用户界面的日期重复模式引擎
致谢
感谢 Keith Rule 提供的 MemDC
类。感谢所有提供反馈和代码的 CP 用户,这些反馈和代码用于我之前发布的 DateEdit 和 MiniCalendar 项目。
关于日期重复模式
许多应用程序都需要能够安排约会、研讨会或申请等。当涉及的日期超过几个时,能够以重复模式安排这些项目是必须的。
我曾寻找过相关的源代码,但对找到的内容不满意。市面上有很多解决方案(可在 Google 上搜索),但我查看过的那些要么不值那个价钱,要么写得不好,要么不能正常工作,要么过于有限。
日期重复模式最大的技术难题在于,存在无数种可能的模式,每种都需要单独编程。大多数重复模式代码(包括我自己的)会选择最常用的几种模式并提供支持。此外,它们很少支持将各种模式组合起来(例如,每月的第一、第三和最后一个星期五)。我的实现基于 MS Outlook,并支持 MS Outlook 中的 7 种模式。此外,我的实现不包括组合模式的支持。
抛开技术问题不谈,事件很少完全按照特定的定义模式发生。经常会出现这样的情况:一个事件原定于星期五,但被重新安排到星期四。此外,假期、休假和其他事件会干扰和修改这些事件的时间安排。我所合作的用户正是出于这个原因而避免使用 MS Outlook 的重复模式。相反,他们会为涉及的各个日期安排单独的约会。这通常是一个繁琐的过程,在某些情况下,容易出错。
关于本实现
如上所述,我的实现基于 MS Outlook。我处理这个项目的方式是提供与 MS Outlook 相同的支持级别作为起点。然后,我审查了各种能够使我受益的增强功能。
我研究了**组合日期模式**的能力,其问题不在于技术层面,而在于用户界面和可用性。用户界面需要看起来和工作起来是什么样的?普通用户能理解吗?我需要提供一个二级用户界面供高级用户使用吗?如果有人设置了组合模式,其他人能理解吗?我决定不实现组合支持,因为我无法充分回答这些问题。我开发的引擎应该能够轻松地容纳组合,假设我(或其他人)能够令人满意地回答这些问题。
我审查的下一个增强功能是在主重复模式中实现**跳过模式**的支持。跳过模式允许自动从生成模式中删除特殊日期(例如,假期、休假等),并自动将适当的日期添加到模式中。例如,“跳过圣诞节,改在下一个星期一举行”。我在核心引擎中实现了对该功能的支持。然而,我还没有开发配套的用户界面,因为这(根据我的用户)优先级较低。我计划在后续版本中添加此功能。
我还审查了为用户提供对模式中包含日期的**精细控制**。这将允许用户从模式中删除特定日期,并将特定日期添加回模式中。在与我的用户合作后,我认为这是最需要提供的功能。我的实现对此提供了支持,并且用户界面提供了一种简单的方式供用户控制模式。
实现概述
CFPSRecurringDates
类提供了核心日期模式生成器支持。这是一个实用类,没有直接的用户界面。提供了访问模式详细信息和修改它的方法。该类公开了一个 Serialize
函数,因此可以轻松地集成到许多项目中。(但是,您可能需要实现支持将配置数据持久化到数据库。)
CPrShtDateRecur
、CPrPgDateRecurBasic
和 CPrPgDateRecurPreview
类提供了用于操作模式引擎的用户界面。这些类需要 IDD_DATE_RECUR_BASIC
、IDD_DATE_RECUR_PREVIEW
和 IDB_RECUR_IMAGES
资源对象。
此外,我还使用了之前开发的迷你日历控件和日期编辑/选择控件。这些项目可在 Code Project 上找到,在此处和在此处。
入门
将重复日期支持添加到您的项目中
-
复制下面列出的 .cpp 和 .h 文件,并将它们包含在您的项目中。
FPSDatePickerCtrl.h FPSDatePickerCtrl.cpp FPSDateTimeButtonCtrl.h FPSDateTimeButtonCtrl.cpp FPSDateTimeCtrl.h FPSDateTimeCtrl.cpp FPSDateTimePopupCtrl.h FPSDateTimePopupCtrl.cpp FPSMiniCalendarCtrl.h FPSMiniCalendarCtrl.cpp FPSMiniCalendarListCtrl.h FPSMiniCalendarListCtrl.cpp FPSRecurringDates.h FPSRecurringDates.cpp MemDC.h OleDateTimeEx.h OleDateTimeEx.cpp PrPgDateRecurPreview.h PrPgDateRecurPreview.cpp PrShtDateRecur.h PrShtDateRecur.cpp PrShtDateRecurBasic.h PrShtDateRecurBasic.cpp -
从 DateRecur.rc 文件(在演示项目中)复制
IDD_DATE_RECUR_BASIC
、IDD_DATE_RECUR_PREVIEW
、IDB_RECUR_IMAGE
和IDB_DATEPICKER_BUTTON
资源到您的项目中。
实现细节
CFPSRecurringDates
核心日期重复引擎。
重要方法
GeneratePattern(CPtrList& List)
调用此函数来执行重复模式并检索结果集。
如果日期模式配置为无结束日期,则此函数只会生成模式中的前 31 个出现。如果这不够,您需要使用其他GeneratePattern
函数之一。GeneratePattern(CPtrList& List, COleDateTime& dtEndBy)
调用此函数来执行重复模式,并检索直到 dtEndBy
参数指定的截止日期为止的结果集。GeneratePattern(CPtrList& List, int iMaxOccurences)
调用此函数来执行重复模式,并检索直到指定的最大出现次数的截止日期为止的结果集。 CleanupDateList(CPtrList &List)
GeneratePattern
函数接受一个CPtrList&
参数,并用指向COleDateTime
对象的指针填充它。在列表被销毁之前,有必要清理该列表。IsDateInPattern(COleDateTime& dtCheck)
调用此函数以确定指定日期是否存在于模式中。
此版本的函数用于低频率检查(例如,一次或两次),但不应用于循环中,因为它可能非常慢,因为它必须在每次调用时重新生成模式。IsDateInPattern(CPtrList& List, COleDateTime &dtCheck)
调用此函数以确定指定日期是否存在于先前生成并存储在 List
中的模式中。
与前一个版本相比,此版本在性能上更优。
持续开发
本项目仍在开发中,但我发布的代码已经过测试,并且在我所知范围内能正常工作。
我目前正在努力将跳过模式的支持集成到用户界面中。此外,我还将核心引擎封装成了一个 COM 组件,并添加了数据库持久化支持。此工作是为了实现 ASP(以及可能的 ASP.NET)版本的用户界面。一旦我完成了 ASP(ASP.NET?)版本的项目,我将把它发布到 Code Project。
我还在与该组件的用户合作,以确定还需要哪些其他功能/增强功能。我不知道这会揭示什么,但如果存在重大更改,我将把它们发布到 Code Project。
注释
您可以自由地在您的项目中使用此代码,无论是个人项目还是专业项目。它可以用于免费软件、共享软件或商业软件,无需许可费等。此代码按“原样”提供,可能会导致宇宙崩溃,因此请谨慎使用。对于由此崩溃的任何结果,我概不负责。我唯一的要求是您在您的应用程序的致谢中包含我的名字,并且在源代码中保留标题注释。
变更历史
2002年4月20日 | 感谢 Neville Franks 识别出数值输入方式存在的问题。 此外,感谢 Martin Bohring 指出了某些本地化问题。
|
2002年4月22日 | 感谢 Michael A. Barnhart 提出了一个新的月度模式。
|
2002年4月23日 | 感谢 Michael A. Barnhart 发现了涉及 2 个组合框中重复条目的错误。 感谢 Kwakkie 指出了由于本地化问题(我的懒惰)导致的年模式问题。此外,时间组合框未正确填充(同样是本地化问题),并且无法使用数字键盘输入数字字段。
|