写一个mfc时钟的代码,及其相关知识

time_t

time_t是库提供的一个数据类型 #define time_t long;

tm结构

在标准C/C++中,我们可通过tm结构来获得日期和时间,tm结构在time.h中的定义如下:

   struct tm {

   int tm_sec; /* 秒–取值区间为[0,59] */
   int tm_min; /* 分 - 取值区间为[0,59] */
   int tm_hour; /* 时 - 取值区间为[0,23] */
   int tm_mday; /* 一个月中的日期 - 取值区间为[1,31] */
  int tm_mon; /* 月份(从一月开始,0代表一月) - 取值区间为[0,11] */
  int tm_year; /* 年份,其值从1900开始 */

  int tm_wday; /* 星期–取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */

  int tm_yday; /* 从每年的1月1日开始的天数–取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推 */

  int tm_isdst; /* 夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负。*/
   };

      可以使用的函数是gmtime()和localtime()将time()获得的日历时间time_t结构体转换成tm结构体。

   其中gmtime()函数是将日历时间转化为世界标准时间(即格林尼治时间),并返回一个tm结构体来保存这个时间,而localtime()函数是将日历时间转化为本地时间。
c语言中 time()函数

函数简介

  函数名: time

  头文件:time.h

   函数原型:time_t time(time_t * timer)
   功能: 获取当前的系统时间,返回的结果是一个time_t类型,其实就是一个大整数,其值表示从CUT(Coordinated Universal Time)时间1970年1月1日00:00:00(称为UNIX系统的Epoch时间)到当前时刻的秒数。然后调用 localtime将time_t所表示的CUT时间转换为本地时间(我们是+8区,比CUT多8个小时)并转成struct tm类型,该类型的各数据成员分别表示年月日时分秒。
   补充说明:time函数的原型也可以理解为 long time(long *tloc),即返回一个long型整数。因为在time.h这个头文件中time_t实际上就是:
   #ifndef _TIME_T_DEFINED
   typedef long time_t; /* time value */
   #define _TIME_T_DEFINED /* avoid multiple defines of time_t */
   #endif
   即long。
函数应用举例
  程序例1:
   time函数获得日历时间。 日历时间,是用“ 从一个标准时间点到此时的时间经过的秒数”来表示的时间。这个标准时间点对不同的编译器来说会有所不同,但对一个 编译系统来说,这个标准时间点是不变的,该编译系统中的时间对应的日历时间都通过该标准时间点来衡量,所以可以说日历时间是“相对时间”,但是无论你在哪一个时区,在同一时刻对同一个标准时间点来说,日历时间都是一样的。
   #include < time.h>
   #include <stdio.h>
   #include < dos.h>
   int main(void)
   {
   time_t t; t = time(NULL);
   printf("The number of seconds since January 1, 1970 is %ld",t);
  return 0;
   }
程序例2:
   //time函数也常用于随机数的生成,用日历时间作为种子。
   #include <stdio.h>
   #include <time.h>
   #include< stdlib.h>
   int main(void)
  {
   int i;
    srand((unsigned) time(NULL));
   printf("ten random numbers from 0 to 99\n\n");
   for(i=0;i<10;i++)
   {
   printf("%d\n",rand()%100)
  }
   return 0;
   }
 程序例3:
   用time()函数结合其他函数(如:localtime、 gmtimeasctimectime)可以获得当前系统时间或是标准时间。
   #include <stdio.h>
   #include < stddef.h>
   #include <time.h>
   int main(void)
   {
   time_t timer;//time_t就是long int 类型
   struct tm *tblock;
   timer = time(NULL);//这一句也可以改成time(&timer);
   tblock = localtime(&timer);
   printf("Local time is: %s\n",asctime(tblock));
   return 0;
   }
 

CClientDC

 
  类CClientDC派生于CDC,在构造时调用了Windows函数GetDC,在析构时调用了ReleaseDC。这意味着和CClientDC对象相关的 设备上下文是窗口的客户区。
几种DC及区别 
 CClientDC:(客户区设备上下文)用于客户区的输出,与特定窗口关联,可以让开发者访问目标窗口中客户区,其构造函数中包含了GetDC,析构函数中包含了ReleaseDC:
   用法是:CClientDC dc(this);//this一般指向本窗口或当前活动视图dc.TextOut(10,10,str,str.GetLength());//利用dc输出文本,如果是在CScrollView中使用,还要注意调用OnPrepareDC(&dc)调整设备上下文的坐标。CPaintDC用于响应窗口重绘消息(WM_PAINT)时的绘图输出。CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中调用EndPaint()释放设备上下文。EndPaint()除了释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。CPaintDC也只能用在WM_PAINT消息处理之中。
   CWindowDC:关联一特定窗口,允许开发者在目标窗口的任何一部分进行绘图,包含边界与标题,这种DC同WM_NCPAINT消息一起发送
   CWindowDC与CClientDC,CPaintDC的区别:CWindowDC可在非客户区绘制图形,而CClientDC,CPaintDC只能在客户区绘制图形。CWindowDC下坐标原点是在屏幕的左上角,CClientDC,CPaintDC下坐标原点是在客户区的左上角。CClientDC与CPaintDC的区别:
   CPaintDC的对象一般用在OnPaint内以响应Windows消息WM_PAINT,自动完成绘制,在整个窗口内进行重画,维持原有窗口完整性。CClientDC应用在非响应Windows消息WM_PAINT的情况下,进行实时绘制,绘制的区域内被重画。
