场景是我有一个‘主应用’和一个‘助手应用’。“助手应用程序”会在键盘钩子上弹出,执行相应的操作,然后重新聚焦应用程序主窗口。问题是,如果主应用程序在助手处于活动状态时弹出一个模式对话框,然后助手重新聚焦到错误的窗口,则模式对话框被隐藏,主应用程序显示为“冻结”。
有什么解决这个问题的策略建议吗?
发布于 2011-12-17 22:54:00
看起来“主应用程序”的模式窗体不属于主应用程序窗口,否则模式窗体将始终位于主窗体之上。因此,可能是编译时的Delphi版本没有MainFormOnTaskbar
属性,或者没有设置。则必须是隐藏的应用程序窗口拥有这些窗口。
你可以在关闭'helper app‘表单时测试应用程序主窗口是否被禁用(如果有模式表单的话就是这种情况),如果是的话,可以恢复隐藏的应用程序窗口所拥有的最后一个活动弹出窗口。
var
Wnd: HWND; // handle to 'main app's main form
mWnd: HWND; // handle to possible modal form
AppWnd: HWND; // handle to hidden Application window
begin
..
if not IsWindowEnabled(Wnd) then begin // test if there's a modal form
AppWnd := GetWindowLong(Wnd, GWL_HWNDPARENT); // TApplication window handle
mWnd := GetLastActivePopup(AppWnd); // most recently active popup window
// restore focus to mWnd
end else
// restore focus to Wnd
(当然,不要忘记包括对API函数结果的测试。)
发布于 2011-12-16 17:09:21
尝试使用Application.Restore
或Application.RestoreTopMosts
。当通过WinAPI调用显示该模式对话框时,也可以在前面尝试Application.Normalize(All)TopMosts
。
现在,这可能已经足够了,但在我自己的应用程序中,它对任务栏隐藏了应用程序句柄,它不是足够的,我需要以下例程作为TApplicationEvents.OnActivate
事件的处理程序:
procedure TMainForm.AppEventsActivate(Sender: TObject);
var
TopWindow: HWND;
begin
TopWindow := GetLastActivePopup(Application.Handle);
if (TopWindow <> 0) and (TopWindow <> Application.Handle) then
begin
BringToFront;
SetForegroundWindow(TopWindow);
end;
end;
说明:Application.BringToFront
中的代码几乎相同,但它不能保证在后台也显示主窗体。也就是说,Application.BringToFront
可能只显示模式对话框。
https://stackoverflow.com/questions/8529946
复制相似问题