您好,欢迎来到好土汽车网。
搜索
您的当前位置:首页课程设计报告

课程设计报告

来源:好土汽车网
C++课程设计报告

计科101

冯康 201000814128

桌面精灵

程序介绍

桌面精灵的主窗体运行结果如图1.1所示。桌面精灵模块是以阴历和阳历相结合的方式显示的日历,其中还包含二十四节气以及一些中西方节日,这些特殊的日期都用不同的颜色进行标注。

图1.1 桌面精灵主窗体

 窗口设置

右键单击主界面,在弹出的菜单中选择“窗口设置”命令,打开“窗口设置”模块,如图1.2所示。在该模块中,用户可以设置窗口的显示风格,包括普通窗口、总在最前和嵌入桌面3种,还可以进行系统设置,包括开机自动运行、鼠标穿透和透明度设置。通过设置这些风格可以更灵活的使用桌面精灵模块。

– – 1

图1.2 窗口设置

 新建备忘录

右键单击主界面,在弹出的菜单中选择“新建备忘录”命令,打开“新建备忘录”窗口,如图1.3所示。在该模块中,可以添加备忘录信息,用来提醒用户,一以免忘记重要的工作。

图1.3 新建备忘录模块

 备忘录列表

右键单击主界面,在弹出的菜单中选择“备忘录列表”命令,打开“备忘录列表”窗口,如图1.4所示。在该模块中,用户可以查看所有的备忘提醒,并可以对这些提醒进行管理。

– – 2

图1.4 备忘录列表模块

 提示显示

图1.5 备忘录的提示界面

 托盘显示

图1.6 静止状态 图1.7 鼠标滑过

图1.8 右键单击

– – 3

图1.9 在主窗口上单击右键菜单显示

功能实现代码介绍:

关键代码

1、 阳历转换成阴历的方法

(1)定义一个LeapYear函数,用来判断当前年份是否是闰年 2、 BOOL CEidolonDlg::LeapYear(int year)

{ return ((year%4==0 && year%100!=0) || year%400==0); }

(2)添加自定义函数FirstDayOfMonth,用来计算月份的第一天是星期几 int CEidolonDlg::FirstDayOfMonth(int year,int month)

