老师布置的作业:让写一个电子钟,发上来留个纪念

            大概说下思路,方便以后回忆~
            在窗口客户区 绘制一个圆,圆心为逻辑坐标。这样,它窗体设备坐标的转换关系如下:
老师布置的作业:让写一个电子钟,发上来留个纪念_第1张图片
   1. 从设备坐标系(x,y)到逻辑坐标系(x',y')
      x' = x - width()/2
      y' = y + height()/2

   2. 从逻辑坐标系(x',y')到设备坐标系(x,y)
       x = x' + width()/2
       y = height()/2 - y'

转换成代码表示如下:
     
 1 ; // ######################################################################
 2 ; //  功  能: 从逻辑坐标系到设备坐标系
 3 ; //  函数名: ConvlogicPos2DevicePos
 4 ; //  参数 
 5 ; //        ptLogicPos:  逻辑坐标
 6 ; //        pptDevicePos: 输出参数 转换后的设备坐标
 7 ; // ######################################################################
 8 ConvlogicPos2DevicePos proc ptLogicPos:POINT, pptDevicePos:ptr POINT
 9     assume esi:ptr POINT
10         mov esi,pptDevicePos
11         mov eax, ptLogicPos.x
12         add eax, g_ptCoor.x
13         mov [esi].x, eax
14         
15         mov eax, g_ptCoor.y
16         sub eax, ptLogicPos.y
17         mov [esi].y, eax
18     assume esi:nothing
19     
20     ret
21 ConvlogicPos2DevicePos endp
22
23 ; // ######################################################################
24 ; //  功  能: 从设备坐标系到逻辑坐标系
25 ; //  函数名: ConvDevicePos2logicPos
26 ; //  参数 
27 ; //        ptDevicePos: 设备坐标
28 ; //        pptLogicPos: 输出参数 转换后的逻辑坐标
29 ; // ######################################################################
30 ConvDevicePos2logicPos proc ptDevicePos:POINT, pptLogicPos:ptr POINT
31     assume esi:ptr POINT
32         mov esi, pptLogicPos
33         
34         mov eax, ptDevicePos.x
35         sub eax, g_ptCoor.x
36         mov [esi].x, eax
37     
38         mov eax, ptDevicePos.y
39         add eax, g_ptCoor.y
40         mov [esi].y, eax
41     assume esi:nothing
42     
43     ret
44 ConvDevicePos2logicPos endp

      关于 钟表指针的绘制就比较简单了,用三角函数,根据分钟数,秒数,小时数,可以计算出相应的角度,再乘以半径就可以得到指定圆的交点坐标了,代码如下:
  1 ; // #############################################################
  2 ; //  设置指针长度
  3 ; // #############################################################
  4 SetPointLong proc hDC:HDC, dwPointType:DWORD, pptCoor:ptr POINT
  5     LOCAL @dwSize:DWORD
  6     assume esi:ptr POINT
  7         mov    esi,pptCoor
  8         
  9         . if  dwPointType  ==  IDT_POINTTYPE_SECOND
 10             mov @dwSize,  25
 11             
 12         .elseif  dwPointType  ==  IDT_POINTTYPE_MIN
 13             mov @dwSize,  35
 14             
 15         .elseif  dwPointType  ==  IDT_POINTTYPE_HOUR
 16             mov @dwSize,  45
 17             
 18         .endif
 19         
 20         mov   eax, g_ptCoor.y
 21         SUB   EAX, @dwSize
 22         mov   [esi].y, eax
 23         
 24         mov   eax, g_ptCoor.x
 25         SUB   EAX, @dwSize
 26         mov   [esi].x, eax
 27     
 28     assume esi:nothing
 29     
 30     ret
 31 SetPointLong endp
 32
 33 ; // ######################################################################
 34 ; //  功  能:绘制钟表指针
 35 ; //  函数名: DrawColckPoint
 36 ; //  参数 
 37 ; //        hWnd: 窗口句柄
 38 ; //      nColor: 秒针的颜色
 39 ; // ######################################################################
 40 DrawColckPoint proc hDC:HDC, dwPointType:DWORD, nColor:DWORD
 41     LOCAL @sysTime:SYSTEMTIME
 42     LOCAL @ptCoor:POINT
 43     LOCAL @hPen:HPEN
 44     LOCAL @halfNum:WORD
 45     LOCAL @nX:DWORD
 46     LOCAL @nY:DWORD
 47     LOCAL @dwRadian:DWORD
 48     LOCAL @dwTmpTime:WORD
 49     LOCAL @dwSecSize:WORD
 50
 51     assume esi:ptr SYSTEMTIME
 52         lea esi,@sysTime
 53         invoke RtlZeroMemory, esi,  sizeof  @sysTime
 54         invoke GetLocalTime, esi
 55         mov @halfNum,  180
 56         
 57         xor edx, edx
 58         xor eax, eax
 59         mov @hPen, eax
 60         
 61         . if  dwPointType  ==  IDT_POINTTYPE_SECOND
 62             invoke CreatePen,PS_SOLID,  1 , nColor
 63             MOV @hPen, eax
 64             mov ax, [esi].wSecond;
 65             mov @dwTmpTime, ax
 66             mov @dwSecSize,  6
 67             
 68         .elseif  dwPointType  ==  IDT_POINTTYPE_MIN
 69             invoke CreatePen,PS_SOLID,  2 , nColor
 70             MOV @hPen, eax
 71             mov ax, [esi].wMinute;
 72             mov @dwTmpTime, ax
 73             mov @dwSecSize,  6
 74         
 75         .elseif  dwPointType  ==  IDT_POINTTYPE_HOUR
 76             invoke CreatePen,PS_SOLID,  3 , nColor
 77             MOV @hPen, eax
 78             mov ax, [esi].wHour;  
 79             mov @dwTmpTime, ax
 80             mov @dwSecSize,  30   
 81         .endif
 82         
 83         invoke SelectObject,hDC, @hPen
 84         
 85         . if  dwPointType  ==  IDT_POINTTYPE_HOUR
 86             add @dwTmpTime,  9
 87             . if  @dwTmpTime  >   12
 88                 sub @dwTmpTime,  12
 89             .endif
 90             
 91             mov ax,  12
 92             sub ax, @dwTmpTime
 93             . if  ax  ==   0
 94                 mov @dwTmpTime,  12
 95             . else
 96                 mov @dwTmpTime, ax
 97             .endif
 98         . else
 99             add @dwTmpTime,  45
