废话少叙。
理解DisplayTime( )是理解本程序的核心!
此函数如下所示:
void DisplayTime (HDC hdc, BOOL f24Hour, BOOL fSuppress)
{
SYSTEMTIME st ;
GetLocalTime(&st) ;
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) ;
}
首先,此函数用GetLocalTime(&st)取得当前的时间,st的结构如下:
typedef struct _SYSTEMTIME { // st
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME;
Oh, 一看就明白,wHour保存小时;wMinute保存分钟;wSecond保存秒数。
接着这句;
if( f24Hour)
DisplayTwoDigits (hdc, st.wHour, fSuppress) ;
此时f24Hour的值是什么呢?
如果你的电脑是以24 hour显示,那么它等于1。
为什么呢?因为:
case WM_CREATE:
hBrushRed = CreateSolidBrush (RGB (255, 0, 0)) ;
SetTimer (hwnd, ID_TIMER, 1000, NULL) ;// fall through
case WM_SETTINGCHANGE:
GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_ITIME, szBuffer, 2) ;
f24Hour = (szBuffer[0] == '1') ;
你看到了,第一个case并未与
break搭配,这意味着在收到WM_CREATE时,将会顺序执行接下来的语句,而WM_SETTINGCHANGE将被略去, f24Hour 将被赋值为 1。
接下来是:
DisplayTwoDigits (hdc, st.wHour, fSuppress) ;
好再看一看它的定义:
void DisplayTwoDigits (HDC hdc, int iNumber, BOOL fSuppress)
{
if (!fSuppress || (iNumber / 10 != 0))
DisplayDigit (hdc, iNumber / 10) ;
OffsetWindowOrgEx (hdc, -42, 0, NULL) ;
DisplayDigit (hdc, iNumber % 10) ;
OffsetWindowOrgEx (hdc, -42, 0, NULL) ;
}
if (!fSuppress || (iNumber / 10 != 0))
DisplayDigit (hdc, iNumber / 10) ;
这句在做什么呢?fSuppress标志着是否禁止显示03:46前面的零,假如为1,则03:46à 3:46;
再假设现在的时间是13:56:23。
好了,不管fSuppress等于多少,肯定if(TRUE)了,这回看出iNumber / 10 != 0的作用了,它设置了DisplayTwoDigits (HDC hdc, int iNumber, BOOL fSuppress)显示两个数字的条件。接下来DisplayDigit (hdc, iNumber / 10)将显示数字1。如何显示呢?
void DisplayDigit (HDC hdc, int iNumber)
{
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
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 ;
for (iSeg = 0 ; iSeg < 7 ; iSeg++)
if (fSevenSegment [iNumber][iSeg])
Polygon (hdc, ptSegment [iSeg], 6) ;
}
以上大家可要看好了,这可是鬼花活呀!不太好讲,好比绣花。你还不知道查尔斯的全称吗?他的全称是—插尔死·西方不败·败怎的?
我说:“Hans, 名字后面不好用 ?吧!”
Hans:“少插嘴,不知道入乡随俗吗?”
“很好!,很好。”
再接下来,OffsetWindowOrgEx (hdc, -42, 0, NULL) 上场了,它是做何工作的呢?
The OffsetWindowOrgEx function modifies the window origin for a device context using the specified horizontal and vertical offsets.
其定义:
BOOL OffsetWindowOrgEx(
HDC hdc, // handle to device context
int nXOffset, // horizontal offset
int nYOffset, // vertical offset
LPPOINT lpPoint // pointer to structure receiving the original origin
);
good!
此函数调整window origin 。
那原来的原点在哪里呢?在这里:
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
SetMapMode (hdc, MM_ISOTROPIC) ;
SetWindowExtEx (hdc, 276, 72, NULL) ;
SetViewportExtEx (hdc, cxClient, cyClient, NULL) ;
SetWindowOrgEx (hdc, 138, 36, NULL) ;
SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ;
OK.
SetMapMode (hdc, MM_ISOTROPIC) ;
SetWindowExtEx (hdc, 276, 72, NULL) ;
这两个语句建立了一个逻辑横坐标为276个单位,纵坐标为72个单位的坐标系。
逻辑是什么意思?意思是“世上本没有路,走的人多了也就成了路。”
我说:“Hans,离谱了吧!”
Hans: 我哪里知道我会想起这句话,坐标非坐标,是名坐标。
我说:“阿弥陀佛!少跟我玩这个!”
这句话什么意思呢?我个人的理解是:在人脑中要显示的东西,在人脑中的坐标!
哈哈哈哈,它当然与在显示设备上的东西有差别,比如我想起一艘航空母舰,如果要显示在显示设备上,不可能用1:1的比例吧,至少现在不可能。
SetViewportExtEx (hdc, cxClient, cyClient, NULL) ;
SetWindowOrgEx (hdc, 138, 36, NULL) ;
SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ;
好的,SetViewportExtEx (hdc, cxClient, cyClient, NULL) 把整个客户区都当成显示区;
SetWindowOrgEx (hdc, 138, 36, NULL) ;把逻辑中心移到了原来逻辑坐标系的中心,原来的中心在哪?当然在那个左上角呀!同志们,这就是我那艘航空母舰的几何中心啊!
SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL);把显示的中心设在了客户区的中心,同志们,这就是我们的视口的中心呀,哈哈哈哈,我只听过大口小口,从未听过视口,嘴能吃饭也能吐饭,视口能吃图象也能吐图像吗?我不知道,你知道吗?
你当然也看出来了“心口如一”呀,不是如一而是绝对是一!我那艘航空母舰的几何中心和我那张视口的中心那是“一心一意”的!
就这样,哈哈,这几条语句把坐标的中心移到了时间最左上的数字角,你若问我具体在哪里呢那你还不如打死我,我没有计算过,我只知道我的航空母舰肯定在窗口的中心,并且心心相印,想起这四个字,Hans想说:“我们的大学生活是多没好呀!”大学生活好不好与心心相印有关吗?我说:Hans你跑题了吧?