前言:
控件在Visual C++编程学习中占据很重要的位置。笔者在国外英文网站上看到了这篇关于日历控件学习的文章,虽然内容看似简单,但读完后感觉到还是学到了一些东西。感觉到原著作者对一些不常用的日历控制的使用方法写的介绍的很详细,通俗易懂,于平淡之中显神奇,是对日历控件的"深度挖掘",对VC的初学者应该是很有帮助的,所以就将其翻译过来介绍给国内读者朋友。
一、有关日历控件的介绍 Win32 API提供了一个显示日期得当彩色日历控件,日期的显示模式是基于控制面板中的区域性设置或者说是依赖于用户的操作系统。具体的日历控件如下图一所示:
 图一、日历控件显示效果
|
这个常用的日历控件的标题条包含两个按钮和两个标签,左边的按钮准许用户单击选择前一个月份,左边的标签显示当前选择的月份,右边的标签显示当前日期中的年份。右边的按钮是让用户选择下一个月份。日历控件可以配置成显示多个月份,下图是一具体的实例:
 图二、显示多个月份的日历控件
|
如果要让日历控件显示多个月份,按钮的个数将通过前月或后月列表来增加或减少。例如,如果控件正在显示4月或5月,这时用户点击了左边的按钮,控件将显示3月或4月;如果用户点击了右边的按钮,控件将显示5月和6月。此外,选择当前年份中的任意一个月份,用户可以点击标题框中的月份名,这时候将显示一个月份列表供用户来选择。具体如图所示:
 图三、显示月份列表
|
如果要更改年份,用户可以点击年份标签,这时候将显示旋转按钮,用户可以通过点击旋转按钮的上下键来更改年份,也可以使用键盘上的上下箭头来更改年份。
 图四、更改日历控件的年份
