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行的顺序是这样的?最后映射点。求指点。