delphi - 显示禁用的模态表单
问题描述
我正在尝试禁用 aTForm
的后代并将其显示为模态形式。
procedure TForm1.Button1Click(Sender: TObject);
var
Frm : TMyForm;
begin
Frm := TMyForm.Create(nil);
try
Frm.Enabled := False;
Frm.ShowModal();
finally
Frm.Free;
end;
end;
在运行时,它会引发以下错误消息:
无法制作可见的窗口模式。
解决方案
当表单应显示为只读目的时,OP 希望以模态方式显示禁用的表单。
禁用表单是错误的做法。
你如何显示信息?如果您使用TEdit
、TMemo
或TRichEdit
控件,您只需将它们设置为只读。否则,如果您有各种控件(如单选按钮)的组合,您应该禁用每个此类控件,而不是表单本身。我的意思是,您肯定还希望启用“取消”按钮吗?
另外,禁用表单而不是实际的控件会使控件看起来是启用的,这很混乱!这是很重要的一点。
因此,您需要做的是正常显示表单(不是禁用!),然后在显示对话框时将其控件设置为适当的状态。
只是为了强调我关于禁用表单及其控件的观点,请考虑以下对话框:
如果我做
procedure TCustomViewFrm.FormShow(Sender: TObject);
begin
Enabled := False;
end;
然后它看起来像这样:
如您所见,每个控件看起来确实非常启用,但没有控件响应鼠标或键盘输入。这是非常令人困惑的,也是非常糟糕的用户体验。
事实上,您甚至无法使用其标题栏关闭按钮或 Alt+F4 关闭对话框。您也无法使用其系统菜单将其关闭。事实上,您根本无法关闭它,因为要关闭一个窗口,它必须响应用户输入,而禁用的窗口不会这样做。(您也不能移动窗口。)
相反,如果我们禁用所有控件(取消按钮除外),
procedure DisableControl(AControl: TWinControl);
begin
for var i := 0 to AControl.ControlCount - 1 do
begin
if
(AControl.Controls[i] is TCustomButton)
and
(TCustomButton(AControl.Controls[i]).ModalResult = mrCancel)
then
Continue;
if AControl.Controls[i] is TWinControl then
DisableControl(TWinControl(AControl.Controls[i]));
AControl.Controls[i].Enabled := False;
end;
end;
procedure TCustomViewFrm.FormShow(Sender: TObject);
begin
DisableControl(Self);
end;
你会得到这个漂亮的用户界面:
不仅所有控件都被禁用非常清楚,用户还可以关闭对话框而无需使用任务管理器杀死您的应用程序。
推荐阅读
- python - 如何将流文件传递给执行 Python 脚本并使用属性和 Nifi 变量来存储该文件?
- javascript - 如何根据传递的值从对象中查找键值
- vue.js - 无法使用 Vue 和 Vuetify 将模板文本添加到 v-textarea
- php - 压缩问题 Excel 使用 Maatwebsite
- c++ - 为什么 C++ 中的这个函数有效,但只有在打印到标准输出时才有效?
- html - 如何计算我的代码中的盒子大小?
- elasticsearch - Elasticsearch:按时间范围分组
- javascript - Javascript - 如何检查'req.send(json);' 返回 0 或 -1
- javascript - Express 的异步中间件
- xamarin.forms - 如何使用刷新令牌通过 Xamarin.Forms 客户端从身份服务器 4 获取新的访问令牌