我有这种尴尬的情况导致异常。我发现了这个问题,但解决方案对我来说实施起来非常棘手。
在我们的应用程序中,如果用户在一段时间内保持活动状态,则安全超时程序会启动用户提示密码输入框。
但是,每当表单在FormShow()
事件期间因任何特定原因显示消息框时(此处需要注意的事项; formShow
事件执行尚未完全完成)和用户决定不单击对话框的“确定”按钮一段时间,安全代码启动并尝试隐藏所有表单,以便提示输入密码。
此方案将触发异常“无法在OnShow或OnHide中更改Visible”。
安全代码使用TScreen.FormCount
循环所有表单,并分别使用TForm(TScreen.Forms[ii]).Hide
隐藏它们。隐藏程序会导致异常,因为我觉得这个表单还没有完全完成它的加载程序。
我已经完成了测试,如果在执行FormShow()事件后显示一个消息框,则安全代码可以正常工作,并且可以毫无问题地隐藏所有窗口。
我已经尝试了几个属性和窗口消息检查,在隐藏表单之前执行“if check”,比如Screen.Forms [ii] .Visible,Screen.Forms [ii]。活跃但到目前为止没有运气。提到的表格将是可见的,并且不能保证它将处于活动状态,如果它处于活动状态,我将如何隐藏其他非活动表格。所以我的问题是,哪个属性或Windows消息表明表单已完全加载,或者至少它已超过FormShow
中存在的任何给定表单的TScreen.Forms
事件?
我需要回答我要问的问题,我需要一个需要在安全代码中实现的通用解决方案,我不能通过我们在这个巨大的应用程序中的一千多种形式,并单独尝试查找这些形式中存在任何验证/警告逻辑的解决方案。
谢谢
答案 0 :(得分:3)
简单的答案是停止在所有者表单的OnShow
中显示模式对话框。在显示模式对话框之前,请等待表单完成显示。如果您进行了更改,并且仅进行了更改,则现有代码将开始工作。
您选择的问题标题是:
无法隐藏尚未完全初始化的窗口
所以显而易见的解决方案是等到窗口完全初始化。
实现此目的的最简单方法是将当前在OnShow
中运行的代码移动到CM_SHOWINGCHANGED
的处理程序中:
procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED;
像这样实施:
procedure TMyForm.CMShowingChanged(var Message: TMessage);
begin
inherited; // this is what invokes OnShow
if Visible then
begin
// do what you previously did in OnShow
end;
end;
答案 1 :(得分:0)
David Heffernan的解决方案给了我一个想法,我在最后解决了这个问题。
我创建了以下内容;
const
WM_SHOW_MESSAGE = WM_USER + 1;
private
procedure WMShowMessage(var Msg: TMessage); message WM_SHOW_MESSAGE;
内部构造函数;
PostMessage(Handle, WM_SHOW_MESSAGE, 0, 0);
这将有消息框逻辑:
procedure MyMethod.WMShowMessage(var msg: TMessage); message WM_SHOW_MESSAGE;