Loops DELPHI 10.3-边按边循环,直到按键出现小问题

Loops DELPHI 10.3-边按边循环,直到按键出现小问题,loops,delphi,while-loop,key,keypress,Loops,Delphi,While Loop,Key,Keypress,各位早上好,, 我编写了一个非常简单的应用程序,其中我必须等待用户按下一个键(例如F2)才能继续处理。按下按钮的等待周期工作得很好,但我需要帮助的问题是:如果在按下按钮的等待周期中,我单击另一个应用程序,我的应用程序将失去焦点,我无法再重新获得控制。 即使我单击应用程序的任何部分,表单的标题始终保持灰色,应用程序仍在等待按键的压力,如果我按下所需的按键,显然什么也没有发生。 如何重新控制我的应用程序?我想我会把指令像SetFocus,StayOnTop,SetForeGroundIndow。。。

各位早上好,, 我编写了一个非常简单的应用程序,其中我必须等待用户按下一个键(例如F2)才能继续处理。按下按钮的等待周期工作得很好,但我需要帮助的问题是:如果在按下按钮的等待周期中,我单击另一个应用程序,我的应用程序将失去焦点,我无法再重新获得控制。 即使我单击应用程序的任何部分,表单的标题始终保持灰色,应用程序仍在等待按键的压力,如果我按下所需的按键,显然什么也没有发生。 如何重新控制我的应用程序?我想我会把指令像SetFocus,StayOnTop,SetForeGroundIndow。。。等在while循环中,始终保持我的应用程序处于活动状态,但我无法组合任何内容。。。代码如下:

var

  Form2: TForm2;
  mkey: word; 

implementation

{$R *.dfm} 

procedure TForm2.FormActivate(Sender: TObject);

begin

  label1.Visible:= false;

  mkey:= 0;

  keyPreview:= true;

  while mkey <> VK_F2 do begin

    label1.Visible:= true;

    label1.Caption:= datetimetostr(now);   // for example

    application.ProcessMessages;

  end;

  label1.Visible:= false;

end; 

procedure TForm2.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);

begin

  mkey:= key;

end;

end.
var
表2:TForm2;
mkey:单词;
实施
{$R*.dfm}
程序TForm2.FORMATIVATE(发送方:TObject);
开始
标签1.可见:=假;
mkey:=0;
keyPreview:=真;
当mkey VK_F2开始时
标签1.可见:=真;
标签1.标题:=datetimetostr(现在);//例如
application.ProcessMessages;
终止
标签1.可见:=假;
终止
程序TForm2.FormKeyUp(发送方:ToObject;变量关键字:Word;Shift:TShiftState);
开始
mkey:=键;
终止
终止

我不想听起来很刺耳,但不幸的是,您的设计存在根本缺陷

如注释所示,图形化Windows应用程序——特别是VCL应用程序——是事件驱动的。(在幕后,这要归功于消息泵,但VCL开发人员通常不需要关心这些细节。特别是,新的Delphi开发人员通常不知道底层的消息泵,如果他们小心的话,仍然可以编写高质量的GUI应用程序。)

例如,使用显式循环等待按键几乎总是错误的。另外,必须调用
Application.ProcessMessages
是一个(主要)设计缺陷的明显标志(在许多情况下,但不是这个,解决方案是添加一个新线程)。最后,如果一项看似基本的任务导致您需要添加代码来解决的问题(如
SetFocus
),您应该始终问问自己是否有更好的解决方案

我不知道您到底想做什么,但下面的示例可能会有所帮助

  • 创建一个新的VCL应用程序。使用对象检查器给主窗体起一个好名字,如
    frmMain
    。在代码编辑器中,向表单类添加一个私有字段
    FStarted:Boolean
    。因为这是类中的一个字段,所以它被初始化(因为它是
    布尔值
    ,所以被初始化为
    )。ª

  • TLabel
    控件添加到表单中。使用对象检查器将其名称设置为
    lblMainText
    。将字体设置为视觉上令人愉悦的²,标题设置为
    按F2开始。

  • 在表单的
    OnKeyDown
    事件处理程序中,添加以下代码:

    procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
      if (Key = VK_F2) and not FStarted then
      begin
        MessageBeep(MB_ICONASTERISK);
        lblMainText.Caption := 'Let''s get to work!';
        FStarted := True;
      end;
    end;
    
  • 运行应用程序

  • 按F2键后:

    请注意,再次按F2键不起任何作用;您已经“启动”了系统

    显然,这个小答案并不能教会您编写VCL应用程序所需的全部知识。它只触及你需要知道的0.1%。要了解更多信息,我强烈建议购买一本关于Delphi编程的好书(特别是关于用Delphi编写Win32应用程序的书)

    在Delphi中,全局变量和类成员被初始化(到
    0
    0.0
    False
    nil
    ,等等)。但是,局部变量永远不会初始化(除非它们是托管类型)

    ²据《科学》杂志称,Segoe用户界面是一个不错的选择。事实上,您可以将此字体用于表单本身;然后所有子控件将自动继承此字体设置


    仅当窗体本身具有焦点(例如,没有子控件)时,此操作才有效。即使子控件有焦点,也要使其正常工作,我的最佳建议是使用
    战术列表。它们真的很有用。

    我不想听起来很刺耳,但不幸的是,您的设计存在根本缺陷

    如注释所示,图形化Windows应用程序——特别是VCL应用程序——是事件驱动的。(在幕后,这要归功于消息泵,但VCL开发人员通常不需要关心这些细节。特别是,新的Delphi开发人员通常不知道底层的消息泵,如果他们小心的话,仍然可以编写高质量的GUI应用程序。)

    例如,使用显式循环等待按键几乎总是错误的。另外,必须调用
    Application.ProcessMessages
    是一个(主要)设计缺陷的明显标志(在许多情况下,但不是这个,解决方案是添加一个新线程)。最后,如果一项看似基本的任务导致您需要添加代码来解决的问题(如
    SetFocus
    ),您应该始终问问自己是否有更好的解决方案

    我不知道您到底想做什么,但下面的示例可能会有所帮助

  • 创建一个新的VCL应用程序。使用对象检查器给主窗体起一个好名字,如
    frmMain
    。在代码编辑器中,向表单类添加一个私有字段
    FStarted:Boolean
    。因为这是类中的一个字段,所以它被初始化(因为它是
    布尔值
    ,所以被初始化为
    )。ª

  • TLabel
    控件添加到表单中。使用对象检查器将其名称设置为
    lblMainText
    。将字体设置为视觉上令人愉悦的²,标题设置为
    按F2开始。

  • 在表单的
    OnKeyDown
    事件处理程序中,添加以下代码
    procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
      if (Key = VK_F2) and not FStarted then
      begin
        MessageBeep(MB_ICONASTERISK);
        lblMainText.Caption := 'Let''s get to work!';
        FStarted := True;
      end;
    end;