《Windows程序设计》之数字时钟

void DisplayDigit(HDC hdc,int iNumber)
{
	//这个数组是根据所要显示的数字来判断显示7个六边形是的哪几个
	static BOOL fSevenSegment[10][7]={
					1,1,1,0,1,1,1,//0
					0,0,1,0,0,1,0,//1
					1,0,1,1,1,0,1,//2
					1,0,1,1,0,1,1,//3
					0,1,1,1,0,1,0,//4
					1,1,0,1,0,1,1,//5
					1,1,0,1,1,1,1,//6
					1,0,1,0,0,1,0,//7
					1,1,1,1,1,1,1,//8
					1,1,1,1,0,1,1};//9
	//7个六边形的42个点的坐标,总84个数字
	static POINT ptSegment[7][6]={7,6,11,2,31,2,35,6,31,10,11,10,
									6,7,10,11,10,31,6,35,2,31,2,11,
									36,7,40,11,40,31,36,35,32,31,32,11,
									7,36,11,32,31,32,35,36,31,40,11,40,
									6,37,10,41,10,61,6,65,2,61,2,41,
									36,37,40,41,40,61,36,65,32,61,32,41,
									7,66,11,62,31,62,35,66,31,70,11,70};
	int iSeg;
	//总共有7个六边形,要进行遍历,通过fSevenSegment来判断是否显示
	for(iSeg=0;iSeg<7;iSeg++)
		//根据输入的数字来选择10组中的哪一组来判断
		if(fSevenSegment[iNumber][iSeg])
			//根据坐标画出多边形
			Polygon(hdc,ptSegment[iSeg],6);
}

void DisplayTwoDigits(HDC hdc,int iNumber,BOOL fSuppress)
{
	//时如果第一位是0,则不不显示,在此判断
	if(!fSuppress||iNumber/10!=0)
		DisplayDigit(hdc,iNumber/10);
	//设备环境窗口原点水平负方向(右)42个逻辑单位
	OffsetWindowOrgEx(hdc,-42,0,NULL);
	//时、分、秒中两位数的后一位显示
	DisplayDigit(hdc,iNumber%10);
	//设备环境窗口原点水平负方向(右)42个逻辑单位
	OffsetWindowOrgEx(hdc,-42,0,NULL);
}

void DisplayColon(HDC hdc)
{
	//画两个方格来分开时、分、秒
	POINT ptColon[2][4]={2,21,6,17,10,21,6,25,
						2,51,6,47,10,51,6,55};
	Polygon(hdc,ptColon[0],4);
	Polygon(hdc,ptColon[1],4);
	//设备环境窗口原点水平负方向(右)12个逻辑单位
	OffsetWindowOrgEx(hdc,-12,0,NULL);
}

void DisplayTime(HDC hdc,BOOL f24Hour,BOOL fSuppress)
{
	//时间结构体
	SYSTEMTIME st;
	//获取当前系统时间和日期
	GetLocalTime(&st);
	//画时,是否是24小时显示
	if(f24Hour)
		DisplayTwoDigits(hdc,st.wHour,fSuppress);
	else
		DisplayTwoDigits(hdc,(st.wHour%=12)?st.wHour:12,fSuppress);
	//画时、分、秒中间的分格符
	DisplayColon(hdc);
	//画分
	DisplayTwoDigits(hdc,st.wMinute,FALSE);
	//画分格符
	DisplayColon(hdc);
	//画秒
	DisplayTwoDigits(hdc,st.wSecond,FALSE);
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	static BOOL f24Hour,fSuppress;
	static HBRUSH hBrushRed;
	static int cxClient,cyClient;
	HDC hdc;
	PAINTSTRUCT ps;
	TCHAR szBuffer[2];
	switch(message)
	{
	case WM_CREATE:
		//创建一个逻辑刷子
		hBrushRed=CreateSolidBrush(RGB(255,0,0));
		//设置定时器
		SetTimer(hwnd,ID_TIMER,1000,NULL);
	case WM_SETTINGCHANGE:
		//得到系统的一些信息
		//如果szBuffer == L"0"表示12小时制,szBuffer == L"1"表示24小时制
		GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_ITIME,szBuffer,2);
		//是否是24h制
		f24Hour=(szBuffer[0]=='1');
		//去掉小时显示开头为0的情况
		GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_ITLZERO,szBuffer,2);
		fSuppress=(szBuffer[0]=='0');
		//刷新区域
		InvalidateRect(hwnd,NULL,TRUE);
		return 0;
	case WM_SIZE:
		cxClient=LOWORD(lParam);
		cyClient=HIWORD(lParam);
		return 0;
	case WM_TIMER:
		//每格一秒刷新一次
		InvalidateRect(hwnd,NULL,TRUE);
		return 0;
	case WM_PAINT:
		hdc=BeginPaint(hwnd,&ps);
		//逻辑单位转换成具有均等比例轴的任意单位,即沿X轴的一个单位等于沿Y轴的一个单位。
		SetMapMode(hdc,MM_ISOTROPIC);
		//设置窗口区域为276*72
		SetWindowExtEx(hdc,276,72,NULL);
		//用指定的值来设置指定设备环境坐标的X轴、Y轴范围
		SetViewportExtEx(hdc,cxClient,cyClient,NULL);
		//设置设备环境的窗口原点
		SetWindowOrgEx(hdc,138,36,NULL);
		//映射逻辑点(0,0)到设备点 (cxClient/2-65, cyClient)
		SetViewportOrgEx(hdc,cxClient/2-65,cyClient/2,NULL);
		SelectObject(hdc,GetStockObject(NULL_PEN));
		SelectObject(hdc,hBrushRed);
		//显示时间
		DisplayTime(hdc,f24Hour,fSuppress);
		EndPaint(hwnd,&ps);
		return 0;
	case WM_DESTROY:
		KillTimer(hwnd,ID_TIMER);
		DeleteObject(hBrushRed);
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd,message,wParam,lParam);
}

书中CLOCK的部分代码。

38----42行与114----123行是我不懂的地方。

在逻辑坐标中,哪个是方向是正,哪个方向是负,代码中没有设置。

通过38----42行我自己的判断,向右是负方向,但是不知道为什么,还有那一些点的设置。

为什么114----123行的顺序是这样的?最后映射点。求指点。

你可能感兴趣的:(timer,windows,user,null,callback)