我希望按鍵A至少要保持三秒鐘而不中斷。如果按鍵被中斷,三秒鐘的時間應該再次適用。
這是我之前的程式。不幸的是,當timer()程式運行時,程式并沒有注意到任何關于釋放按鈕或再次按下按鈕的情況。
我想問的是:我可以做什么?
我想留在C語言中。
我的IDE是Microsoft Visual Studio Community 2019,版本為16.11.2.
。我使用的是 Windows 10.
#pragma warning(disable : 4996) // Visual Studio不希望看到像'scanf'這樣老的函式。
#include <stdio.h>/span>
#include <Windows.h>/span>
#include <cstdint>/span>
#include <time.h>
bool supposed_to_run = true;
VOID KeyEventProc(KEY_EVENT_RECORD)。
long long waited = 0ll;
time_t Time_of_the_keydown_event;
bool triggered = false;
void timer()
{
Time_of_the_keydown_event;
time_t _to = time(&_to) 3ll;
do do
{
Time_of_the_keydown_event = time(&Time_of_the_keydown_event)。
} while (Time_of_the_keydown_event < _to & & triggered);
}
void Logic(INPUT_RECORD rec)
{
if (rec.Event.KeyEvent.wVirtualKeyCode == 0)
{
return;
}
if (!rec.Event.KeyEvent.bKeyDown)
{
triggered = false;
return;
}
switch (rec.Event.KeyEvent.wVirtualKeyCode)
{
case VK_SHIFT:
break;
case VK_CONTROL:
break;
case VK_SPACE:
break;
case VK_LEFT:
break;
case VK_UP:
break;
case VK_RIGHT:
break;
case VK_DOWN:
break;
case 0x41: /*A*/: /*A*/.
triggered = true;
timer()。
printf("A
")。)
break。
case 0x51: /*Q*/: /*Q*/.
break;
case 0x5A: /*Z*/: /*Z*/.
supposed_to_run = false;
break。
default:
break;
}
}
int main(void)
{
INPUT_RECORD rec{};
HANDLE hConInp = GetStdHandle(STD_INPUT_HANDLE)。
DWORD ReadCount = 0;
//Change_size_position_and_color();.
while (supposed_to_run)
{
ReadConsoleInput(hConInp, &rec, 1, & ReadCount)。
邏輯(rec)。
}
//結束程式。
printf("
程式已經結束了。如果你想知道更多關于程式的資訊,請點擊 "進入"。
")。)
getchar()。
return 0。
}
uj5u.com熱心網友回復:
我推薦你使用函式WaitForSingleObject。該函式允許您等待新的控制臺輸入,還允許您指定一個超時時間,在您的案例中應該是 3 秒。
根據該函式的回傳值,你將知道新的控制臺輸入是否已經發生,或者超時是否已經過期。
switch ( WaitForSingleObject( hConInp, 3000 ) )
{
case WAIT_OBJECT_0:
//處理新的控制臺輸入。
//ReadConsoleInput如果現在呼叫將不會阻塞。
break。
case WAIT_TIMEOUT:
//handle timeout; case WAIT_TIMEOUT: /handle timeout
break;
default:
//handle error; default[/span]: 錯誤。
然而,這個解決方案有一個問題。在按住按鍵的同時,按鍵會自動重復,產生新的輸入事件。因此,3秒的超時可能永遠不會過期(除非您將您的作業系統配置為具有很長的重復延遲)。
因此,您將不得不忽略這些按鍵下降事件,并再次呼叫 WaitForSingleObject,但這次不會再使用 3 秒的超時。相反,新的超時應該是原來 3 秒的剩余時間。
在你的代碼中,你正在使用 ISO C 函式 time。然而,這個函式的精度只有一秒,可能不夠準確。因此,你可能想使用平臺特定的函式GetTickCount來代替。
我相信,通過上述的修改,我能夠讓你的程式作業。以下是我的代碼:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
bool supposed_to_run = true。
bool triggered = false;
bool require_release = false;
DWORD remaining_timeout。
void Logic(INPUT_RECORD rec)
{
if (rec.Event.KeyEvent.wVirtualKeyCode == 0)
{
return;
}
if (!rec.Event.KeyEvent.bKeyDown)
{
if ( triggered )
{
printf( "driving trigger
" )。)
triggered = false;
}
else if ( require_release && rec.Event.KeyEvent.wVirtualKeyCode == 0x41 )
{
printf( "key has been released and timeout may now be triggered again
" )。)
require_release = false;
}
return;
}
switch (rec.Event.KeyEvent.wVirtualKeyCode)
{
case VK_SHIFT:
break;
case VK_CONTROL:
break;
case VK_SPACE:
break;
case VK_LEFT:
break;
case VK_UP:
break;
case VK_RIGHT:
break;
case VK_DOWN:
break;
case 0x41: /*A*/: /*A*/.
if ( !kiggered && !require_release )
{
printf( "triggering timeout
" )。)
triggered = true;
remaining_timeout = 3000;
}
break;
case 0x51: /*Q*/: /*Q*/.
break;
case 0x5A: /*Z*/: /*Z*/.
supposed_to_run = false;
break。
default:
break;
}
}
int main(void)
{
INPUT_RECORD rec = {0}。
HANDLE hConInp = GetStdHandle(STD_INPUT_HANDLE)。
DWORD ReadCount。
while (supposed_to_run)
{
if ( triggered )
{
bool timeout_expired = false;
DWORD start_time = GetTickCount();
switch ( WaitForSingleObject( hConInp, remaining_timeout ) )
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
timeout_expired = true;
break;
default:
fprintf( stderr, " unexpected error!" )。
exit( EXIT_FAILURE )。
}
DWORD time_expired = GetTickCount() - start_time;
if ( !timeout_expired )
{
//可能是WaitForSingleObject沒有報告。
/a timeout,但是GetTickCount現在報告說
//a timeout expired。我們應該認為這也是一個超時。
if ( time_expired >= remaining_timeout )
timeout_expired = true。
}
if ( timeout_expired )
{
triggered = false;
require_release = true;
printf("A
")。)
continue。
}
else; }
{
remaining_timeout -= time_expired;
}
}
ReadConsoleInput(hConInp, &rec, 1, & ReadCount)。
邏輯(rec)。
}
return 0;
}
當用戶按住A鍵三秒后,將在螢屏上顯示該字符。之后,新的超時將不會被觸發,直到用戶釋放該鍵,然后再次按下該鍵。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/320283.html
標籤:
上一篇:注冊表查詢資訊給出不正確的值
下一篇:用c 移動輸入檔案