{

int n=0,d=0;//d来保存这一天之前在全年中的天数 for(int i=1;i}

(3)添加GetMonthDays函数用来计算各个月份的天数

int CEidolonDlg::GetMonthDays(int year,int month) { switch(month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31; case 4: case 6: case 9: case 11: return 30; case 2: if(LeapYear(year))//如果是闰年则返回29天 return 29;

– –

4

else return 28; } return 0; }

(4)添加DaysFrom1900函数,用来计算Y年M月D日到1900年相差的天数,就是将1900年作为一个基数,根据它来计算当前日期是星期几即农历日期 LONG CEidolonDlg::DaysFrom1900(CustomDate Date) { LONG days; days = 365*Date.Year+(Date.Year-1)/4-(Date.Year-1)/100+(Date.Year-1)/400- (365*1900+(1900-1)/4-(1900-1)/100+(1900-1)/400); for(int i=0;i(5)添加YearDays函数用来计算农历的总天数 int CEidolonDlg::YearDays(int year) { UINT i, sum = 348; for(i=0x8000; i>0x8; i>>=1) { sum += (LunarInfo[year-1900] & i) ? 1 : 0; } return(sum+LeapDays(year)); }

(6)添加 LeapMonth函数该函数是用来计算农历Y年闰月的天数

int CEidolonDlg::LeapMonth(UINT year) {

return LunarInfo[year-1900] & 0xf;

}

(7)添加LeapDays函数,用来计算农历Y年M月的天数 int CEidolonDlg::LeapDays(int year) { if(LeapMonth(year)) { return (LunarInfo[year-1900] & 0x10000) ? 30: 29;

} else {

return 0;

– – 5

}

}

(8)添加MonthDays函数,计算Y年M月的总天数 int CEidolonDlg::MonthDays(UINT year, UINT month) { return (LunarInfo[year-1900] & (0x10000>>month))? 30: 29;} (9)添加GetLunar函数,根据输入的阳历日期来计算阴历日起 CustomDate CEidolonDlg::GetLunar(CustomDate date)

{

LONG offset; int i, leap=0, temp=0; CustomDate retdate;

offset=DaysFrom1900(date)-30; for(i=1900; i<2050 && offset>0; i++) { temp = YearDays(i); offset -= temp;

}

if(offset<0) { offset += temp; i--;

}

retdate.Year = i; leap = LeapMonth(i); bool isLeap = false;

for(i=1; i<13 && offset>0; i++) { if(leap>0 && i==(leap+1) && isLeap==false) { --i;

isLeap = true;

temp = LeapDays(retdate.Year);

} else

{

– –

6

}

}

temp = MonthDays(retdate.Year, i);

if(isLeap==true && i==(leap+1))

isLeap = false;

offset -= temp;

if(offset==0 && leap>0 && i==leap+1) { }

if(offset<=0) { }

retdate.Month = i; retdate.Day = offset ; retdate.IsRunYue=isLeap; return retdate;

offset += temp; --i; if(isLeap) else { }

isLeap = true; --i;

isLeap = false;

}

(10)添加GetLunarString函数,将阴历日期转化成天干地支字符串 char* CEidolonDlg::GetLunarString(CustomDate date) {

TCHAR szNongli[30], szNongliDay[10],szShuXiang[10];

const char *cTianGan[] = {\"甲\乙\丙\丁\戊\己\庚\辛\壬\癸\天干 const char *cDiZhi[] = {\"子\丑\寅\卯\辰\巳\午\未\申\酉\戌\亥\

//地支

const char *cShuXiang[] = {\"鼠\牛\虎\兔\龙\蛇\马\羊\猴\鸡\狗\猪\

– – 7

//生肖

const char *cDayName[] = { \"*\初一\初二\初三\初四\初五\

\"初六\初七\初八\初九\初十\ \"十一\十二\十三\十四\十五\ \"十六\十七\十八\十九\二十\ \"廿一\廿二\廿三\廿四\廿五\ \"廿六\廿七\廿八\廿九\三十\农历日期

const char *cMonName[] = {\"*\正\二\三\四\五\六\七\八\九\十\十一\腊\"};

//生成农历天干、地支、属相

int nShuXiang = ((date.Year - 4) % 60) % 12;

if ( nShuXiang < 0 || nShuXiang >= sizeof(cShuXiang)/sizeof(cShuXiang[0]) ) return NULL ;

wsprintf(szShuXiang,\"%s\int nTianGan = ((date.Year - 4) % 60) % 10;

if ( nTianGan < 0 || nTianGan >= sizeof(cTianGan)/sizeof(cTianGan[0]) ) {

return NULL; }

int nDiZhi = ((date.Year - 4) % 60) % 12;

if ( nDiZhi < 0 || nDiZhi >= sizeof(cDiZhi)/sizeof(cDiZhi[0]) ) return NULL;

wsprintf(szNongli,\"%s(%s%s)年\//生成农历月、日

if( date.Month < 0 || date.Month >= sizeof(cMonName)/sizeof(cMonName[0]) ) else

– –

return NULL;

wsprintf(szNongliDay,\"闰%s\strcpy(szNongliDay,cMonName[date.Month]);

8

if(date.IsRunYue)

strcat(szNongliDay,\"月\");

if( date.Day < 0 || date.Day >= sizeof(cDayName)/sizeof(cDayName[0]) )

return NULL;

strcat(szNongliDay,cDayName[date.Day]); strcat(szNongli,szNongliDay); sprintf(m_slunar,szNongli); return m_slunar;

3、 时钟算法

在新建备忘录的左上角有一个时钟,时钟的表盘只能是一个图片,指针是设备上下文绘制道到图片上。由于时间的不断变化,故绘制的表针也要不断变化,这需要用到CDC类的MoveTo和LineTo函数。

添加变量int m_hour,m_min,m_sec;//声明三个变量分别来保存时分秒。在定时器中设置这三个变量的值。

void CNewMemoDlg::OnTimer(UINT nIDEvent) {

// TODO: Add your message handler code here and/or call default CDC *pDC=m_Clock.GetDC(); CRect m_rect;

m_Clock.GetClientRect(m_rect);//获得绘制区域 DrawClock(pDC,m_rect);//绘制秒针 m_sec = m_sec+1; if(m_sec==60) { m_sec=0; m_min=m_min+1; if(m_min==60) { m_min=0; m_hour=m_hour+1; } }

CDialog::OnTimer(nIDEvent); }

表针的绘制:

void CNewMemoDlg::DrawClock(CDC* pDC,CRect m_rect) {

CRgn rgn;

HRGN m_hrgn;

m_hrgn = ::CreateEllipticRgn(25,22,75,72); rgn.Attach(m_hrgn);

CBrush m_brush (1,RGB(255,255,255)); pDC->SelectClipRgn(&rgn,0);

– – 9

pDC->FillRgn(&rgn,&m_brush); int x=m_rect.Width()/2;

int y=m_rect.Height()/2;//点(x,y)刚好是圆的中心

CPen SecondPen(PS_SOLID,1,RGB(255,0,0));//设置秒针画笔 pDC->SelectObject(&SecondPen); pDC->MoveTo (x,y);//设置画笔位置 pDC->LineTo

(x+(long)23*cos(pi/2-2*pi*m_sec/60.0),y-(long)23*sin(pi/2-2*pi*m_sec/60.0)); CPen MinutePen(PS_SOLID,2,RGB(0,0,0));//设置分针画笔 pDC->SelectObject(&MinutePen); pDC->MoveTo (x,y); pDC->LineTo

(x+(long)20*cos(pi/2-2*pi*m_min/60.0),y-(long)20*sin(pi/2-2*pi*m_min/60.0)); CPen HourPen(PS_SOLID,3,RGB(0,0,0));//设置时针画笔 pDC->SelectObject(&HourPen); pDC->MoveTo (x,y); pDC->LineTo

(x+(long)15*cos(pi/2-5*2*pi*m_hour/60.0),y-(long)15*sin(pi/2-5*2*pi*m_hour/60.0)); }

4、 添加系托盘

自定义函数响应函数OnTray,在主窗体头文件中声明该函数 afx_msg void OnTray(WPARAM wParam, LPARAM lParam);

在主体窗的宏映射中添加如下代码 ON_MESSAGE(WM_ONTRAY,OnTray); 在OnTray函数中设置鼠标右键单击及左键双击的一系列操作

void CEidolonDlg::OnTray(WPARAM wParam, LPARAM lParam) {

UINT uMouseMsg = (UINT) lParam;

if(uMouseMsg == WM_RBUTTONDOWN) { CMenu* pPopup = m_Menu.GetSubMenu(0); CPoint point; GetCursorPos(&point); SetForegroundWindow();//实现在别处点击鼠标,隐藏右键菜单 pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON TPM_VERTICAL, point.x,point.y,AfxGetApp()->m_pMainWnd,TPM_LEFTALIGN); }

if(uMouseMsg == WM_LBUTTONDBLCLK) //双击鼠标 { ShowWindow(SW_SHOWNOACTIVATE); //恢复窗口的显示 }

}

5、 自绘右键弹出菜单

在绘制菜单项的背景位图时,采用StretchBit方法,该方法用于绘制位图文件。(1) 创建一个以CMenu为基类的新类CCustomMen;

(2) 定义一个数据结构CMenuItemInfo,用来保存菜单信息。 (3) 添加DrawMenuTile函数,用来绘制弹出菜单左侧的标题栏

– –

|

10

void CCustomMenu::DrawMenuTitle(CDC *pDC, CRect rect) {

CBitmap m_bitmap;

m_bitmap.LoadBitmap(IDB_LEFTBITMAP); BITMAP m_size;

m_bitmap.GetBitmap(&m_size); CDC m_memdc;

m_memdc.CreateCompatibleDC(pDC); CGdiObject* m_oldobject;

m_oldobject = m_memdc.SelectObject(&m_bitmap); pDC->StretchBlt(0,0,28,rect.bottom,&m_memdc,0,0, m_size.bmWidth,m_size.bmHeight,SRCCOPY); m_bitmap.DeleteObject();

CFont* m_oldfont = pDC->SelectObject(&m_TitleFont); pDC->SetTextColor(RGB(255,0,0));

pDC->TextOut(rect.left+5,rect.Height()-10,\"桌\"); pDC->TextOut(rect.left+5,rect.Height()+10,\"面\"); pDC->TextOut(rect.left+5,rect.Height()+30,\"精\"); pDC->TextOut(rect.left+5,rect.Height()+50,\"灵\"); pDC->SelectObject(m_oldfont); }

(4) 添加DrawComMenu函数,用绘制址菜单项的背景位图

void CCustomMenu::DrawComMenu(CDC *pDC, CRect rect, BOOL select) { if(select) { pDC->SelectStockObject(BLACK_PEN); rect.DeflateRect(29,1,0,2); pDC->Rectangle(rect); CBitmap m_bitmap; m_bitmap.LoadBitmap(IDB_ITEMBITMAP); BITMAP m_size; m_bitmap.GetBitmap(&m_size); CDC m_memdc; m_memdc.CreateCompatibleDC(pDC); CGdiObject* m_oldobject; m_oldobject = m_memdc.SelectObject(&m_bitmap); pDC->StretchBlt(rect.left+1,rect.top+1,rect.Width()-2,rect.Height()-2, &m_memdc,0,0,m_size.bmWidth,m_size.bmHeight,SRCCOPY); m_bitmap.DeleteObject(); } else { pDC->FillSolidRect(rect,RGB(255,255,255)); } }

(5) 添加DrawItemText函数,用来会址菜单项的文本

void CCustomMenu::DrawItemText(CDC *pDC, LPSTR str, CRect rect) { rect.DeflateRect(40,0,0,0);

– – 11

pDC->DrawText(str,rect,DT_SINGLELINE|DT_VCENTER|DT_LEFT); }

(6) 添加DrawSeparater函数,用来绘制菜单分割条

void CCustomMenu::DrawSeparater(CDC *pDC, CRect rect) { if(pDC != NULL) { rect.DeflateRect(29,0,0,0); pDC->Draw3dRect(rect,RGB(0,0,255),RGB(0,0,255)); } }

(7) 添加ChangeMenuItm函数,用来修改菜单信息

BOOL CCustomMenu::ChangeMenuItem(CMenu *menu) { int m_index=0; if(menu != NULL) { int m_itemcount = menu->GetMenuItemCount(); //获得菜单项个数 for(int i=0;iGetMenuString(i,m_ItemLists[m_index].m_ItemText,MF_BYPOSITION); int m_itemID = menu->GetMenuItemID(i); //获得菜单项ID m_ItemLists[m_index].m_ItemID = m_itemID; if(m_itemID>0) { m_ItemLists[m_index].m_ItemIndex= m_ImageIndex; m_ImageIndex++; } //修改菜单项信息 menu->ModifyMenu(i,MF_OWNERDRAW | MF_BYPOSITION | MF_STRING, m_ItemLists[m_index].m_ItemID,(LPSTR)&(m_ItemLists[m_index])); m_index++; CMenu* m_subMenu = menu->GetSubMenu(i); if(m_subMenu) { ChangeMenuItem(m_subMenu); } } } return TRUE ;

(8) 重载MeasureItem函数,用来设置菜单项大小

void CCustomMenu::MeasureItem(LPMEASUREITEMSTRUCT lpStruct) { if(lpStruct->CtlType==ODT_MENU) { lpStruct->itemHeight = 22; //设置菜单项的高 lpStruct->itemWidth = 100; //设置菜单项的宽 CMenuItemInfo* m_iteminfo;

– –

12

m_iteminfo = (CMenuItemInfo*)lpStruct->itemData; if(m_iteminfo->m_ItemID == 0) { lpStruct->itemHeight = 1; //设置分隔条 } } }

(9) 重载DrawItem函数,用来重绘菜单项

void CCustomMenu::DrawItem(LPDRAWITEMSTRUCT lpStruct) { if(lpStruct->CtlType==ODT_MENU) { if(lpStruct->itemData == NULL) return; unsigned int m_state = lpStruct->itemState; //获得菜单项状态 CDC* pDC = CDC::FromHandle(lpStruct->hDC); CString str = ((CMenuItemInfo*)(lpStruct->itemData))->m_ItemText; LPSTR m_str = str.GetBuffer(str.GetLength()); int m_itemID = ((CMenuItemInfo*)(lpStruct->itemData))->m_ItemID; int m_itemicon = ((CMenuItemInfo*)(lpStruct->itemData))->m_ItemIndex; CRect m_rect = lpStruct->rcItem; pDC->SetBkMode(TRANSPARENT); //设置菜单项文本背景透明 switch(m_itemID) { case 0: //绘制分隔条 DrawSeparater(pDC,m_rect); break; default: //绘制菜单项和左侧标题 DrawComMenu(pDC,m_rect,m_state&ODS_SELECTED); DrawItemText(pDC,m_str,m_rect); DrawMenuTitle(pDC,m_rect); break; } } }

这是设计的主要代码,部分细节可参照程序源代码。

– – 13

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- howto234.com 版权所有 湘ICP备2022005869号-3

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务