聚星亭

吾笨笨且懒散兮 急须改之而奋进
posts - 74, comments - 166, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

            大概说下思路,方便以后回忆~
            在窗口客户区 绘制一个圆,圆心为逻辑坐标。这样,它窗体设备坐标的转换关系如下:

   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;//######################################################################
 8ConvlogicPos2DevicePos 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
21ConvlogicPos2DevicePos endp
22
23;//######################################################################
24;// 功  能: 从设备坐标系到逻辑坐标系
25;// 函数名: ConvDevicePos2logicPos
26;// 参数 
27;//       ptDevicePos: 设备坐标
28;//       pptLogicPos: 输出参数 转换后的逻辑坐标
29;//######################################################################
30ConvDevicePos2logicPos 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
44ConvDevicePos2logicPos endp

      关于 钟表指针的绘制就比较简单了,用三角函数,根据分钟数,秒数,小时数,可以计算出相应的角度,再乘以半径就可以得到指定圆的交点坐标了,代码如下:
  1;//#############################################################
  2;// 设置指针长度
  3;//#############################################################
  4SetPointLong 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
 31SetPointLong endp
 32
 33;//######################################################################
 34;// 功  能:绘制钟表指针
 35;// 函数名: DrawColckPoint
 36;// 参数 
 37;//       hWnd: 窗口句柄
 38;//     nColor: 秒针的颜色
 39;//######################################################################
 40DrawColckPoint 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
155DrawColckPoint endp

最后就是绘制方面,为了防止闪烁,用了双缓存,建了个内存DC,代码如下:
 1OnPaintSub 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, 00, @tmpBuf, eax, @hMemDC, 00, SRCCOPY
42        
43        invoke DeleteDC, @hMemDC;
44        invoke DeleteObject, @hBrush;
45        invoke DeleteObject, @hBmp;
46        invoke EndPaint, hWnd, addr @ps;
47    
48    ret
49OnPaintSub endp

            最后贴下效果图:
                  

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

Feedback

# re: 老师布置的作业:让写一个电子钟,发上来留个纪念  回复  更多评论   

2010-07-28 08:06 by heguo
高人

# re: 老师布置的作业:让写一个电子钟,发上来留个纪念  回复  更多评论   

2010-07-28 08:28 by ccsdu2009
啥语言的?

# re: 老师布置的作业:让写一个电子钟,发上来留个纪念  回复  更多评论   

2010-07-28 09:31 by Husiwa
DELPHI

# re: 老师布置的作业:让写一个电子钟,发上来留个纪念[未登录]  回复  更多评论   

2010-07-28 10:00 by ZUHD
这是Delphi??
这分明是pascal嘛。。。。。。

楼主还是学生,我曾在看雪里拜读过你的文章

# re: 老师布置的作业:让写一个电子钟,发上来留个纪念  回复  更多评论   

2010-07-28 10:35 by yafare
pascal,汉……

不过MASM那堆语法也跟高级语言差不多了

# re: 老师布置的作业:让写一个电子钟,发上来留个纪念[未登录]  回复  更多评论   

2010-07-28 17:10 by besterchen
@ZUHD
(*^__^*) 嘻嘻……,那些东西就别提了,上不了台面的……

# re: 老师布置的作业:让写一个电子钟,发上来留个纪念  回复  更多评论   

2010-07-28 17:25 by nehCretseB
这个明明是 VB 嘛...

唉. 现在的人眼神越来越差了~!

# re: 老师布置的作业:让写一个电子钟,发上来留个纪念  回复  更多评论   

2010-08-05 14:47 by 吴冬亮
看到汇编指令 我很纠结

# re: 老师布置的作业:让写一个电子钟,发上来留个纪念  回复  更多评论   

2010-08-08 09:06 by foxtail
汇编现在还有应用领域吗 搞不懂

# re: 老师布置的作业:让写一个电子钟,发上来留个纪念  回复  更多评论   

2010-08-11 16:44 by nero
@nehCretseB
是VB?笑掉大牙!

# re: 老师布置的作业:让写一个电子钟,发上来留个纪念  回复  更多评论   

2010-09-15 11:23 by SIsIA
这好像是易语言的吧?

# re: 老师布置的作业:让写一个电子钟,发上来留个纪念[未登录]  回复  更多评论   

2012-04-08 17:13 by a
应该是WIN32汇编写的吧,我下了金山卫士会报毒。
不过我想应该是误报。不知道是不是

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理