2012-08-03 6 views
0

C++에서 리셋 할 수있는 간단한 비 차단 타이머를 만들려고합니다. 나는 몇몇 코드 예제를 찾기 위해 잠시 동안 구글을 찾았지 만, 내가 발견 한 모든 것은 이해하기가 너무 복잡하거나 여분의 비 예제 코드없이 컴파일되지 않는다.넌 블로킹 타이머 C++

키 누르기를 파일에 기록하는 프로그램이 있지만 두 번째 파일이 시작되기 전에 다른 키를 누르지 않으면이 키를 누른 후이 파일을 1 초 이상 기록해야합니다.

저는 Win32 타이머를 사용해야한다고 생각합니다. 그러나 창을 사용하고 있습니다. 그러나 사용법에 대한 간단한 예를 찾을 수는 없습니다. 이 방법은 정보 페이지에서 가져온 예를 들어

:

SetTimer(hwnd,    // handle to main window 
IDT_TIMER1,     // timer identifier 
1000,      // 1-second interval 
(TIMERPROC) MyTimerProc);  // no timer callback 


VOID CALLBACK MyTimerProc( 
HWND hwnd,  // handle to window for timer messages 
UINT message,  // WM_TIMER message 
UINT idTimer,  // timer identifier 
DWORD dwTime)  // current system time 
{ 

// my proceedure code 

FILE *OUTPUT_FILE; 
OUTPUT_FILE = fopen("LOG.TXT", "w"); 
fprintf(OUTPUT_FILE, "%s", ""); 
fclose(OUTPUT_FILE); 

// writes a blank text file. 


KillTimer(hwnd, IDT_TIMER1); // stop timer after one call 
} 

컴파일하지 않는 IDT_TIMER1의 었소는 '정의되어 있기 때문에 나는 생각한다.

또한이 방법을 두 번 호출하여 다시 설정할지 또는 두 번 별도의 호출을 1 초 간격으로 시작할지 잘 모르겠습니다.

도움을 주시면 감사하겠습니다.

+0

간단하면 'IDT_TIMER1'대신 1과 같은 숫자를 사용할 수 있습니다. 당신이 일반적으로하는 일은'const int IDT_TIMER1 = 1;'과 비슷합니다. 실제로 C++ 11은 Windows 전용 함수를 사용하지 않고 자신 만의 도구를 만들 수있는 도구를' '에 제공합니다. nonblocking 부분에서 C++ 11은 또한 ''을 제공합니다. – chris

+0

간단한 컴파일 가능한 예제를 찾지 못하는 이유는 사소한 Win32 API C 프로그램조차도 상용구가 엉망이되기 때문입니다. 하지만 http://msdn.microsoft.com/en-us/library/windows/desktop/ms644901(v=vs.85).aspx#creating_timer에서 코드를 사용해 보셨습니까? – abarnert

+0

그래, 그 링크는 내가 뭘 하려는지 거의 알 수 없지만 하나의 예제만으로는 컴파일되지 않을 것이다. – Zac

답변

0

귀하는 ID_TIMER1 값을 제공 할 책임이 있습니다. 나는 당신이 (99 %) 그것이 작동하도록 Windows 메시지 루프가 있어야한다고 생각합니다.

여기에 최소한으로 컴파일 가능한 examples 몇 가지가 있습니다.

+0

예, 확실히 WndProc 메시지 루프가 필요합니다. 그러나 어떤 종류의 타이머 구현이 어떻게 스레드를 생성하는지 (어떻게 든 join에 대해 알아야 할) 또는 일종의 이벤트 루프를 필요로하지 않고 어떻게 작동하는지 상상하기가 어렵습니다. – abarnert

+0

새 스레드를 생성 한 다음 사용할 수 있습니다. sleep (1000), 그 후 파일을 쓰겠습니다 ... 유일한 문제는 스레드가 살아 있는지 확인하는 것이고 완료 되었다면 죽이기 전에 다시 시작하는 것입니다.하지만 그게 좋은 방법일까요? – Zac

+0

메시지 루프가 필요하다는 것을 100 % 확신 할 수 있습니다. 타이머를 사용하는 3 가지 다른 방법이 있습니다. 먼저, 윈도우 핸들에 대해'NULL '을'SetTimer' 함수에 전달할 수 있습니다. 이 경우, 응용 프로그램의 메시지 루프에서'WM_TIMER'를 처리하고이를 적절한 창에 직접 보내야합니다. 두 번째로'SetTimer'를 호출 할 때 특정 윈도우에 대한 핸들을 지정할 수 있습니다.이 경우 해당 윈도우의 윈도우 프로시 저는'WM_TIMER' 메시지를받습니다. 셋째, 마지막으로'SetTimer'를 호출 할 때'TimerProc' 콜백 함수를 지정할 수 있습니다 ... –

0

Google을 통해 빠르게 찾을 수있는 Hardware Performance Timer를 사용하거나 Google에서 찾을 수있는 timegettime 메소드를 사용하는 플랫폼을 더 많이 사용하려면 Win32 메시지 루프가 필요하지 않습니다.

0

창이나 이벤트 루프가 필요하지 않습니다. WaitForSingleObject function을 확인하십시오. 여기

는 일부 코드 다음 콘솔 프로그램이 작동

HANDLE hStdin; 
hStdin = GetStdHandle(STD_INPUT_HANDLE); 

FILE *OUTPUT_FILE; 
OUTPUT_FILE = fopen("LOG.TXT", "w"); 

bool previous_input_written = TRUE; 

switch (WaitForSingleObject(hStdin, 1000) { 

    case WAIT_OBJECT_0: 
    // input happened on hStdin 
    if (!previous_input_written) { 
     // the previous input was not saved to file 
     fprintf(OUTPUT_FILE, ... 
     previous_input_written= TRUE; 
    } 
    ReadConsoleInput(hStdin, ... 
    previous_input_written = FALSE; 

    case WAIT_TIMEOUT: 
    // the 1000ms delay timed out, write to file 
    fprintf(OUTPUT_FILE, ... 
    previous_input_written= TRUE; 
} 


fclose(OUTPUT_FILE); 
0

입니다. SetTimer 을 사용하여 타이머를 설정 한 다음 메시지 루프에서 반복합니다. 메시지 루프는 WM_TIMER 메시지 을 수신하여 처리하고 타이머 콜백도 각 시간 간격마다 호출됩니다. 그리고 그것은 차단되지 않습니다.

#define STRICT 1 
#include <windows.h> 
#include <iostream.h> 

VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime) 
{ 
    cout << "Time: " << dwTime << '\n'; 
    cout.flush(); 
} 

int main(int argc, char *argv[], char *envp[]) 
{ 
    int Counter=0; 
    MSG Msg; 

    UINT TimerId = SetTimer(NULL, 0, 500, &TimerProc); //SetTimer 

    cout << "TimerId: " << TimerId << '\n'; 
    if (!TimerId) 
    return 16; 

    while (GetMessage(&Msg, NULL, 0, 0)) 
    { 
     ++Counter; 
     if (Msg.message == WM_TIMER) 
     cout << "Counter: " << Counter << "; timer message\n"; 
     else 
     cout << "Counter: " << Counter << "; message: " << Msg.message << '\n'; 
     DispatchMessage(&Msg); 
    } 

    KillTimer(NULL, TimerId); 
return 0; 
}