100             . if  @dwTmpTime  >   60
101                 sub @dwTmpTime,  60
102             .endif
103             
104             mov ax,  60
105             sub ax, @dwTmpTime
106             . if  ax  ==   0
107                 mov @dwTmpTime,  60
108             . else
109                 mov @dwTmpTime, ax
110             .endif
111         .endif
112         
113         mov ax, @dwTmpTime
114         mul @dwSecSize
115         mov @dwSecSize, ax; //  相应秒数D 
116     
117         FLDPI 
118         FIDIV @halfNum  ; //  得到 1°角的弧度值
119         FIMUL @dwSecSize  ; //  得到应秒数角的弧度值
120         FSTP @dwRadian ;
121         FLD  @dwRadian
122         
123         FCOS    ; //  得到单位圆的X
124         FSTP  @nX
125         FLD  @dwRadian; //  再保存一次
126         FSIN    ; //  得到单位圆的Y
127         FSTP  @nY
128         
129         invoke SetPointLong, hDC, dwPointType, addr @ptCoor
130         
131         FLD   @nY
132         FIMUL @ptCoor.y
133         FISTP @ptCoor.y
134         
135         FLD   @nX
136         FIMUL @ptCoor.x
137         FISTP @ptCoor.x
138         
139         push  NULL          ; //  不要返回值
140         push  g_ptCoor.y     ; //  Y坐标
141         push  g_ptCoor.x     ; //  X坐标
142         push  hDC
143         call MoveToEx       ; //  移动到指定位置
144         
145         invoke ConvlogicPos2DevicePos, @ptCoor, addr @ptCoor
146
147         push @ptCoor.y
148         push  @ptCoor.x     ; //  X坐标
149         push  hDC
150         call  LineTo
151         invoke DeleteObject, @hPen;
152     assume esi:nothing
153     
154     ret
155 DrawColckPoint endp

最后就是绘制方面,为了防止闪烁,用了双缓存,建了个内存DC,代码如下:
 1 OnPaintSub proc  hWnd:HWND
 2     LOCAL @ps:PAINTSTRUCT
 3     LOCAL @hDlgDC:HDC
 4     LOCAL @hMemDC:HDC
 5     LOCAL @hBmp:HBITMAP
 6     LOCAL @hBrush:HBRUSH
 7     LOCAL @tmpBuf:DWORD
 8     
 9         ; //  得到窗口DC
10         invoke BeginPaint, hWnd, addr @ps
11         mov @hDlgDC, eax
12         
13         mov eax, g_Rect.right
14         sub eax, g_Rect.left
15         mov @tmpBuf, eax
16         
17         mov eax, g_Rect.bottom
18         sub eax, g_Rect.top
19         invoke CreateCompatibleBitmap, @hDlgDC, @tmpBuf,eax
20         mov @hBmp, eax
21         
22         invoke CreateCompatibleDC, @hDlgDC
23         mov @hMemDC, eax
24         
25         invoke CreateSolidBrush, 242448h
26         mov @hBrush, eax 
27         
28         invoke SelectObject,@hMemDC, @hBmp
29         invoke SelectObject,@hMemDC, @hBrush
30         
31         invoke FillRect, @hMemDC,addr g_Rect, @hBrush;
32         
33         invoke DrawClockBK, @hMemDC             ; //  绘制钟表背景
34         invoke ShowTimeText, @hMemDC, IDT_COLOR_TEXT  ; //  绘制文本时间字符
35         invoke DrawColckPoint, @hMemDC, IDT_POINTTYPE_HOUR,  0
36         invoke DrawColckPoint, @hMemDC, IDT_POINTTYPE_MIN,  0
37         invoke DrawColckPoint, @hMemDC, IDT_POINTTYPE_SECOND, 00000FFh
38         
39         mov eax, g_Rect.bottom
40         sub eax, g_Rect.top
41         invoke BitBlt, @hDlgDC,  0 0 , @tmpBuf, eax, @hMemDC,  0 0 , SRCCOPY
42         
43         invoke DeleteDC, @hMemDC;
44         invoke DeleteObject, @hBrush;
45         invoke DeleteObject, @hBmp;
46         invoke EndPaint, hWnd, addr @ps;
47     
48     ret
49 OnPaintSub endp

            最后贴下效果图:
                   老师布置的作业:让写一个电子钟,发上来留个纪念_第2张图片

            恩,就这么多了,下面给出完整代码。
源码下载地址          /Files/besterChen/besTimer/besTimer.rar

你可能感兴趣的:(老师布置的作业:让写一个电子钟,发上来留个纪念)