求MFC万年历源码,感激不禁!!
发布网友
发布时间:2024-07-02 14:20
我来回答
共1个回答
热心网友
时间:2024-07-22 04:14
VC有自己的日历控件 CMonthCalCtrl
http://www.codeguru.com/code/legacy/controls/MonthCalCtrlCalendar.zip
阅读MSDN2003,我们可以看到,MFC提供了18种通用控件,具体是哪18种,我不详细列出,可以在MSDN2003的MSDN \ Visual Studio .NET \ Visual C++ \ 添加功能 \ MFC \ 用户界面 \ 控件 \ 中看到。其中每一个控件都对应了一个MFC类,这些类的详细说明可以在MSDN2003 的MSDN \ Visual Studio .NET \ Visual C++ \ Visual C++参考 \ MFC Reference \ MFC Classes \ 中找到。
在MFC中添加控件有两种方法。
第一种是直接手动从“Controls”工具栏中拖动控件到窗体上,这种方法比较直观,但是仅仅局限与基于对话框的MFC应用程序。为此我将重点描述第二种方法。
第二种方法是使用MFC类动态添加控件,我将以Month Calendar控件为例介绍这中方法。Month Calendar控件对应的MFC类是CMonthCalCtrl。
第一步,在窗体中添加成员指针:CMonthCalCtrl *m_pCtrlMonth
第二步,在窗体初始化的时候初始化控件,这里所说的窗体初始化,并不是窗体类的初始化函数,而是OnInitialUpdate()或OnInitDialog()函数
m_pCtrlMonth = new CMonthCalCtrl;
m_pCtrlMonth->Create(WS_VISIBLE|WS_CHILD|WS_BORDER|MCS_NOTODAY,rect,this, IDC_MCC );
m_pCtrlMonth->ShowWindow(SW_SHOW);
Create()函数有四个参数:
第一个参数是一些宏定义的组合,这些宏指定了控件的风格,例如WS_VISIBLE表示控件初始化可见,WS_CHILD表示控件为子窗体,WS_BORDER表示控件有边框,MCS_NOTODAY是Month Calendar的风格,表示控件不会在底部提示今天的日期。关于控件的风格,可以参考MSDN。在MSDN \ Visual Studio .NET \ Visual C++ \ Visual C++参考 \ MFC Reference \ Structures, Styles, Callbacks, and Message Maps \ Styles Used by MFC \ 中描述了各种窗体风格。具体控件特有的风格,在MSDN描述该控件对应类的Create函数的时候 具体给出。
第二个参数是一个RECT结构体的引用,表示控件在窗体中的位置坐标。
第三个参数是该控件父窗体的指针。
第四个参数是控件的资源ID。可以自己定义#define ID_CONTROL ******。
现在控件已经基本初始化成功,其他的控件也是这样的方式,不同的是控件的风格和控件对应的MFC类。接下来就可以设置控件的属性和添加控件消息。这里,我只介绍Month Calendar控件两个常用的消息。
MCN_SELECT消息:当完成日期选定的时候触发此消息的消息处理函数。
NM_RELEASEDCAPTURE消息:在Month Calendar控件中有一个Scoll,击中Scoll就会触发这个消息的消息处理函数,默认的,点击一次Scoll,控件切换一个月,可以通过SetMonthDelta函数设置切换几个月。m_pCtrlMonth->SetMonthDelta(3)表示一次切换三个月。
控件中如果添加MCS_DAYSTATE风格,可以显示日期的状态。此状态强调当前显示的月的某些日期,状态信息表示为 32 位数据类型,MONTHDAYSTATE。MONTHDAYSTATE 位域(1 到 31)中的每一位表示一月中一天的状态。如果某个位打开,相应的日将用粗体显示;否则,日将以无强调的方式显示。有两种方法用于设置月历 (MonthCalendar) 控件的日状态:通过调用 CMonthCalCtrl::SetDayState 显式地设置或通过处理 MCN_GETDAYSTATE 通知消息来设置。
MCN_GETDAYSTATE消息:此方法在MSDN \ Visual Studio .NET \ Visual C++ \ 添加功能 \ MFC \ 用户界面 \ 控件 \ 使用 CMonthCalCtrl \ 设置月历 (MonthCalendar) 控件的日状态 \ 中有详细的中文说明。
一种方法是调用SetDayState函数,例如在NM_RELEASEDCAPTURE消息处理函数中,初始化这个月的哪些天需要突出显示:
SYSTEMTIME timeFrom;
SYSTEMTIME timeUntil;
int nCount =m_pCtrlMonth ->GetMonthRange(&timeFrom,&timeUntil,GMR_DAYSTATE);
LPMONTHDAYSTATE pDayState;
pDayState = new MONTHDAYSTATE[nCount];
memset(pDayState, 0, sizeof(MONTHDAYSTATE) * nCount);
int nIndex = (timeFrom.wDay == 1) ? 0 : 1;
pDayState[nIndex] |= 1 << 3; // 4th day
pDayState[nIndex] |= 1 << 18; // 19th day
pDayState[nIndex] |= 1 <<24; // 25th day
VERIFY(m_pCtrlMonth ->SetDayState(nCount, pDayState));
delete [] pDayState;
这段代码是MSDN中介绍SetDayState函数时给出的。原理其实很简单,控件中有个属性表示这些日期的状态,自己定义一个该属性的副本,然后设置副本中日期的状态,最后调用SetDayState函数把这个副本的信息传递给控件的属性。