1 delphi loops key keypress while-loop
大家早上好,我写了一个非常简单的应用程序,我必须等待用户按下某个键(例如 F2)才能继续处理。按下按钮的等待周期工作正常,但我需要帮助的问题是:如果在按下按钮的等待周期中,我点击了另一个应用程序,我的应用程序失去了焦点,我无法再重新获得控制权。即使我点击应用程序的任何部分,表单的标题始终保持灰色,应用程序仍然在等待按键的压力,如果我按下所需的键,显然什么也没有发生。如何重新控制我的应用程序?我想我会在 while 循环中放置诸如 SetFocus、StayOnTop、SetForegroundWindow 等指令,以始终保持我的应用程序处于活动状态,但我无法组合任何东西...
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.
Run Code Online (Sandbox Code Playgroud)
我不想听起来很刺耳,但不幸的是,您的设计存在根本性缺陷。
正如评论中所指出的,图形 Windows 应用程序——尤其是 VCL 应用程序——是事件驱动的。(在幕后,这要归功于消息泵,但 VCL 开发人员通常不需要关心这些细节。特别是,新的 Delphi 开发人员通常不了解底层消息泵,但仍然可以编写高质量的 GUI应用程序,如果他们小心。)
因此,例如,使用显式循环等待按键被按下几乎总是错误的。此外,必须调用Application.ProcessMessages是(主要)设计缺陷的明显标志(在许多情况下,但不是这个,解决方案是添加一个新线程)。最后,如果一个看似基本的任务导致您需要添加代码来解决的问题(如SetFocus),您应该始终问问自己是否有更好的解决方案。
我不确切知道您要做什么,但以下示例可能会有所帮助。
创建一个新的 VCL 应用程序。给主窗体起一个好名字,比如frmMain使用对象检查器。在代码编辑器中,FStarted: Boolean向表单类添加一个私有字段。由于这是类中的一个字段,因此它已被初始化(因为它是 a Boolean, to False)。¹
private
FStarted: Boolean;
Run Code Online (Sandbox Code Playgroud)TLabel向窗体添加控件。将其名称设置为lblMainText使用对象检查器。将其字体设置为视觉上令人愉悦的东西²,并将其标题设置为Press F2 to begin.
在表单的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;
Run Code Online (Sandbox Code Playgroud)运行应用程序。
按F2后:
请注意,再次按 F2 不会执行任何操作;您已经“启动”了系统。
显然,这个小答案不会教您编写 VCL 应用程序所需的全部知识。它只涉及您需要了解的内容的 0.1%。要了解更多信息,我强烈建议您购买一本关于 Delphi 编程的好书(特别是关于用 Delphi 编写 Win32 应用程序)。
¹在Delphi,全局变量和类成员被初始化(至0,0.0,False,nil,等等)。但是,局部变量永远不会被初始化(除非它们是托管类型)。
²Segoe UI根据Microsoft Windows 用户界面指南,是一个不错的选择。实际上,您可以将这种字体用于表单本身;那么所有子控件将自动继承此字体设置。
³ 这仅在表单本身具有焦点(例如,不是子控件)时才有效。为了即使子控件具有焦点也能正常工作,我最好的建议是使用TActionList. 它们真的很有用。
| 归档时间: |
|
| 查看次数: |
381 次 |
| 最近记录: |