老師布置的作業(yè):讓寫一個電子鐘,發(fā)上來留個紀念
Posted on 2010-07-27 22:04 besterChen 閱讀(3556) 評論(12) 編輯 收藏 引用 所屬分類: 項目工程 大概說下思路,方便以后回憶~
在窗口客戶區(qū) 繪制一個圓,圓心為邏輯坐標。這樣,它窗體設備坐標的轉換關系如下:
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
;// 函數(shù)名: ConvlogicPos2DevicePos
4
;// 參數(shù)
5
;// ptLogicPos: 邏輯坐標
6
;// pptDevicePos: 輸出參數(shù) 轉換后的設備坐標
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
;// 函數(shù)名: ConvDevicePos2logicPos
26
;// 參數(shù)
27
;// ptDevicePos: 設備坐標
28
;// pptLogicPos: 輸出參數(shù) 轉換后的邏輯坐標
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
;//######################################################################2
;// 功 能: 從邏輯坐標系到設備坐標系3
;// 函數(shù)名: ConvlogicPos2DevicePos4
;// 參數(shù) 5
;// ptLogicPos: 邏輯坐標6
;// pptDevicePos: 輸出參數(shù) 轉換后的設備坐標7
;//######################################################################8
ConvlogicPos2DevicePos proc ptLogicPos:POINT, pptDevicePos:ptr POINT9
assume esi:ptr POINT10
mov esi,pptDevicePos11
mov eax, ptLogicPos.x12
add eax, g_ptCoor.x13
mov [esi].x, eax14
15
mov eax, g_ptCoor.y16
sub eax, ptLogicPos.y17
mov [esi].y, eax18
assume esi:nothing19
20
ret21
ConvlogicPos2DevicePos endp22

23
;//######################################################################24
;// 功 能: 從設備坐標系到邏輯坐標系25
;// 函數(shù)名: ConvDevicePos2logicPos26
;// 參數(shù) 27
;// ptDevicePos: 設備坐標28
;// pptLogicPos: 輸出參數(shù) 轉換后的邏輯坐標29
;//######################################################################30
ConvDevicePos2logicPos proc ptDevicePos:POINT, pptLogicPos:ptr POINT31
assume esi:ptr POINT32
mov esi, pptLogicPos33
34
mov eax, ptDevicePos.x35
sub eax, g_ptCoor.x36
mov [esi].x, eax37
38
mov eax, ptDevicePos.y39
add eax, g_ptCoor.y40
mov [esi].y, eax41
assume esi:nothing42
43
ret44
ConvDevicePos2logicPos endp關于 鐘表指針的繪制就比較簡單了,用三角函數(shù),根據(jù)分鐘數(shù),秒數(shù),小時數(shù),可以計算出相應的角度,再乘以半徑就可以得到指定圓的交點坐標了,代碼如下:
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
;// 函數(shù)名: DrawColckPoint
36
;// 參數(shù)
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;// 相應秒數(shù)D
116
117
FLDPI
118
FIDIV @halfNum ;// 得到 1°角的弧度值
119
FIMUL @dwSecSize ;// 得到應秒數(shù)角的弧度值
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
;//#############################################################2
;// 設置指針長度3
;//#############################################################4
SetPointLong proc hDC:HDC, dwPointType:DWORD, pptCoor:ptr POINT5
LOCAL @dwSize:DWORD6
assume esi:ptr POINT7
mov esi,pptCoor8
9
.if dwPointType == IDT_POINTTYPE_SECOND10
mov @dwSize, 2511
12
.elseif dwPointType == IDT_POINTTYPE_MIN13
mov @dwSize, 3514
15
.elseif dwPointType == IDT_POINTTYPE_HOUR16
mov @dwSize, 4517
18
.endif19
20
mov eax, g_ptCoor.y21
SUB EAX, @dwSize22
mov [esi].y, eax23
24
mov eax, g_ptCoor.x25
SUB EAX, @dwSize26
mov [esi].x, eax27
28
assume esi:nothing29
30
ret31
SetPointLong endp32

33
;//######################################################################34
;// 功 能:繪制鐘表指針35
;// 函數(shù)名: DrawColckPoint36
;// 參數(shù) 37
;// hWnd: 窗口句柄38
;// nColor: 秒針的顏色39
;//######################################################################40
DrawColckPoint proc hDC:HDC, dwPointType:DWORD, nColor:DWORD41
LOCAL @sysTime:SYSTEMTIME42
LOCAL @ptCoor:POINT43
LOCAL @hPen:HPEN44
LOCAL @halfNum:WORD45
LOCAL @nX:DWORD46
LOCAL @nY:DWORD47
LOCAL @dwRadian:DWORD48
LOCAL @dwTmpTime:WORD49
LOCAL @dwSecSize:WORD50