dc
DC(device context)叫设备环境或者设备描述表,它其实是GDI内部保存数据的一种数据结构。此结构中的属性内容与特定的输出设备(显示器、打印机等)相关,属性定义了GDI函数的工作细节。
总之,你要使用GDI绘图函数,就需要一个DC句柄。
MFC中把和DC相关的都封装成类。CDC是一个抽象基类,可以访问整个显示器和打印机等。CClientDC类和窗口客户区关联,能用于显示客户区相关内容。
DC是 "Device Content" , MS VC++ 的 MFC图形设备接口 的 设备描述表。它是MFC的主要对象之一。通过CDC类进行各种绘图操作,例如选笔,选色,选涂色的花样,选“画”字的大小字体,画直线曲线多变性,画图像(照片)等,可以“画”到屏幕上,“画”到打印机上,“画”到文件里。

afx_msg

  AFX前缀
  Afx前缀是微软MFC一个小组的名称简写,并没有别的意义。 MFC的很多代码,包括全局函数名、宏、头文件名都使用了"Afx"。 Afx*.h是一组MFC的核心头文件, 比如: afxwin.h 定义MFC的核心和标准组件 afxext.h 定义MFC的扩展 afxdisp.h 是MFC自动化支持的类定义头文件 afxdb.h 是MFC的ODBC类封装 AFX_msg  
     在头文件(DrawView.h)中声明消息响应函数原型。
   //{{AFX_MSG(CDrawView) //注释宏
   afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
   //}}AFX_MSG //注释宏
   说明:
   在注释宏之间的声明在VC中灰色显示。afx_msg宏表示声明的是一个消息响应函数
   afx_msg消息函数 
   应用程序框架产生的消息映射函数
   例如:afx_msg void OnBnClickedButton1(); 其中 afx_msg为消息标志,它向系统声明:有消息映射到函数实现体;而在map宏定义中,就有具体消息和此函数的映射定义(可以是自定义,也可以是系统自动完成的)
   afx是 application framework
   如定义一个Edit的Change处理函数:
   一、在类的头文件(*.h)中增加 :
   //{{AFX_MSG(CDialogDemo)
   afx_msg void OnChangeEdit1();
   //}}AFX_MSG
   二、在类的实现文件(*.cpp)中增加:
   1.消息定义( ON_EN_CHANGE):
   BEGIN_MESSAGE_MAP(CDialogDemo, CDialog)
   //{{AFX_MSG_MAP()
   ON_EN_CHANGE(IDC_EDIT1, OnChangeEdit1)
   //}}AFX_MSG_MAP
   END_MESSAGE_MAP()
   2.执行函数:
   void CDialogDemo::OnChangeEdit1()
   {
   // TODO: Add your control notification handler code here
   ……
   }
   在afxwin.h中afx_msg的解释:
   #ifndef afx_msg
   #define afx_msg // intentional placeholder
   #endif
   没什么意思.只是定义了这个符号而已. 这个对编译器来说,相当于什么都没有,对于人来说,我们可以看到这样的符号. 对于类向导来说.这个符号才是有意义的.它是一个消息处理函数的前缀. 类向导生成的消息函数,分发函数,事件响应函数都以这个为前缀. 如果去掉了,向导将不能识别
 
在给对话框添加的类中enum={IDD=DIALOG}时经常报错,原因是没有加#include"resource.h"
但是在resource.h中#define 的值却报错(此类型没有存储类或类型说明符)这是为什么
1. (此情况经常出现在大型工程项目中)如果存在两个类的头文件a.h和b.h,在a.h中有这样的语句:#include "b.h",在b.h文件中有这样的语句:#include "a.h"   且在一个类中有另一个类的对象时   那么就会出现这样的错误。
2. 没有包含要定义的类的头文件。
3.项目中少加了宏定义,导致头文件重复定义或相应宏无法识别。
4.当有多个头文件时,顺序写反也可能导致相关的错误,其根本是头文件中的预编译语句被隐去了。
e.g

#include <stdio.h>
#include <Windows.h>
#include <WinCrypt.h>
#include <string.h>

如果把第二个和第三个写反,一个宏定义就被#if给注了,就会出现类似错误
 
(未完待续)

转载于:https://www.cnblogs.com/langzi93/archive/2012/04/29/mfc.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值