如何在Delphi控制台应用程序中实现一个IsKeyPressed函数?

8

我有一个Delphi控制台应用程序,需要在用户按任意键时终止。问题是我不知道如何实现检测按键的功能,我想做类似以下的操作。

{$APPTYPE CONSOLE}

begin
 MyTask:=MyTask.Create;
 try
 MyTask.RunIt; 
  while MyTask.Running and not IsKeyPressed do //how i can implement a IsKeyPressed  function?
    MyTask.SendSignal($56100AA);
 finally
   MyTask.Stop;
   MyTask.Free;
 end;

end.


1
你确定要使用繁忙循环吗?为什么不在按下Ctrl+Break时中断呢? - David Heffernan
1个回答

13
你可以编写一个函数来检测按键是否按下,通过检查控制台输入缓冲区实现。
每个控制台都有一个输入缓冲区,其中包含一系列输入事件记录。当控制台的窗口具有键盘焦点时,控制台会将每个输入事件(例如单个按键、鼠标移动或鼠标按钮单击)格式化为输入记录,并将其放入控制台的输入缓冲区中。
首先,您必须调用GetNumberOfConsoleInputEvents函数以获取事件数量,然后使用PeekConsoleInput函数检索事件并检查它是否为KEY_EVENT,最后使用FlushConsoleInputBuffer刷新控制台输入缓冲区。
请参考以下示例。
function KeyPressed:Boolean;
var
  lpNumberOfEvents     : DWORD;
  lpBuffer             : TInputRecord;
  lpNumberOfEventsRead : DWORD;
  nStdHandle           : THandle;
begin
  Result:=false;
  //get the console handle
  nStdHandle := GetStdHandle(STD_INPUT_HANDLE);
  lpNumberOfEvents:=0;
  //get the number of events
  GetNumberOfConsoleInputEvents(nStdHandle,lpNumberOfEvents);
  if lpNumberOfEvents<> 0 then
  begin
    //retrieve the event
    PeekConsoleInput(nStdHandle,lpBuffer,1,lpNumberOfEventsRead);
    if lpNumberOfEventsRead <> 0 then
    begin
      if lpBuffer.EventType = KEY_EVENT then //is a Keyboard event?
      begin
        if lpBuffer.Event.KeyEvent.bKeyDown then //the key was pressed?
          Result:=true
        else
          FlushConsoleInputBuffer(nStdHandle); //flush the buffer
      end
      else
      FlushConsoleInputBuffer(nStdHandle);//flush the buffer
    end;
  end;
end;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接