关于多媒体定时器!(100分)

  • 主题发起人 主题发起人 sunshinebbs
  • 开始时间 开始时间
S

sunshinebbs

Unregistered / Unconfirmed
GUEST, unregistred user!
本人编写了一个软件,里面需要用到高精度定时器,最早采用QueryPerformanceFrequency<br>代码为<br>var<br> &nbsp;Start, L: TLargeInteger;<br> &nbsp;Freq: Integer;<br>begin<br> &nbsp;{ 取得频率, 并将单位转为 &quot;次/每毫秒&quot; }<br> &nbsp;QueryPerformanceFrequency(L);<br> &nbsp;Freq := Round(L / 1000);<br><br> &nbsp;bStopCounter := False;<br> &nbsp;{ 进入回圈前取得开始计数值 }<br> &nbsp;QueryPerformanceCounter(Start);<br> &nbsp;repeat<br> &nbsp; &nbsp;{ 不断取得目前计数值 }<br> &nbsp; &nbsp;QueryPerformanceCounter(L);<br><br> &nbsp; &nbsp;{ QuadPart 栏位是 Comp 型态, 因此可以直接进行加减乘除运算 }<br> &nbsp; &nbsp;//do something<br> &nbsp; &nbsp; &nbsp; &nbsp;{ 让讯息回圈处理讯息, 包括 WM_PAINT, 让 lblElapseTime 元件重绘 }<br> &nbsp; &nbsp;Application.ProcessMessages;<br> &nbsp; until bStopCounter or Application.Terminated;<br><br>后发现CPU资源达到70以上,后来发现多媒体定时器没有问题,也知道它是多线程的,所以编写代码为:<br>procedure TimerProc(uTimerID, uMessage: UINT; dwUser, dw1, dw2:<br> &nbsp;DWORD); stdcall;<br>begin<br> &nbsp;if time &gt; 1000 then exit;<br> &nbsp;time:= mictime + 0.01;<br>end;<br>procedure MMTime(b: Boolean);<br>begin<br> &nbsp;if b then<br> &nbsp; &nbsp;TimerID := timeSetEvent(10, 0, @TimerProc, 0, 1)<br> &nbsp;else<br> &nbsp; &nbsp;timeKillEvent(TimerID);<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> &nbsp;MMTime(False);<br> &nbsp;time := 0;<br> &nbsp;MMTime(True);<br>end;<br><br>后来程序不固定时间出现代码错误,说内存不可写,然后退出程序,在delphi里编译,出现提示什么“致命性错误”,尤其使用界面里的按钮和点击鼠标最为明显,大惑不解,至于分辨率也设过很多次,什么上限,下限的都设过,问题依旧,请高手明示一下怎样使用多媒体定时器最为适合,又或者有没有其他既占资源少,精确度又高的方法!
 
帮你改一改你试试:<br>implementation<br>const<br> &nbsp;Stoplimit=1000;<br>var<br> time:Extended;<br> TimerID:LongWord;<br>procedure MMTime(b: Boolean);forward;<br>procedure TimerProc(uTimerID, uMessage: UINT; dwUser, dw1, dw2:DWORD); stdcall;<br>begin<br> &nbsp;if time &gt; Stoplimit then<br> &nbsp;begin<br> &nbsp; MMTime(False);<br> &nbsp; exit;<br> &nbsp;end;<br> &nbsp;time:= time + 0.01;<br>end;<br><br>procedure MMTime(b: Boolean);<br>begin<br> &nbsp;if b then<br> &nbsp; &nbsp;TimerID := timeSetEvent(10, 0, @TimerProc, 0, 1)<br> &nbsp;else<br> &nbsp; &nbsp;if timeKillEvent(TimerID)=0 then TimerID:=0;<br>end;<br><br>procedure TimeBegin;<br>begin<br> if TimerID&lt;&gt;0 then MMTime(False);<br> TimerID:=0;<br> time:=0;<br> MMTime(True);<br>end;<br><br>测试调用:<br>procedure TForm1.ButtonClick(Sender: TObject);<br>begin<br> TimeBegin;<br>end;<br>修改理由是假设错误因重复按下按钮引起,故不要盲目杀死TimerID,改用判断决定TimerID的生死。<br>说实在话,都不知道你在做什么,看看没人回复,就顺手回复一次。
 
非常感谢回复,其实我的意图是显示秒表效果,当我按一下按钮秒表就会停,然后记下那个时间,这个秒表继续运行,我测试过纯简单窗口运行(一个Form,一个button,一个Edit1)没有发现问题,但我程序有好多个Timer,加上SkinData,里面还有很多控件,就发生问题,因重新开发非常困难,如何有效率地排除错误呢
 
分段排除,也就是将一些没有关系的代码给注释了,然后运行,一个部分一个部分的来。
 
出现的错误为两个窗口,一个为 &quot;0x00401ee0&quot; 指令引用的 &quot;0x000001a&quot; 内存。该内存不能为&quot;written&quot;。<br>另一个为 Invalid pointer operation<br>晕!~
 
嘿嘿,不要指望我会告诉你任何知识,我在这个论坛是不说任何有价值的话的。<br><br>所以以下也是废话:<br>1.你真的把这样的代码作为共用代码来多处使用?<br>2.你真的使用一个EXIT做为暂停的手段?<br>3.你为什么不能写得更好些呢?<br>4.不要指望亡羊补牢的调试手段帮你解决所有问题!
 
谢谢flamingo大哥的教诲。
 
后退
顶部