|
在标题条的下面,根据控制面板的格式显示着星期的简写,在英语地区,每个星期的第一天通常是星期天。开发人员可以改变控件中的第一天设置。
控件上,当前选择的日期有一圆圈。用户可以点击欲选择的日期来在控件上选择一个日期。在大部分地区,日期以数字的形式显现在一个白色背景上(这个背景颜色乃至控件上的任何颜色可以通过程序来改变)。默认的情况下,控件显示一个椭圆围绕的当前日期。使用标题条按钮、月份和年份标签,用户可以更改日期。如果控件显示的不是当前日期,用户可以通过点击控件底部显示今天日期的标签来使控件显示今天的日期。(如果你是一个程序员,可以隐藏控件底部这个显示今日日期的标签)。
二、创建日历控件 我们可以在窗口、对话框架、工具条及其他任何容器窗口中创建日历控件。日历控件对应着CmonthCalCtrl类,所以要动态创建一个日历控件,需要声明一个CmonthCalCtrl变量或指向CmonthCalCtrl的指针,代码如下:
// Exercise1Dlg.h : header file class CExercise1Dlg : public CDialog { // Construction public: CExercise1Dlg(CWnd* pParent = NULL); // standard constructor private: CMonthCalCtrl *ctlCalendar; };
|
CmonthCalCtrl类象MFC中其他控件对应的类一样,提供了一个Create()方法用来在容器窗口中动态创建日历控件,代码如下:
CExercise1Dlg::CExercise1Dlg(CWnd* pParent /*=NULL*/) : CDialog(CExercise1Dlg::IDD, pParent) { //{{AFX_DATA_INIT(CExercise1Dlg) //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); ctlCalendar = new CMonthCalCtrl; } ///////////////////////////////////////////////////////////////////////////// // CExercise1Dlg message handlers BOOL CExercise1Dlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here ctlCalendar->Create(WS_TABSTOP | WS_CHILD | WS_VISIBLE | WS_BORDER,CPoint(20, 20), this, 0x224); return TRUE; // return TRUE unless you set the focus to a control } |
三、日历控件属性操作
在对话框或窗口中创建一个日历控件后,它仅显示当前的月份并仅仅只能显示一个月份,这是因为,按照默认的设计,控件的长、宽、高只能容纳一个月的日期,如果要显示两个月,就要增加控件的宽度(同样的道理,也可以通过增加高度来显示两个月份)。
作为一个可视化对象,日历控件可以用不同的颜色来表现背景、星期日、标题条文本、标题条背景等。作为开发人员理所当然地可以通过程序来更换这些颜色,当然是要在不影响控件亲合力的情况下。改变日历控件的颜色,需要调用CMonthCalCtrl::SetColor() 方法,该方法的语法是:
COLORREF SetColor(int nRegion, COLORREF ref); |
默认情况下,控件的标题条显示蓝色背景,如果要改变它,需要向nRegion参数传递MCSC_TITLEBK值,向ref参数传递你所要显示的颜色。如果更改标题条上文本的颜色,需要向nRegion参数传递MCSC_TITLETEXT值。
  图五、更改控件的标题条颜色
|
上文说过,在标题条的下方显示着星期日,在英语国家,一个星期的第一天是星期天,如果你想更改一个星期的第一天,可以调用函数SetFirstDayOfWeek(),它的语法是:
BOOL SetFirstDayOfWeek(int iDay, int* lpnOld = NULL); |
第一个参数必须是对应的下列整数值:
Value |
Weekday |
0 |
Monday |
1 |
Tuesday |
2 |
Wednesday |
3 |
Thursday |
4 |
Friday |
5 |
Saturday |
6 |
Sunday |
如果想要获知日历控件的星期天中具体哪一天设置为第一天,可以调用函数:GetFirstDayOfWeek(),它的语法是:
int GetFirstDayOfWeek(BOOL* pbLocal = NULL) const; |
该函数返回一个整数值,它对应的含义与上个表格一致。
星期日的名字使用的颜色与使用SetColor()函数传递MCSC_TITLETEXT时使用的颜色一致,在星期日的下面是一个水平分割线,默认情况下它该是黑色的,但这里它却与选择的日期一个颜色。在分割线下是日期列表,默认情况下背景是Windows默认的白色,如果要改变它,需要向nRegion参数传递MCSC_MONTHBK值,向ref参数传递你所要显示的颜色。
表示日期的数字显示有两种颜色,当前选择的月份中的日期以黑色表示,如果要改变这种颜色,可以向需要向nRegion参数传递MCSC_TRAILINGTEXT值,向ref参数传递你所要显示的颜色。
  图六、更改日历控件的日期显示颜色
|
分割线下的日期列表以两种颜色显示,为了规定当前月份中日期的颜色,可以向需要向nRegion参数传递MCSC_TEXT值,向ref参数传递你所要显示的颜色。
日历控件习惯于用两种形式来让用户了解当前的日期,一是在列表中以椭圆将当前日期圈起来,另一种方式是在底部以句子的形式显示。在创建控件时,将"today"属性设置为"NO"将不显示今天的日期。
 图七、不显示"今日"标签的日历控件
|
如上所述,默认情况下控件显示今天日期,可以通过编程使用MCS_NOTODAY来隐藏这个标签,代码如下:
BOOL CExercise1Dlg::OnInitDialog() { CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
ctlCalendar->Create(WS_TABSTOP | WS_CHILD | WS_VISIBLE | WS_BORDER | MCS_NOTODAY, CPoint(20, 20), this, 0x224);
return TRUE; // return TRUE unless you set the focus to a control } |
我们注意到, 当前日期还被一个椭圆圈了起来,如果要将它隐藏起来,应该使用MCS_NOTODAYCIRCLE类型,代码如下:
BOOL CExercise1Dlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here ctlCalendar->Create(WS_TABSTOP | WS_CHILD | WS_VISIBLE | WS_BORDER | MCS_NOTODAYCIRCLE, CPoint(20, 20), this, 0x224); return TRUE; // return TRUE unless you set the focus to a control } |
为了获取当前日历控件中选择的日期,可以使用方法:CMonthCalCtrl::GetCurSel(),该方法重载有3个版本,它们是:
BOOL GetCurSel(COleDateTime& refDateTime) const; BOOL GetCurSel(CTime& refDateTime) const; BOOL GetCurSel(LPSYSTEMTIME pDateTime) const; |
这里有一个例子:
void CExercise1Dlg::OnRetrieveBtn() { // TODO: Add your control notification handler code here UpdateData(); CTime tme = this->m_dtpCurrent.GetCurrentTime(); this->m_Result.Format("%s", tme.Format("%A, %B %d, %Y")); UpdateData(FALSE); } |
为了控制用户是否可以选择两个以上的日期,在创建控件时可以相应地设置多项选择属性。例如,如果你想让用户在控件中选择一定范围的日期,可以将多项选择属性设置为真。为了动态设置多日期选择,应用MCS_MULTISELECT属性,代码如下:
BOOL CExercise1Dlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
ctlCalendar->Create(WS_TABSTOP | WS_CHILD | WS_VISIBLE | WS_BORDER | MCS_NOTODAYCIRCLE | MCS_MULTISELECT, CPoint(20, 20), this, 0x224);
return TRUE; // return TRUE unless you set the focus to a control } |
 图八、显示多选择日期的日历控件
|
通过属性设置,用户可以在日历控件中选择多个日期,当然,也可以通过动态编程来选择多个日期,这时,可以调用CMonthCalCtrl::SetSelRange()方法,它有三个不同的版本,语法是:
BOOL SetSelRange(const COleDateTime& pMinRange, const COleDateTime& pMaxRange); BOOL SetSelRange(const CTime& pMinRange, const CTime& pMaxRange); BOOL SetSelRange(const LPSYSTEMTIME pMinRange, const LPSYSTEMTIME pMaxRange); |
如果想获取一个日历控件的可选择范围,可以调用CMonthCalCtrl::GetSelRange() 方法。
为了控制用户可选择的日期范围,可以调用CMonthCalCtrl::SetRange()方法,它也有三中不同的形式,分别是:
BOOL SetRange(const COleDateTime* pMinRange, const COleDateTime* pMaxRange); BOOL SetRange(const CTime* pMinRange, const CTime* pMaxRange); BOOL SetRange(const LPSYSTEMTIME pMinRange, const LPSYSTEMTIME pMaxRange); |
第一个参数nMinRange是选择范围的开始日期,参数nMaxRange是可供选择的最大日期。
分享到:
相关推荐
本文档详细介绍了如何使用Visual C++ 2010来创建一个具有扩展功能的列表控件(List Control)。通过这些扩展功能,可以实现在列表中的单元格上直接编辑数据、选择日期时间、下拉选择以及单选等功能。 #### 二、创建...
《Visual C++编写的万年历程序详解》 在信息技术领域,编程语言是构建软件的基础,而C++作为其中一种强大的面向对象编程语言,被广泛应用于各种系统开发,包括桌面应用、游戏引擎甚至操作系统。本篇文章将深入探讨...
**ACTIVEX控件详解** ACTIVEX控件,又称为OLE控件,是微软在Windows平台上推出的一种组件技术,它是ActiveX技术的重要组成部分。ActiveX控件是一种可执行的软件模块,能够嵌入到其他应用程序中,提供特定的功能,如...
在某些应用中,日历控件还可以实现日期选择的事件处理,比如当用户选择特定日期时触发某个功能。 为了实现这些控件的交互和功能,开发者需要熟练掌握MFC框架,理解控件的消息处理机制,以及如何在代码中响应用户的...
OCX(Object Linking and Embedding, Control eXtension)控件是Microsoft在Visual Basic和Visual C++等开发环境中广泛使用的一种组件技术。OCX控件是ActiveX控件的一个子集,主要用于Windows应用程序的用户界面设计...
标题“ACTUVEX时间控件例子”暗示我们将会探讨如何在C++中使用ACTUVEX库来创建和操作时间控制功能。ACTUVEX是一个用于Windows平台的C++库,它为Visual C++提供了丰富的Windows API控件封装,使得开发者能够更加方便...
在Windows应用程序开发中,Visual C++(简称VC++)是一种广泛使用的编程环境,尤其在构建桌面应用时。为了丰富应用程序的用户界面(UI)和增强功能,开发者经常会利用第三方控件。"cjlib"就是这样一个专门为VC++设计...
而“OCX控件文件”很可能是包含一个或多个OCX控件的实际二进制文件,开发者可以下载并尝试在自己的项目中使用。 总之,OCX控件是Windows平台下增强应用程序功能的重要工具,它简化了UI组件的开发和集成过程,使得...
本篇文章将深入探讨使用VC++(Visual C++)开发日历小程序的过程,通过分析提供的源代码文件,揭示其中的核心知识点。 首先,我们看到压缩包中的源代码文件包括例2-6.cpp到例2-19.cpp,这些文件很可能包含了日历...
《C#实现的工厂日历管理系统详解》 在信息技术领域,C#是一种广泛使用的编程语言,尤其在开发Windows应用程序和Web应用程序方面具有显著优势。本系统——“C#实现的工厂日历管理系统”正是利用了C#的强大功能,旨在...
除了基础的控件,如按钮、文本框、列表框等,Raize Components还提供了许多高级组件,如数据绑定控件、图表组件、日历控件、进度条、分页控件等。这些组件不仅功能强大,而且易于集成和自定义,能帮助开发者实现复杂...
二、日历控件 在VC++6.0中,实现日历功能通常会利用MonthCalendar控件。MonthCalendar控件允许用户选择日期范围,并且能够显示公历中的月份和年份。开发者可以通过设置控件属性,如MaxSelCount(最大可选日期数量)...
**Delphi、BCB与EHLib控件详解** 在编程领域,Delphi和BCB(Borland C++ Builder)是两种广泛使用的集成开发环境(IDE),尤其在Windows平台的应用程序开发中。它们都基于Object Pascal语言,提供高效、快速的...
Microsoft Date and Time Picker Control 6.0是Microsoft ActiveX控件库的一部分,适用于Visual Basic 6.0、Visual C++等开发环境。该控件通过提供一个图形化界面,让用户能够以日历形式选择日期,时钟形式选择时间...
Visual C++(简称VC++)作为Microsoft公司开发的一种强大的Windows平台下的编程工具,结合MFC(Microsoft Foundation Classes)库,可以构建高效、用户友好的应用程序,如“学生个人事务管理系统”。本篇文章将深入...
打开这个文档,你将能获取更多关于如何在实际项目中使用 OCX 控件的具体步骤和建议。 总的来说,OCX 文件作为 ActiveX 控件的载体,是 Windows 应用程序开发中的一个重要工具,它提供了丰富的界面元素和交互功能。...
例如,它们可能包括但不限于按钮、表格、日历、进度条、对话框等,以及各种定制的布局和容器控件。 **2. 支持C++Builder6** C++Builder6是 Borland 公司(后来被Embarcadero收购)在2003年发布的一款集成开发环境...
3. **跨平台兼容性**:虽然OCX主要是为Windows平台设计的,但通过OLE技术,它们可以在支持OLE的其他应用程序中使用,例如在Visual Basic、Visual C++或Delphi等开发环境中。 4. **自包含性**:每个OCX文件都包含了...
2. **丰富的控件集**:库中包含多种控件,如工具栏、菜单、状态栏、对话框、日历控件等,满足开发者构建各种复杂UI的需求。 3. **智能布局**:自动处理控件的大小调整和位置排列,确保在不同分辨率和屏幕尺寸下都能...
《MFC单文档VS2012:模拟时钟日历程序详解》 MFC(Microsoft Foundation Classes)是微软提供的一套C++类库,用于简化Windows应用程序开发。在这个项目中,我们关注的是如何在Visual Studio 2012环境下,利用MFC...