第一次寫部落格,就把這第一次獻給親愛的MFC吧~作為一個MFC初學者,我懂得各位同是初學者的同學朋友們的不易,網上關於從MFC 0基礎開始講解MFC的書籍並不多,在這裡就對我練習的這個小程式儘可能地做詳細地講解,請各同學朋友多多指點,相互學習,高手勿噴~
最終小程式的運行結果如下圖所示(時鐘各個點的位置的數學演算法可以自己用正餘弦定理計算一下或者去參考一下網上其他人計算好的):
好了,上正題,筆者這個MFC小程式是用VS2012寫成的,於是乎我們第一步開啟VS2012,依次點擊“檔案->建立->項目”以此來建立一個項目,並選擇MFC的模板,這裡我們就將項目名稱命名為“ClockShower”:
在彈出來的嚮導中,我們先別急點擊“完成”,點擊“下一步”進入下一介面,在應用程式類型中,我們選擇應用程式類型為“單個文檔”,其他的可以保持預設:
再不斷地點擊“下一步”(保持預設配置就行了),直到出現“產生的類”這個嚮導介面,我們選中CClockShowerView,在“基類”中選擇CFormView,這樣CClockShowerView就繼承了允許對話方塊控制項拖動到View視圖的特性,我們就可以在單文檔程式中使用對話方塊的控制項了:
好了,準備工作做好了,點擊“完成”,產生項目。
項目產生好後,我們首先運行一下,得到如下介面:
在這裡向同學朋友們說明一下View的用戶端地區和MainFrm顯示的範圍界限,因為在View中的繪圖和在MainFrame中的繪圖得到的效果並不一樣,可以自己嘗試一下:
在左下方找到資源檢視(或者點擊菜單上的“視圖->資源檢視”),開啟“IDD_CLOCKSHOWER_FORM”,這個就是在View視圖中顯示的對話方塊了,在右邊的工具箱->對話方塊編輯器中,我們可以看到此時項目允許我們拖動各種控制項(如果點擊了工具箱後,仍沒有看到控制項的列表,請點擊工具箱,然後在工具箱選項卡中的空白處右鍵->重設工具箱,等vs重設工具箱後就可以看到了),我們選擇“Month Calendar Control”這個控制項並拖到對話方塊上,然後再運行一遍程式,怎麼樣,是不是看到了一個日曆,有點感覺了吧:
對於這個日曆的控制項,在這裡我們不需要對它做些什麼,只需要它擺在一旁做襯托就行,接下來我們找到“Menu->IDR_MAINFRAME”,這就是單文檔程式中的主菜單視窗了,我們菜單右邊的“請在此鍵入”中輸入我們自訂的菜單選項和子功能表選項“時鐘行事曆程式”和“開始/停止”:
好了,添加功能表項目完畢之後,得為功能表項目添加訊息處理常式或者COMMAND訊息,否則這個功能表項目就會變灰,無法使用。於是我們對“開始/停止”右鍵->添加事件處理常式,在彈出來的對話方塊中首先選擇COMMAND訊息類型,在右邊的“類列表”中選擇CMainFrame(或者選擇CClockShowerView也是可以的,並且在View中繪製要合理一些,這裡我們就選在CMainFrame來講解了),然後點擊“添加編輯”這樣在MainFrm.cpp中我們可以看到多了一個CMainFrame::OnStartorstopControl()
同理我們再為“開始/停止”這個子功能表項添加UPDATE_COMMAND_UI訊息處理常式,添加完畢後,我們在MainFrm.h中的CMainFrame類中添加私人變數m_Start,並在MainFrm.cpp的建構函式中初始化m_Start = TRUE,然後在剛才的兩個COMMAND訊息函數中添加代碼:
void CMainFrame::OnStartorstopControl(){// TODO: 在此添加命令處理常式代碼if(m_Start){//通過關閉定時器停止運行時鐘程式KillTimer(1);}else {//通過開啟定時器開始運行時鐘程式SetTimer(1,1000,NULL);}//繪圖使能標識取反 m_Start = !m_Start; }void CMainFrame::OnUpdateStartorstopControl(CCmdUI *pCmdUI){// TODO: 在此添加命令更新使用者介面處理常式代碼//根據m_bDraw的值設定是否選中 pCmdUI->SetCheck(m_Start); }
選擇“類別檢視”,找到並選中CMainFrame這個類,右鍵->屬性或者在右邊面板上找到“屬性”,在屬性面板上找到“訊息”,然後再找到“WM_TIMER”這個訊息,也就是定時器的訊息,點擊“<Add OnTimer>”,就會看到vs為我們在CMainFrame類中建好了一個定時器的訊息處理函數OnTimer,前面的SetTimer(1,1000,NULL)就是讓程式每隔1秒執行一次OnTimer函數:
好了,訊息處理函數的準備工作也做完了,我們就開始來建類(為什麼要建類。規範代碼,便於維護,易於閱讀,老師說你懂的 :) )
這裡我們就建兩個簡單的類就行了,一個是時鐘類CClock,一個是針類(時針、分針、秒針)CNeedle,在“解決方案”視圖中我們右鍵“標頭檔”->添加->類來建立這兩個類
寫好類名後直接點擊“完成”就可以了
同理添加CNeedle這個類,完成後會發現我們的“標頭檔”和“源檔案”中分別多了“Clock.h、Needle.h”和“Clock.cpp、Needle.cpp”這四個檔案,其中.h檔案是用於定義一個類或者其他公有的結構例如枚舉、結構體等,我們修改Clock.h和Needle.h中的類,添加代碼:
Clock.h
#pragma once#include "Needle.h"//時鐘類class CClock{public:CClock(void);~CClock(void);//繪製時鐘周圍的大圈void DrawCircle(CDC *pDC,int x1,int y1,int x2,int y2);//繪製時鐘上面的各個點void Draw(CDC *pDC,int nMoveToX,int nMoveToY,int nDrawX,int nDrawY);//建立畫筆void CreatePen(int index,int nPenStyle,int nWidth,COLORREF color);//獲得圓圈的畫筆CPen *GetCirclePen();//獲得關鍵點的畫筆CPen *GetKeyPointPen();//獲得其他點的畫筆CPen *GetPointPen();//擷取時針CNeedle *GetHourNeedle();//擷取分針CNeedle *GetMinuteNeedle();//擷取秒針CNeedle *GetSecondNeedle();private://時針CNeedle *m_HourNeedle;//分針CNeedle *m_MinuteNeedle;//秒針CNeedle *m_SecondNeedle;//外部圓的畫筆CPen m_CirclePen;//關鍵點的畫筆CPen m_KeyPointPen;//其他點的畫筆CPen m_PointPen;};
Needle.h
#pragma once//針類class CNeedle{public:CNeedle(void);~CNeedle(void);//建立畫筆void CreatePen(int nPenStyle,int nWidth,COLORREF color);//繪製自己void Draw(CDC *pDC,int moveToX,int moveToY,int drawX,int drawY);//擷取自己的畫筆CPen *GetPen();public://畫筆CPen m_Pen;};
然後在他們各自的cpp檔案中寫入實現方法:
Clock.cpp
#include "stdafx.h"#include "Clock.h"#include "Needle.h"CClock::CClock(void){//構造時針、分針、秒針m_HourNeedle = new CNeedle();m_MinuteNeedle = new CNeedle();m_SecondNeedle = new CNeedle();}CClock::~CClock(void){//釋放成員delete(m_HourNeedle);delete(m_MinuteNeedle);delete(m_SecondNeedle);}//繪製時鐘周圍的大圈void CClock::DrawCircle(CDC *pDC,int x1,int y1,int x2,int y2){pDC->Ellipse(x1,y1,x2,y2);}//繪製時鐘上面的各個點void CClock::Draw(CDC *pDC,int nMoveToX,int nMoveToY,int nDrawX,int nDrawY){//將繪點移動到根點pDC->MoveTo(nMoveToX,nMoveToY);//連線繪製pDC->LineTo(nDrawX,nDrawY);}//建立畫筆,0繪製圓圈,1繪製關鍵點,2繪製其他點void CClock::CreatePen(int index,int nPenStyle,int nWidth,COLORREF color){if(index == 0)m_CirclePen.CreatePen(nPenStyle,nWidth,color);else if(index == 1)m_KeyPointPen.CreatePen(nPenStyle,nWidth,color);else m_PointPen.CreatePen(nPenStyle,nWidth,color);}//獲得畫筆CPen *CClock::GetCirclePen(){return &m_CirclePen;}//獲得關鍵點的畫筆CPen *CClock::GetKeyPointPen(){return &m_KeyPointPen;}//獲得其他點的畫筆CPen *CClock::GetPointPen(){return &m_PointPen;}//擷取時針CNeedle *CClock::GetHourNeedle(){return m_HourNeedle;}//擷取分針CNeedle *CClock::GetMinuteNeedle(){return m_MinuteNeedle;}//擷取秒針CNeedle *CClock::GetSecondNeedle(){return m_SecondNeedle;}
Needle.cpp
#include "stdafx.h"#include "Needle.h"CNeedle::CNeedle(void){}CNeedle::~CNeedle(void){}void CNeedle::CreatePen(int nPenStyle,int nWidth,COLORREF color){m_Pen.CreatePen(nPenStyle,nWidth,color);}void CNeedle::Draw(CDC *pDC,int moveToX,int moveToY,int drawX,int drawY){//移動到目標根點pDC->MoveTo(moveToX,moveToY);//連線形成繪製pDC->LineTo(drawX,drawY);}CPen *CNeedle::GetPen(){return &m_Pen;}
OK,到這裡,類已經建完,還得去執行個體化它們並且調用才能看到效果,於是乎我們又轉到MainFrm.h中為CMainFrame類添加私人成員變數,代碼如下(包括了之前的m_Start在內了),記得要加上#include “Clock.h”,否則識別不了CClock這個類:
private://控制功能表項的標識bool m_Start;//時鐘CClock *m_Clock;//當前系統時間CTime m_CurrentTime;//當前的小時int m_Hour;//當前的秒int m_Second;//當前的分int m_Minute;
同時為了讓代碼結構看起來更工整一些,我們還是建立幾個方法分別把各種的實現給封裝起來,盡量避免所有代碼都寫在一個函數裡,於是我們在MainFrm.h中繼續添加方法,代碼如下:
public://輸出Title以及時鐘的文字void PrintText(CDC *pDc,int quarterWidth,int threeQuartersWidth,int quarterHeight,int threeQuartersHeight,int midWidth,int midHeight);//繪製時鐘的圖形void DrawClock(CDC *pDc,int quarterWidth,int threeQuartersWidth,int quarterHeight,int threeQuartersHeight,int midWidth,int midHeight);//繪製日曆的所有內容void DrawCalendar(CDC *pDc,CRect rect);//初始化資料void Init();
然後在MainFrm.cpp的CMainFrame這個類中寫上這幾個方法的具體實現(也就是實現時鐘和日曆的繪製的核心代碼,代碼我基本都添加了注釋了的,同學們朋友們如果看不太明白的話給我留言哈,能幫到的一定幫忙~)
//初始化資料void CMainFrame::Init(){m_Start = FALSE;//構造時鐘m_Clock = new CClock();//構建時鐘外圓的畫筆m_Clock->CreatePen(0,PS_SOLID,3,RGB(255,255,0));//構建時鐘關鍵點的畫筆m_Clock->CreatePen(1,PS_SOLID,3,RGB(0,0,0));//構建時鐘其他點的畫筆m_Clock->CreatePen(2,PS_SOLID,2,RGB(0,0,0));//構建秒針的畫筆m_Clock->GetSecondNeedle()->CreatePen(PS_SOLID,2,RGB(255,0,0));//構建分針的畫筆m_Clock->GetMinuteNeedle()->CreatePen(PS_SOLID,4,RGB(0,0,255));//構建時針的畫筆m_Clock->GetHourNeedle()->CreatePen(PS_SOLID,6,RGB(0,255,0));}//輸出介面中的文字,根據六個方向確定時鐘和文字的座標void CMainFrame::PrintText(CDC *pDc,int quarterWidth,int threeQuartersWidth,int quarterHeight,int threeQuartersHeight,int midWidth,int midHeight){//擷取當前的系統時間,傳遞給m_CurrentTimethis->m_CurrentTime = CTime::GetCurrentTime();//格式化時間字串為時分秒CString str = this->m_CurrentTime.Format("%H:%M:%S");//設定標題字型為微軟雅黑CFont titleFont;titleFont.CreateFontW(35,15,0,0, FW_NORMAL,false ,false,false, DEFAULT_CHARSET,OUT_DEVICE_PRECIS ,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH ,_T("微軟雅黑"));//選擇建立的字型pDc->SelectObject(&titleFont);//輸出標題pDc->TextOutW(midWidth-180,40,_T("歡迎使用時鐘日曆類比程式"));//設定字型為微軟雅黑CFont font;font.CreateFontW(20,7,0,0, FW_NORMAL,false ,false,false, DEFAULT_CHARSET,OUT_DEVICE_PRECIS ,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH ,_T("微軟雅黑"));//選擇建立的字型pDc->SelectObject(&font);//輸出時間的文字pDc->TextOutW(midWidth-30,midHeight+quarterHeight+20,str);//輸出星期幾CString clockWeek(_T("星期"));int week = m_CurrentTime.GetDayOfWeek();CString weekStr;switch (week){case 1:weekStr += _T("天");clockWeek+=weekStr;break;case 2:weekStr += _T("一");clockWeek+=weekStr;break;case 3:weekStr += _T("二");clockWeek+=weekStr;break;case 4:weekStr += _T("三");clockWeek+=weekStr;break;case 5:weekStr += _T("四");clockWeek+=weekStr;break;case 6:weekStr += _T("五");clockWeek+=weekStr;break;case 7:weekStr += _T("六");clockWeek+=weekStr;break;default:break;}pDc->TextOutW(midWidth-25,midHeight+quarterHeight+40,clockWeek);}//繪製時鐘,根據六個方向確定時鐘座標void CMainFrame::DrawClock(CDC *pDc,int quarterWidth,int threeQuartersWidth,int quarterHeight,int threeQuartersHeight,int midWidth,int midHeight){//更換畫外部圓圈的畫筆並儲存系統畫筆CPen *pOldPen = pDc->SelectObject(m_Clock->GetCirclePen());//畫圓m_Clock->DrawCircle(pDc,midWidth-quarterHeight,quarterHeight,midWidth+quarterHeight,threeQuartersHeight);//更改成繪製關鍵點的畫筆pDc->SelectObject(m_Clock->GetKeyPointPen());//畫12,將畫筆移至客戶區中間寬度,四分之一的高度的地方,然後y軸向下延伸20個單位,其他的同理m_Clock->Draw(pDc,midWidth,quarterHeight,midWidth,quarterHeight+20);//畫6m_Clock->Draw(pDc,midWidth,threeQuartersHeight,midWidth,threeQuartersHeight-20);//畫3m_Clock->Draw(pDc,midWidth+quarterHeight,midHeight,midWidth+quarterHeight-20,midHeight);//畫9m_Clock->Draw(pDc,midWidth-quarterHeight,midHeight,midWidth-quarterHeight+20,midHeight);//畫1m_Clock->Draw(pDc,midWidth+quarterHeight/2,midHeight-(int)(0.866*(double)quarterHeight),midWidth+quarterHeight/2-10,midHeight-(int)(0.866*(double)quarterHeight)+17);//畫7m_Clock->Draw(pDc,midWidth-quarterHeight/2,midHeight+(int)(0.866*(double)quarterHeight),midWidth-quarterHeight/2+10,midHeight+(int)(0.866*(double)quarterHeight)-17);//畫2m_Clock->Draw(pDc,midWidth+(int)(0.866*(double)quarterHeight),midHeight-quarterHeight/2,midWidth+(int)(0.866*(double)quarterHeight)-17,midHeight-quarterHeight/2+10);//畫8m_Clock->Draw(pDc,midWidth-(int)(0.866*(double)quarterHeight),midHeight+quarterHeight/2,midWidth-(int)(0.866*(double)quarterHeight)+17,midHeight+quarterHeight/2-10);//畫4m_Clock->Draw(pDc,midWidth+(int)(0.866*(double)quarterHeight),midHeight+quarterHeight/2,midWidth+(int)(0.866*(double)quarterHeight)-17,midHeight+quarterHeight/2-10);//畫10m_Clock->Draw(pDc,midWidth-(int)(0.866*(double)quarterHeight),midHeight-quarterHeight/2,midWidth-(int)(0.866*(double)quarterHeight)+17,midHeight-quarterHeight/2+10);//畫5m_Clock->Draw(pDc,midWidth+quarterHeight/2,midHeight+(int)(0.866*(double)quarterHeight),midWidth+quarterHeight/2-10,midHeight+(int)(0.866*(double)quarterHeight)-17);//畫11m_Clock->Draw(pDc,midWidth-quarterHeight/2,midHeight-(int)(0.866*(double)quarterHeight),midWidth-quarterHeight/2+10,midHeight-(int)(0.866*(double)quarterHeight)+17);//更換回系統畫筆pDc->SelectObject(pOldPen);//畫其他點for(int i=0;i<60;i++){m_Clock->Draw(pDc,midWidth+(int)(quarterHeight*sin(i*PI/30)),midHeight-(int)(quarterHeight*cos(i*PI/30)),midWidth+(int)(quarterHeight*0.87*sin(i*PI/30)),midHeight-(int)(quarterHeight*0.87*cos(i*PI/30)));}//更改成秒針畫筆pDc->SelectObject(m_Clock->GetSecondNeedle()->GetPen());//pDc->SelectObject(&penS);//畫秒針m_Clock->GetSecondNeedle()->Draw(pDc,midWidth-(int)(quarterHeight*0.3*sin(this->m_Second*PI/30)),midHeight+(int)(quarterHeight*0.3*cos(this->m_Second*PI/30)),midWidth+(int)(quarterHeight*0.8*sin(this->m_Second*PI/30)),midHeight-(int)(quarterHeight*0.8*cos(this->m_Second*PI/30)));//更改成分針畫筆pDc->SelectObject(m_Clock->GetMinuteNeedle()->GetPen());//畫分針m_Clock->GetMinuteNeedle()->Draw(pDc,midWidth,midHeight,midWidth+(int)(quarterHeight*0.8*sin(2*PI*(this->m_Minute/60.0+this->m_Second/3600.0))),midHeight-(int)(quarterHeight*0.8*cos(2*PI*(this->m_Minute/60.0+this->m_Second/3600.0))));//更改畫筆pDc->SelectObject(m_Clock->GetHourNeedle()->GetPen());//畫時針m_Clock->GetHourNeedle()->Draw(pDc,midWidth,midHeight,midWidth+(int)(quarterHeight*0.6*sin(2*PI*(this->m_Hour/12.0+this->m_Minute/720.0))),midHeight-(int)(quarterHeight*0.6*cos(2*PI*(this->m_Hour/12.0+this->m_Minute/720.0))));//換回系統畫筆pDc->SelectObject(pOldPen);}//繪製日曆的所有內容void CMainFrame::DrawCalendar(CDC *pDc,CRect rect){//-----------------繪製日曆矩形框和數字//日曆矩形框的左邊界就是三分之二的客戶區寬度int calendarLeft = rect.Width()/3*2;//日曆矩形框的頂部邊界就是四分之一的客戶區高度int calendarTop = rect.Height()/4;//日曆矩形框的右邊界就是客戶區的最右邊int calendarRight = rect.Width();//日曆矩形框的底部邊界就是客戶區的四分之三的高度int calendarButtom = rect.Height()/4*3;//繪製矩形框pDc->Rectangle(calendarLeft,calendarTop,calendarRight,calendarButtom);/**日曆矩形框的高度均分為8部分,寬度均分為7部分*/int partWidth = (calendarRight-calendarLeft)/7;int partHeight = (calendarButtom-calendarTop)/8;int year = m_CurrentTime.GetYear();CString head;//int轉cstringhead.Format(TEXT("%d"),year);head+=_T("年");int month = m_CurrentTime.GetMonth();CString headPart;headPart.Format(TEXT("%d"),month);head+=headPart+_T("月");//一周的第一天為星期天,GetDayOfWeek為1,依次類推//CString cc;////int dayOfWeak = m_CurrentTime.GetDayOfWeek();//int dayOfWeak = m_CurrentTime.GetDay();//cc.Format(TEXT("%d"),dayOfWeak);//head+=_T("星期")+cc;//在日曆矩形框中頂部繪製年月pDc->TextOutW(calendarLeft-20+(calendarRight-calendarLeft)/2-10,calendarTop+10,head);//設定字型顏色 pDc->SetTextColor(RGB (125,0,255));//在日曆矩形框中繪製星期pDc->TextOutW(calendarLeft+5,calendarTop+partHeight*1,_T("周日"));pDc->TextOutW(calendarLeft+5+partWidth,calendarTop+partHeight*1,_T("周一"));pDc->TextOutW(calendarLeft+5+partWidth*2,calendarTop+partHeight*1,_T("周二"));pDc->TextOutW(calendarLeft+5+partWidth*3,calendarTop+partHeight*1,_T("周三"));pDc->TextOutW(calendarLeft+5+partWidth*4,calendarTop+partHeight*1,_T("周四"));pDc->TextOutW(calendarLeft+5+partWidth*5,calendarTop+partHeight*1,_T("周五"));pDc->TextOutW(calendarLeft+5+partWidth*6,calendarTop+partHeight*1,_T("周六"));//設定字型顏色 pDc->SetTextColor(RGB (0,0,0));//在日曆矩形框中繪製具體天數的日期//當前是幾號int nowDay = m_CurrentTime.GetDay();//當前天數的備份int nowDayBack = nowDay;//當前是星期幾int nowWeak = m_CurrentTime.GetDayOfWeek();//計算當前天數應在的行數int row;//預設是在第一行row = 1;if((nowDay - nowWeak)>=0){row = (nowDay-nowWeak)/7+1;if((nowDay-nowWeak)%7 != 0){row++;}}//行號的備份int rowBack = row;//更換畫筆CPen *pOldPen = pDc->SelectObject(m_Clock->GetSecondNeedle()->GetPen());//圈出當前天數的日期pDc->Ellipse(calendarLeft+partWidth*(nowWeak-1),calendarTop+partHeight*(row+1),calendarLeft+partWidth*(nowWeak),calendarTop+partHeight*(row+2));//換回系統畫筆pDc->SelectObject(pOldPen);//分行繪製數字//只當前天數那一行往前推for(int j=0;j<nowWeak;j++){if(nowDay == 0)break;CString cstr;cstr.Format(TEXT("%d"),nowDay--);pDc->TextOutW(calendarLeft+partWidth*(nowWeak-j-1) + 5,calendarTop+partHeight*(row+1),cstr);}//當前天數往上推int R = row-1;if(R>0){for(int i=0;i<R;i++){row--;if(nowDay == 0)break;for(int j=0;j<7;j++){CString cstr;cstr.Format(TEXT("%d"),nowDay--);pDc->TextOutW(calendarLeft+partWidth*(7-j-1) + 5,calendarTop+partHeight*(row+1),cstr);if(nowDay == 0)break;}}}//當前天數往下推//本月剩餘天數int restDay;if(month == 1||month == 3||month == 5||month == 7||month == 8||month == 10||month == 12){restDay = 31-nowDayBack;}else if(month == 2){//閏年if((year%4 == 0&&year%100)||(year%400 == 0)){restDay = 29 - nowDayBack;}//平年else {restDay = 28 - nowDayBack;}}else {restDay = 30 - nowDayBack;}for(int i=0;i<restDay;i++){CString cstr;cstr.Format(TEXT("%d"),++nowDayBack);pDc->TextOutW(calendarLeft+partWidth*(nowWeak++) + 5,calendarTop+partHeight*(rowBack+1),cstr);//換行if(nowWeak == 7){rowBack++;nowWeak = 0;}}}
記得要添加MainFrm.cpp中添加這些標頭檔,否則會提示找不到相應的變數或者類:
#include "ClockShowerView.h"#define PI 3.141593#include "math.h"
同時因為在CMainFrame中添加了對View的標頭檔的調用,在ClockShowerView.h中需要添加標頭檔:
#include "ClockShowerDoc.h"
最後我們在CMainFrame的建構函式中修改並添加對Init的調用即可:
// CMainFrame 構造/析構CMainFrame::CMainFrame(){// TODO: 在此新增成員初始化代碼Init();theApp.m_nAppLook = theApp.GetInt(_T("ApplicationLook"), ID_VIEW_APPLOOK_VS_2008);}
然後我們就開始運行程式,出來後,點擊菜單上的“時鐘行事曆程式”中的子功能表項“開始/停止”,我們的時鐘和自己繪製的日曆就出來了~,自己繪製的日曆會根據系統時間的變化而變化,各同學們朋友們可以更改自己的系統時間來驗證這個我自己繪製的日曆是否正確(演算法自己寫的但是也沒怎麼測試過,就只試了9月和10月的每一天都無問題,應該還是可以的哈 :) )
最後,附上整個程式的源碼,免積分~多多交流,多多指教~
http://download.csdn.net/detail/yueya_shanhua/8108625