如何确定没有计时器已经过了多少时间?

时间:2013-06-25 15:27:37

标签: c++ windows optimization timer

我正在尝试制作一个旋转的程序并在10秒内完成360度的位图绘制,但我发现我用来做这个的方法不是即时甚至关闭的,所以我的函数将会不能在预期的时间内执行。为了弥补这一点,我决定确定从我用来旋转图像并绘制它直到它完成的函数开始已经过了多少时间,并且通过执行所花费的额外时间来增加它旋转的量。

我查看了计时器,我知道我可以创建一个计时器,增加一个变量来“计算”已经过了多少时间,但是为了使它足够准确,它必须至少每50个使用一次。 ms(可能更短)当我的重复功能在每个周期完成时需要大约0.4秒完成,当我希望它是即时或接近即时时,我觉得这可能会消耗太多额外资源并且想要寻找不同的解决方案。

如果您需要任何代码,请执行以下操作:

#include <windows.h>
#include <tgmath.h>

void rotatebmp (HDC hdc_x, float q, float x0, float y0)
{
  q = (q * 0.01745333055);
  XFORM blah;
  blah.eM11 = cos(q);
  blah.eM12 = sin(q);
  blah.eM21 = -sin(q);
  blah.eM22 = cos(q);
  blah.eDx = x0 - cos(q)*x0 + sin(q)*y0;
  blah.eDy = y0 - cos(q)*y0 - sin(q)*x0;
  SetWorldTransform(hdc_x, &blah);
  return;
}

int main()
{
  float q = 0;
  HDC hdc = CreateCompatibleDC(NULL);
  HBITMAP cross = (HBITMAP)LoadImage(NULL, ("C:\\Documents and Settings\\Death\\My Documents\\45Hand.bmp") ,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
  HBITMAP crossmask = (HBITMAP)LoadImage(NULL, ("C:\\Documents and Settings\\Death\\My Documents\\45Hand2.bmp") ,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
  while (1)
  {
    q = (q + 3.6);
    HDC hdc_x = GetDC(HWND_DESKTOP);
    SetGraphicsMode(hdc_x, GM_ADVANCED);
    SelectObject(hdc, crossmask);
    rotatebmp (hdc_x, q, 850, 375);
    BitBlt(hdc_x,550,0,600,527,hdc,0,0, SRCAND);
    ReleaseDC(HWND_DESKTOP,hdc_x);
    hdc_x = GetDC(HWND_DESKTOP);
    SetGraphicsMode(hdc_x, GM_ADVANCED);
    SelectObject(hdc, cross);
    rotatebmp (hdc_x, q, 850, 375);
    BitBlt(hdc_x,550,0,600,527,hdc,0,0, SRCPAINT);
    ReleaseDC(HWND_DESKTOP,hdc_x);
    Sleep(10);
  }
  return 0;
}

3 个答案:

答案 0 :(得分:1)

Windows提供了一对功能,用于获取高精度的经过时间。 QueryPerformanceCounter将提供当前计数,QueryPerformanceFrequency给出每秒计数数。

只需在开始时获取计数,在结尾处获得另一个计数,从结尾减去开始,然后除以频率以获得经过的时间。

答案 1 :(得分:0)

为了解决这个问题,我发现timeGetTime()与timeBeginPeriod()和timeEndPeriod()是最准确的,没有严重错误结果的可能性,QueryPerformanceCounter和QueryPerformanceFrequency并没有为我做伎俩,他们抛出了疯狂的结果这似乎是随机的,有时甚至是负值。

GetTickCount()比timeGetTime(根据this文章)更不准确,在阅读了关于这个主题的很多其他信息之后,我得出的结论是timeGetTime()是最好的通用计时器在准确性和可靠性方面。

答案 2 :(得分:-1)

我不确定我明白你在这里要做什么。如果我理解正确,你想在10秒内将图像旋转360度?

如果是这种情况,则需要每27毫秒进行一次旋转。虽然Windows中的睡眠不是非常准确(您可能需要等待15毫秒来“唤醒”),但这可能是您最接近的解决方案。

C#中的另一个选项(并且可能有一种在C ++中执行此操作的方法,我只是不知道它)是使用事件。例如,在C#中,创建一个以毫秒为单位的计时器非常容易,每次达到27时,它都会触发对旋转函数的异步调用。当计时器继续滴答时,这将有效地重新绘制图像。如果C#是一条可行的途径,我很乐意提供一些代码