1

以下のプログラムがあります。仕組みを知りたいのですがsetTimer。そのため、プログラムを作成しましたが、TimerProc関数が呼び出されない理由を理解できませんでした。なんで?setTimer/TimerProcを起動するために他に何をする必要がありますか。助けてください。

#include <windows.h>
#include <stdio.h>

VOID CALLBACK TimerProc(
    HWND hwnd,  // handle of window for timer messages 
    UINT uMsg,  // WM_TIMER message
    UINT idEvent,   // timer identifier
    DWORD dwTime    // current system time
   ) {
      printf("from callback\n");

   }
int main(int argc, char *argv[])
{
   UINT timerid = SetTimer(NULL,1,1000,TimerProc);/*changed the time from 1 to 1000, but no effect*/
   printf("timerid %d\n",timerid); 
   int i,j;

      //delay loop, waiting for the callback function to be called
   for(j=0;j<0xffffffff;j++);
   /*{
   printf("%d\n", j);
   }*/

   printf("done \n");
  system("PAUSE");  
  return 0;
}
4

4 に答える 4

4

タイマーはWindowsメッセージキューを介して機能し、コンソールアプリケーションがあります。

基本的なWin32アプリケーションを作成してウィンドウとメッセージループを取得する場合、WM_TIMERメッセージがDefWndProc()呼び出しによってキャッチされると、そこでコールバックが実行されます。もちろん、WM_TIMERを自分でトラップすることもできます。

于 2013-03-14T10:14:08.227 に答える
3

メッセージループのパラダイムを学ぶ必要があります。Win32の初期化と操作を実際に行わずに、Win32APIを使用しようとしています。

Posixから来た場合は、SIGALRMとアラームを使用できます。

Windowsでは、さらに多くの作業が必要になると思います(コールバック関数を提供する場合でも、デフォルトのメッセージループ処理関数を呼び出すメッセージループポンピングがタイマーのコールバックを呼び出すため、メッセージループの開始など) 、これを確認してください:http: //msdn.microsoft.com/en-us/library/windows/desktop/ms644906 (v=vs.85).aspx

アプリケーションは、ウィンドウプロシージャにWM_TIMER caseステートメントを含めるか、タイマーの作成時にTimerProcコールバック関数を指定することにより、WM_TIMERメッセージを処理できます。TimerProcコールバック関数を指定すると、デフォルトのウィンドウプロシージャは、WM_TIMERを処理するときにコールバック関数を呼び出します。したがって、WM_TIMERを処理する代わりにTimerProcを使用する場合でも、呼び出し元のスレッドでメッセージをディスパッチする必要があります。

于 2013-03-14T10:18:07.673 に答える
3

SetTimerのドキュメントには次のように記載されています。*TimerProcコールバック関数を指定すると、デフォルトのウィンドウプロシージャは、WM_TIMERを処理するときにコールバック関数を呼び出します。したがって、WM_TIMERを処理する代わりにTimerProcを使用する場合でも、呼び出し元のスレッドでメッセージをディスパッチする必要があります。*

代わりに、次のような遅延ループが必要です。

bool bStillBusy = false;


int main()
{

MSG msg;

bStillBusy  = true;

id = SetTimer(NULL, 0, 3000, (TIMERPROC) TimerProc);

while(bStillBusy) 
{
  GetMessage(&msg, NULL, 0, 0);
  DispatchMessage(&msg);
}
...
etc.
}

次に、コールバックでbStillBusyを「false」に設定します。

于 2013-03-14T10:20:25.457 に答える
2

タイマーは通常のWindowsイベントシステムを使用して処理されるため、通常のイベントループが必要です。

于 2013-03-14T10:15:41.257 に答える