| 网站首页 | 业界新闻 | 小组 | 交易 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
买学问 - 大牛一对一辅导,有问必答买学问 - 专业的付费知识问答平台
共有 534 人关注过本帖
标题:怎么设置VB 10ms或者1ms画一个点
只看楼主 加入收藏
chen3bing
Rank: 2
等 级:论坛游民
帖 子:291
专家分:99
注 册:2008-11-12
结帖率:90.59%
  已结贴   问题点数:10  回复次数:6   
怎么设置VB 10ms或者1ms画一个点
这是我定时器的画图程序
Private Sub TmrTriger_Timer()
   dateNowTime = Now()  '记录当前时刻
   longSecond = DateDiff("s", dateStartTime, dateNowTime) - 1   '计算当前时刻与计数开始时刻的时间差(秒)
                                
   'cy = 0.1 * Pic1.ScaleHeight + Rnd * 0.8 * Pic1.ScaleHeight   '计算当前时刻在图中对应像素的横坐标x值
    cy = longSecond     '计算当前时刻在图中对应像素的横坐标x值
   If longSecond <= intNum Then
     cx = intInterval * longSecond        '计算当前时刻对应图中像素的横坐标x值
     If longSecond = 0 Then
       Pic1.PSet (cx, cy), Pic1.ForeColor '以前景色画第一个点
     End If
     
     If longSecond > 0 Then
       Pic1.Line (lx, ly)-(cx, cy), Pic1.ForeColor '以前景色将当前点与上一点连在一起
     End If
     
     
     If longSecond = intNum - 1 Then
      llx = cx                                 '将当前点保存为上二点,用于重画后更新
      lly = cy
     End If
     
   Else
     
     BitBlt Pic1.hDC, Pic1.ScaleLeft, Pic1.ScaleTop, Pic1.ScaleWidth - intInterval, Pic1.ScaleHeight, Pic1.hDC, intInterval, 0, &HCC0020 '将窗口右端部分区域拷贝至左端,右端用于重画区
      
     Pic1.Line (lx, ly)-(llx, lly), Pic1.BackColor  '用背景色抹掉最后画的线条
     Pic1.PSet (lx, ly), Pic1.BackColor     '用背景色抹掉最右端倒数第一点
     Pic1.PSet (llx, lly), Pic1.BackColor   '用背景色抹掉倒数第二点
     Pic1.Line (Pic1.ScaleWidth - intInterval, ly)-(Pic1.ScaleWidth, cy), Pic1.ForeColor
     Pic1.Refresh                           '更新显示窗口
     llx = Pic1.ScaleWidth - intInterval    '设置上二点X值坐标
     lly = ly                      '设置上二点Y值坐标
   End If
     If longSecond <= intNum Then  '如果时间秒数低于窗口显示上限值,则将像素当前X、Y值赋给上一点
        lx = cx
        ly = cy
     Else
        ly = cy    '如果时间秒数高于窗口显示上限值,则只将像素当前Y值赋给上一点
     End If
 
End Sub
不过这样只能1秒钟画一个点,我怎么才能实现10ms或者1ms画一个点?谢谢!
2018-12-29 08:54
Joforn
Rank: 6Rank: 6
等 级:贵宾
威 望:23
帖 子:1242
专家分:122
注 册:2007-1-2
  得分:2 
1ms画个点,基本就是个死循环。

VB QQ群:47715789
2018-12-29 10:04
chen3bing
Rank: 2
等 级:论坛游民
帖 子:291
专家分:99
注 册:2008-11-12
  得分:0 
回复 2楼 Joforn
10ms总可以吧
2018-12-29 10:09
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:248
帖 子:4394
专家分:26986
注 册:2008-10-15
  得分:2 
VB 定时器的精度只有 100ms ,所以你想用定时器来实现 10ms ,1ms 是不可能的。

然后查了一个API
程序代码:
'----bas-------
Option Explicit

Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
'定时器回调函数
Public Sub TimerProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long)
    Form1.Print Timer
End Sub
'----Form1-------
Option Explicit
Dim lngTimerID As Long          '定时器ID,使用自动获取方式
Dim BlnTimer As Boolean         '开关状态变量

Private Sub Form_Load()
    BlnTimer = False
    Command1.Caption = "定时开始"
End Sub
Private Sub Form_Unload(Cancel As Integer)
    KillTimer 0, lngTimerID
End Sub

Private Sub Command1_Click()
If BlnTimer = False Then '每多少毫秒调用一次函数
    lngTimerID = SetTimer(0, 0, 1000, AddressOf TimerProc)            '第三个参数是定时时间,单位是ms
    BlnTimer = True
    Command1.Caption = "定时结束"
Else
    KillTimer 0, lngTimerID
    BlnTimer = False
    Command1.Caption = "定时开始"
End If
End Sub


发现 100ms 也不精确,再百度了一下, 定时器 是按 75ms 为一个周期进行触发,并且消息级别为最低。
也就是说定时器最小周期为 75ms 一次,你打算如何实现你的 10ms,自已看着办。

授人于鱼,不如授人于渔
早已停用QQ了
2018-12-29 10:25
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:248
帖 子:4394
专家分:26986
注 册:2008-10-15
  得分:2 
还有,特意测试了一下, API 定时器,是在主线程里执行的,也就是说主线程当前这空闲的情况下,才会执行定时器。
-------------------------
有一个多媒体系统里用的 定时器,定时精度为 1ms ,但没找着怎么用的。
有兴趣自己去测试一下。


授人于鱼,不如授人于渔
早已停用QQ了
2018-12-29 10:33
chen3bing
Rank: 2
等 级:论坛游民
帖 子:291
专家分:99
注 册:2008-11-12
  得分:0 
谢谢!如果VB是这样,是不是说Delphi和VC都是这样,定时不准?
2018-12-29 10:43
wds1
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:36
帖 子:347
专家分:1840
注 册:2016-3-10
  得分:4 
这个为取得流逝时间,单位为ms。
但是经实测只有大于5ms才能精准,大于2ms偶尔会不准。
Private Declare Function timeGetTime Lib "winmm.dll" () As Long '取得流逝时间需调用次函数

一般我都是作为延时使用
Private Sub sleep(seconds As Integer)
Dim temp As Variant
temp = timeGetTime
  While timeGetTime - seconds < temp
  DoEvents
  Wend
End Sub

timer控件是靠中断产生定时,只有系统空闲,才会响应中断。
另外系统检测中断也需要一个周期,此周期约为20ms。
在程序中,如果程序对cpu占用的越多,这timer偏差就会越大。
程序循环体中增加doevents一般可以保证500ms-1s的中断产生。

2018-12-29 16:36







关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030535 second(s), 8 queries.
Copyright©2004-2019, BCCN.NET, All Rights Reserved