如何在没有计时器的情况下确定经过了多少时间

How to determine how much time has passed without a timer?

本文关键字:过了 时间 多少 情况下 计时器      更新时间:2023-10-16

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

我研究了计时器,我知道我可以创建一个计时器,增加一个变量来"计数"经过了多少时间,但为了足够准确,它必须至少每50毫秒使用一次(可能更短),因为我的重复功能在我希望它是即时或接近即时的时候,每个周期大约需要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;
}

Windows提供了一对函数来获取非常精确的运行时间。QueryPerformanceCounter将给出当前计数,QueryPerformanceFrequency给出每秒计数的数量。

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

为了解决这个问题,我发现timeGetTime()与timeBeginPeriod()和timeEndPeriod(。

GetTickCount()的准确度略低于timeGetTime(根据本文),在阅读了许多关于该主题的其他信息后,我得出结论,就准确性和可靠性而言,timeGetTime()是最好的通用计时器。

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

如果是这样的话,你需要每27毫秒做一次旋转。虽然在窗口中睡眠并不十分准确(你可能需要等待15毫秒才能"醒来"),但这可能是你最接近的解决方案。

C#中的另一个选项(在C++中可能有一种方法可以做到这一点,我只是不知道)是使用事件。例如,在C#中,很容易创建一个以毫秒为单位的计时器,每当计时器达到27时,它就会触发对rotate函数的异步调用。这将有效地重新绘制图像,同时计时器继续计时。如果C#对您来说是一条可行的路径,我很乐意提供一些代码