ros*_*mcm 7 delphi delphi-2006
我有一个Delphi 2006应用程序,它可以弹出一个模态对话框以响应错误情况.它似乎进入一种状态,其中一个模态对话框是打开的,位于主窗体的前面,但两种形式都没有响应消息.点击其中任何一个都会给出"bonk".应用程序运行正常,UI正在更新主窗体,但您无法执行任何操作.我想主要形式下很可能还有另一个模态对话框.无论是我的还是Windows的我都不知道.
其他要点:
我打开模态对话框
ModalDialog.PopupParent := MainForm ;
ModalDialog.ShowModal ;
Run Code Online (Sandbox Code Playgroud)如果其他模态对话框打开,我推迟这些错误对话框:
if (Application.ModalLevel = 0) then
{open modal dialog}
Run Code Online (Sandbox Code Playgroud)我的问题有两个部分:
有没有办法以编程方式找出哪个窗口有焦点?然后,我可以为这个场景或最后的手段采取一些操作,我可以提供一个快捷键将其置于前面或采取一些规避行动(取决于对话框),如将ModalResult设置为mrCancel.
这种情况怎么会出现?通常当我在主窗体后面得到一个模态对话框时(我可以通过打开模态对话框,从托盘图标中最小化应用程序,然后再次恢复应用程序) - 应用程序主窗体在对话框前面恢复,对话框仍然保持焦点),我可以通过单击托盘图标再次将它带到前面,或者用Esc
键关闭它但在这种情况下它不起作用.
**更新**
Misha的解决方案与TSaveDialog之类的非delphi对话分开.通过Application.ModalPopupMode := pmAuto ;
在调用之前添加,我能够让他们工作Execute
.
通过"让它工作"我的意思是在以下序列之后保存对话框在前面:
而它没有主要形式ModalPopupMode := pmAuto
.
所以我希望这些变化能够帮助解决这个问题(尚未产生).
如果具有焦点的表单花费太长时间来响应消息(Form1),那么Windows认为Form1没有响应,然后Form1显示模式表单(Form2),在显示Form2并且应用程序再次处理消息后,Form1将被带到前面,从而可能"覆盖"Form2.
将它放在Application.OnIdle事件中就可以了:
if Assigned(Screen.ActiveForm) then
begin
if (fsModal in Screen.ActiveForm.FormState) and
(Application.DialogHandle <= 0)) then
begin
Screen.ActiveForm.BringToFront;
end;
end;
Run Code Online (Sandbox Code Playgroud)
可以使用以下命令查询最后一个活动弹出窗口(VCL 或非 VCL)GetLastActivePopup
:
function GetTopWindow: HWND;
begin
Result := GetLastActivePopup(Application.Handle);
if (Result = 0) or (Result = Application.Handle) or
not IsWindowVisible(Result) then
Result := Screen.ActiveCustomForm.Handle;
end;
Run Code Online (Sandbox Code Playgroud)
这有点抄袭自TApplication.BringToFront
。
可以通过以下方式将此窗口置于前面SetForegroundWindow
:
SetForegroundWindow(GetTopWindow);
Run Code Online (Sandbox Code Playgroud)
请注意,这Application.BringToFront
可能完全可以解决问题,但我曾经遇到过它无法正常运行的情况,但从那以后我一直无法重现这种情况。
归档时间: |
|
查看次数: |
5115 次 |
最近记录: |