大概說下思路,方便以后回憶~
在窗口客戶區 繪制一個圓,圓心為邏輯坐標。這樣,它窗體設備坐標的轉換關系如下:
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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

關于 鐘表指針的繪制就比較簡單了,用三角函數,根據分鐘數,秒數,小時數,可以計算出相應的角度,再乘以半徑就可以得到指定圓的交點坐標了,代碼如下:
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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

最后就是繪制方面,為了防止閃爍,用了雙緩存,建了個內存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

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

最后貼下效果圖:

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