日历






4.67/5 (8投票s)
2004年2月9日
11分钟阅读

83978

3864
适用于WinXP+的托盘日历(取代MirandaPlanner)。
引言
我制作了一个用于日常使用的日历。这是我能写得最短的描述了。我很清楚我们已经有了Outlook和数十个类似的软件;它们都有一个共同的特点:功能太多。我的设想是,并且一直是将其精简到绝对最小值,砍掉几乎所有的控件、窗口、DLL和数百万个文件,只留下真正需要的东西,因为我们和其他人只会使用我们真正需要的东西,而平均需求量其实非常小(确实如此!)。换句话说,让我们砍掉所有花哨的东西,拥有一款文字处理器,让我们能够专注于重要的事情——内容和漂亮的字体,而不是3D动画,或者像本例中的笔记、日期、时间等。在这种情况下,当我需要日历时,我不想去想“日历”这个词。这是我的信条。
大局观
这篇文章最初在CodeProject上名为Miranda,后来改名为MirandaPlanner。这给我带来了一些意想不到的问题,并且收到的邮件也告知我一些我之前不知道的Miranda产品,从某种意义上说侵犯了他们的权益。我辩称这并非我的本意,并将名称改为MirandaPlanner。但人们仍然给我写不那么友好的邮件——因此,我将其改名为现在的名字,即Calendar,希望这次不再冒犯任何人(命名对我来说不是什么重要的事情,几乎微不足道)。此外,我认为这个改变也符合我极简的信条。所以,首先,文章的名称从MirandaPlanner改为了Calendar——在此文本发布之时,程序本身也一并改名,以免我和其他人混淆。我已经请求从CP中删除MirandaPlanner。
这个项目也是我在业余时间玩的一个小玩意。我会添加我需要的功能,并且我认为自己是普通的日历用户。所以,我需要的东西,以及你们大家认为应该加入的东西,只要不画蛇添足,我都愿意添加。我认为这是一个长期的过程。
从(MFC-)编程的角度来看,这个项目中没有太多值得您学习的东西——我猜想想要看我如何滑动窗口、编写托盘程序和自定义绘制按钮的程序员可以从中获得一些想法。但不会有什么重大的技术突破。这也不是我的初衷。在编写这些内容时,我考虑的是整体的内部/外部设计以及我如何与用户交互。目前的程序代码量约为6000行,并且每周、每月都在增长,我正密切关注其质量是否也随之提高。项目树中的文件数量也保持得很少——我认为在10到20个之间。
详细说明
我最初使用的是MS VS 6.0+,然后迁移到了MS VS 7.0的beta版,两者都运行在Win2K上。大约4-5个月前,我迁移到了我现在的平台:MS VS 7.0.9466,运行在WinXP Pro上。我认为在继续之前,这一点对你们中的一些人很重要——它让一些人产生了误解,认为它仍然兼容MS VS 6.0,但由于一些我记不清技术细节的奇怪模板问题,它实际上不再兼容了。所以您必须运行.NET版本的MS VS(抱歉)。
正如你们已经知道的,这是一个MFC项目。首先,请记住它完全围绕按钮构建——关键词是“按钮”。
内部剖析。
本节与功能解释结合在一起。
当您第一次打开项目时,请打开calendar_framewnd.h/cpp。其中有一个名为CCalFrameWnd
的类,它继承自CFrameWnd
。这是框架窗口,也是日历本身的宿主。可以将其想象成带有按钮的滑动板。该板最多可容纳6 * 7个日历按钮,以确保无论月份如何奇怪,都能容纳下。对于日历来说,日期是最重要的,所以我先从日期开始:-)。此外,左侧还有6列星期,显示一年的周数(对我们欧洲人来说这很重要,但我认为对美国用户来说不太重要)。如果您不熟悉周数,可以将其理解为从1到52的年度周的序号,以1月1日为第一周(有关更详细的解释,请参见timeex.h/cpp和Outlook,以及网络上的其他地方,就像我制作它时一样)。我不是时间编程领域的专家——只是我的一些看法——好的,回到按钮。最上面是一个宽按钮,显示月份和年份,下面有5个用于时间浏览的按钮(从左到右)。
- 按<<: 返回上一个月(该月的1日)。
- 按<< + Ctrl: 返回上一年(该年的1月1日)。
- 按<: 返回前一天。
- 按< + Ctrl: 返回上一周。
- 按[]: 转到当前时间(=现在)。
- 按>: 前进一天。
- 按> + Ctrl: 前进一周。
- 按>>: 前进一个月(该月的1日)。
- 按>> + Ctrl: 前进一年(该年的1月1日)。
这解释了一半的日历功能。在(富文本)编辑框正上方,有三个按钮,一个作为消息栏,两个用于浏览笔记(稍后将详细介绍笔记)。消息栏的功能尚不完善。鼠标离开按钮后,文本仍会保留在此处,显示提示信息。我不知道确切如何处理这个问题,而不让“鼠标是否已离开”的间隔时间缩短——例如10毫秒,但这并不理想。我需要稍后解决这个问题,在此期间您只能暂时忍受。
一个CCalEdit
占据了近一半的空间。这个类也像按钮类一样,是MFC类的特化——在本例中是CRichEdit
。您可以在这里为某一天写文本,这就是笔记。一天可以有一个笔记。也就是说,可以有一个或没有,不能有多个。笔记是以文件的形式保存在名为“notes”的库中的,有笔记的日期会显示一个黄色复选标记。当日期改变时,文本会被流式输出,如果新日期有笔记,则新的文本会被流式输入。笔记,或者其中的文本,都保存在文件中,而不是保存在数组CSingletonArrayEx<CNote, CNote> *m_pArray_Notes
中。而这个数组实际上是CCalFrameWnd
的一个嵌套类CCalendar
的成员。该数组负责处理笔记的名称,并且所有名称都是唯一的,因为它们是由yyyy.mm.dd.txt组成的。
在将文本粘贴到编辑框时,它会只粘贴文本而不会粘贴任何格式。请跟踪CCalEdit::SetDefaultCharFormat(...)
的使用。该编辑框可以响应较新鼠标上的滚轮滚动。
所以, picture 是笔记始终是小对象,因为它们是名为CNote
的类的实例。唯一可能增长的是笔记库中文件的大小和数量。时间,以及前进和后退时间的操作由CCalendar
处理——例如,使用Go2_SpecificDay()
。除了滑动行为和计时器之外,还有很多工作是为了保持事物同步。和 GUI 更新。因此,您会发现大量的刷新和同步功能。
在最底部,有四个按钮。它们是(从左到右):
- “笔记”
- “联系人”
- “工作”
- “提醒”
这最好被视为一个功能组,在当前发布的1.23版本中,我只完成了第一个。这里的“笔记”与日期和日记笔记无关。这是一个通用笔记,因此保存在其自己的库note_cardinal
中。其余的分别是,“联系人”,类似于Outlook的简化版,“工作”,您可以在其中写入从-到时间并查看月度工作统计,“提醒”,一个简单的“当我需要去开会时弹出的窗口”之类的东西:-)。我还没有完全决定前面三个按钮将实现什么功能。我所知道的是,当我按下这个单选组的成员时,我会将CCalEdit
滑下,并显示“工作”的控件组。
这让我想起CCalBtn
也是(相当)特殊的,并且是“为”这个日历目的而制作的。除了是自定义绘制并继承CButton
之外,它还可以作为单选按钮和复选按钮使用。我需要能够精确控制按钮的颜色、字体、边框以及所有功能,所以您会发现一些看起来不太好看的SetColors(...)
成员等等。我觉得我需要再次深入研究细节——但目前为止,它工作得还不错,包括一些过度的设计。
同时请注意,这是一个“托盘应用程序”,它会自动添加到启动文件夹中,并且您可以从托盘图标菜单中控制它。这个菜单并不完美——如果多次按键,菜单可能会损坏。我无法从开发人员那里获得帮助(在CP的其他地方找到)。
这个项目没有resource.h也没有<something>.rc文件。所有控件都是通过编程方式在ResoursesCreate(...)
和Init(...)
中创建的,并在对应的ResourcesDestroy(...)
和UnInit(...)
中销毁。项目中的所有文本和所有重要常量——如颜色和所有默认设置——都可以在calendar.rh中找到。
重要提示:窗口的宽度必须是5和8的倍数,以便在行中的按钮之间不留任何空隙。按钮的高度不重要。
这就是我目前的内部解释。我不知道是否足够(请告诉我)。
已知问题和限制
- 代码缺少DoxyGen注释和HTML文档。
- 托盘菜单存在问题。
- 消息栏会保留旧提示的文本。
- 在按钮类中,以改进简单图形的绘制。
- 1972年至2037年是有效区间(否则在我的机器上会崩溃)。
免责声明
我几乎空白地发布了这篇文章——那是昨天(04年2月9日)。哦,我犯错了,我看到了(更多邮件——谢谢=:-|)。问题是我之前在旧zip文件中混淆了一些愚蠢的东西,而且我太懒了,以至于在上传项目之前没有测试它是否作为一个项目能够正常工作。这就是我如此快速发布文章的原因——抱歉所有新读者。
未来计划
- 在删除笔记和创建新笔记之前创建备份。
想法
- 按“Esc”键隐藏。
- 不同类型的复选标记。
修订历史
MirandaPlanner的历史
- 版本0.990,2003年5月18日。说明:开发平台为W2K SP2,仅在开发机上测试。开发环境为VS 6.0。
- 版本0.991,2003年5月19日。说明:笔记处理(保存/加载)的小幅修复。笔记浏览按钮启用的小幅修复。自动更新计时器的小幅修复。
- 版本1.00,2003年5月20日。说明:全面修复和清理。为按钮类添加了运行时信息,并修复了发布版本的问题。现在鼠标滚轮消息会发送到编辑框,无论哪个子窗口拥有焦点。
- 版本1.01,2003年5月23日。说明:准备支持_UNICODE编译。
- 版本1.10,2003年5月27日。说明:带有笔记的日期的悬停提示(可选功能),更广泛的错误处理。从现在开始,它的新名称是MirandaPlanner。版本号将继续。运行“today”时,自动更新再次修复,使其能自动进入第二天。
- 版本1.11,2003年6月9日。说明:悬停提示的自动清理,粘贴其他
CHARFORMAT
到笔记中时,会保留其原始默认格式(在显示粘贴文本之前完成)。修复了CTimeEx
类中的错误。 - 版本1.20,2003年6月12日。说明:添加了通用笔记(参见“笔记”按钮)。当标记过去日期的笔记时,显示为灰色,标记当前或未来日期的笔记时显示为黄色。全面清理代码。
- 版本1.21,2003年6月16日。说明:修复了窗口隐藏时的保存问题。使笔记浏览的箭头按钮启用保持一致。
- 版本1.23,2004年1月29日。说明:修复了闰年问题。(与Calendar v. 1.00相同)。
Calendar(基于MirandaPlanner)的历史
- 版本1.00,2004年2月10日。说明:更改了部分底部按钮的位置,并将名称更改为Calendar。添加了“联系人”、“工作”和“提醒”的准备工作。删除了“删除”和“删除+”按钮,并将其改为菜单项。