51
assume esi:ptr SYSTEMTIME52
lea esi,@sysTime53
invoke RtlZeroMemory, esi, sizeof @sysTime54
invoke GetLocalTime, esi55
mov @halfNum, 18056
57
xor edx, edx58
xor eax, eax59
mov @hPen, eax60
61
.if dwPointType == IDT_POINTTYPE_SECOND62
invoke CreatePen,PS_SOLID, 1, nColor63
MOV @hPen, eax64
mov ax, [esi].wSecond;65
mov @dwTmpTime, ax66
mov @dwSecSize, 667
68
.elseif dwPointType == IDT_POINTTYPE_MIN69
invoke CreatePen,PS_SOLID, 2, nColor70
MOV @hPen, eax71
mov ax, [esi].wMinute;72
mov @dwTmpTime, ax73
mov @dwSecSize, 674
75
.elseif dwPointType == IDT_POINTTYPE_HOUR76
invoke CreatePen,PS_SOLID, 3, nColor77
MOV @hPen, eax78
mov ax, [esi].wHour; 79
mov @dwTmpTime, ax80
mov @dwSecSize, 30 81
.endif82
83
invoke SelectObject,hDC, @hPen84
85
.if dwPointType == IDT_POINTTYPE_HOUR86
add @dwTmpTime, 987
.if @dwTmpTime > 1288
sub @dwTmpTime, 1289
.endif90
91
mov ax, 1292
sub ax, @dwTmpTime93
.if ax == 094
mov @dwTmpTime, 1295
.else96
mov @dwTmpTime, ax97
.endif98
.else99
add @dwTmpTime, 45100
.if @dwTmpTime > 60101
sub @dwTmpTime, 60102
.endif103
104
mov ax, 60105
sub ax, @dwTmpTime106
.if ax == 0107
mov @dwTmpTime, 60108
.else109
mov @dwTmpTime, ax110
.endif111
.endif112
113
mov ax, @dwTmpTime114
mul @dwSecSize115
mov @dwSecSize, ax;// 相應秒數(shù)D 116
117
FLDPI 118
FIDIV @halfNum ;// 得到 1°角的弧度值119
FIMUL @dwSecSize ;// 得到應秒數(shù)角的弧度值120
FSTP @dwRadian ;121
FLD @dwRadian122
123
FCOS ;// 得到單位圓的X124
FSTP @nX125
FLD @dwRadian;// 再保存一次126
FSIN ;// 得到單位圓的Y127
FSTP @nY128
129
invoke SetPointLong, hDC, dwPointType, addr @ptCoor130
131
FLD @nY132
FIMUL @ptCoor.y133
FISTP @ptCoor.y134
135
FLD @nX136
FIMUL @ptCoor.x137
FISTP @ptCoor.x138
139
push NULL ;// 不要返回值140
push g_ptCoor.y ;// Y坐標141
push g_ptCoor.x ;// X坐標142
push hDC143
call MoveToEx ;// 移動到指定位置144
145
invoke ConvlogicPos2DevicePos, @ptCoor, addr @ptCoor146

147
push @ptCoor.y148
push @ptCoor.x ;// X坐標149
push hDC150
call LineTo151
invoke DeleteObject, @hPen;152
assume esi:nothing153
154
ret155
DrawColckPoint endp最后就是繪制方面,為了防止閃爍,用了雙緩存,建了個內(nèi)存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
OnPaintSub proc hWnd:HWND2
LOCAL @ps:PAINTSTRUCT3
LOCAL @hDlgDC:HDC4
LOCAL @hMemDC:HDC5
LOCAL @hBmp:HBITMAP6
LOCAL @hBrush:HBRUSH7
LOCAL @tmpBuf:DWORD8
9
;// 得到窗口DC10
invoke BeginPaint, hWnd, addr @ps11
mov @hDlgDC, eax12
13
mov eax, g_Rect.right14
sub eax, g_Rect.left15
mov @tmpBuf, eax16
17
mov eax, g_Rect.bottom18
sub eax, g_Rect.top19
invoke CreateCompatibleBitmap, @hDlgDC, @tmpBuf,eax20
mov @hBmp, eax21
22
invoke CreateCompatibleDC, @hDlgDC23
mov @hMemDC, eax24
25
invoke CreateSolidBrush, 242448h26
mov @hBrush, eax 27
28
invoke SelectObject,@hMemDC, @hBmp29
invoke SelectObject,@hMemDC, @hBrush30
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, 036
invoke DrawColckPoint, @hMemDC, IDT_POINTTYPE_MIN, 037
invoke DrawColckPoint, @hMemDC, IDT_POINTTYPE_SECOND, 00000FFh38
39
mov eax, g_Rect.bottom40
sub eax, g_Rect.top41
invoke BitBlt, @hDlgDC, 0, 0, @tmpBuf, eax, @hMemDC, 0, 0, SRCCOPY42
43
invoke DeleteDC, @hMemDC;44
invoke DeleteObject, @hBrush;45
invoke DeleteObject, @hBmp;46
invoke EndPaint, hWnd, addr @ps;47
48
ret49
OnPaintSub endp最后貼下效果圖:

恩,就這么多了,下面給出完整代碼。


