![](/img/trans.png)
[英]How to Validate InputQuery user input before the user clicks OK?
[英]How to create a modeless dialog box and close it when the user clicks ok?
用户坚持在应用程序中为每个“重要事件”设置一个弹出框,而在备注或列表框中添加一行是不可接受的。
我不能使用标准模式框,因为PC经常是无用的,我的应用程序将等待用户单击“确定”后再继续。
我是否可以动态创建带有备忘录组件和“确定”按钮的表单,并传递一些文本以显示在备忘录中?
我尝试了一下,单击“确定”后出现访问冲突。
问题:
Google并不是那么有用,因为表单应该销毁自己,而示例中有其创建者销毁它。
主要形式:
theDialogForm := TDialogFormForm.Create(Nil);
theDialogForm.ShowTheForm('Database error '+#13+#10+''+#13+#10+
E.ClassName+#13+#10+
E.Message);
和对话框形式...
unit fDialogForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TDialogFormForm = class(TForm)
Memo1: TMemo;
OkButton: TButton;
procedure OkButtonClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
procedure ShowTheForm(const theMessage : String);
end;
implementation
{$R *.dfm}
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
procedure TDialogFormForm.FormCreate(Sender: TObject);
begin
Visible := False;
end;
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
procedure TDialogFormForm.OkButtonClick(Sender: TObject);
begin
// Close();
Free();
end;
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
procedure TDialogFormForm.ShowTheForm(const theMessage : String);
begin
Memo1.Text := theMessage;
Show();
end;
end.
调用堆栈
main thread ($630):
005164e3 +013 StoreRoom.exe Vcl.Controls TControl.WMLButtonUp
00515b30 +2d4 StoreRoom.exe Vcl.Controls TControl.WndProc
0051a47b +5b3 StoreRoom.exe Vcl.Controls TWinControl.WndProc
00537bf0 +06c StoreRoom.exe Vcl.StdCtrls TButtonControl.WndProc
00519ad0 +02c StoreRoom.exe Vcl.Controls TWinControl.MainWndProc
0048dea4 +014 StoreRoom.exe System.Classes StdWndProc
76677885 +00a USER32.dll DispatchMessageW
005b7c63 +0f3 StoreRoom.exe Vcl.Forms TApplication.ProcessMessage
005b7ca6 +00a StoreRoom.exe Vcl.Forms TApplication.HandleMessage
005b7fd9 +0c9 StoreRoom.exe Vcl.Forms TApplication.Run
00823616 +17a StoreRoom.exe StoreRoom 56 +24 initialization
75c43398 +010 kernel32.dll BaseThreadInitThunk
要关闭表格,您可以
Close
关闭它,并在OnClose事件中将action设置为caFree
Release
,这是Free的一种特殊风格,特别是对于表单。 调用Free
的问题在于,当您仍在处理关闭按钮上的click事件时,将立即释放该窗体。 在该过程中,窗体和按钮因此被释放,从而导致访问冲突。 Release
内部将消息发送到表单,导致单击处理后关闭。
FormStyle
设置为fsStayOnTop
nil
传递给Create()
Close
然后在表单的OnClose
事件中将Action
设置为caFree
。 您为什么不轻松自如地制作一个看起来像对话框的不可见面板,当发生重大事件时该面板变为可见,而当用户单击“确定”时该对话框不可见?
因为它是无模式显示的,所以有必要启动一个线程来显示表单吗?
VCL不是多线程的。 您应该始终在主线程中运行表单。 您可能会在额外的线程dunno中调用Win32 API ShowMessageBox,但随后仅用于一条消息。 无法将事件累积到TMemo或网格中。
我应该通过什么作为构造函数参数(价格)?
我会通过应用程序,但这没什么大不了的。
当用户单击“确定”时,我应该怎么称呼? Close()还是Free()?
两者都不是创建/删除表单的依据。 只有当您可以具有许多相同类的形式时,它才有意义。 这次,只需在程序启动/结束时使Delphi自动创建并自动处理它即可。
您只应显示或隐藏它。 手动创建和处置没有意义。
现在,关于线程-为什么要完全阻止应用程序? 将该窗口设置为AlwaysOnTop,然后使用TApplication.OnActivate事件检查用户何时切换到该窗口,并将该窗口置于屏幕/主窗体的前面和中央。 这样该用户就会看到它。
或者,您可以尝试使用Snarl之类的第三方通知工具,并提供邮件永不过期的选项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.