windows - 多个应用程序窗口激活无法正常工作

标签 windows delphi focus

我有一个 Delphi 应用程序,它的主窗体是文档浏览器。当用户打开文档时,我们会打开一个编辑器窗口。我们希望每个编辑器的任务栏和主窗体上都有一个按钮。我已经应用普通代码来执行此操作(如下),但是当我在使用编辑器窗口后单击主窗体时,编辑器位于顶部,而焦点位于主窗体上。我无法弄清楚是什么导致了这种行为。

阶段设置:我打开主窗体和文档窗体。

  1. 点击另一个应用,点击主窗体,主窗体保持焦点。 (表现符合预期。)

  2. 点击文档窗体,点击主窗体,出现文档窗体 回到前面,但显示为非事件状态。 (图为结果)

alt text http://www.matthew-jones.com/temp_xfer/titlebarfailure.jpg

第一步,这是Delphi 2007,我在项目中有:

Application.MainFormOnTaskBar := True;

对于主窗体,我没有额外的代码。

对于文件形式,我有

procedure TCommonEditForm.CreateParams(var params: TCreateParams);
begin
  inherited;
  params.WndParent := 0; // GetDeskTopWindow; no diff
end;

我已经尝试确定是否有导致这种情况发生的消息,但找不到任何合适的信息。我在代码中搜索了与“激活”有关的任何内容。欢迎提供线索!

最佳答案

我的应用程序按照您描述的方式工作。这是我采取的方法。我本来想找到一种更简单的方法,但从未这样做过。

我是从阅读这些文章开始的。第一个是 Peter Below 写的一篇很棒的文章:

http://groups-beta.google.com/group/borland.public.delphi.winapi/msg/e9f75ff48ce960eb?hl=en

其他信息也在这里找到,但这并没有被证明是一个有效的解决方案:供我使用: http://blogs.teamb.com/DeepakShenoy/archive/2005/04/26/4050.aspx

最终这就是我的结局。

我的启动画面兼作应用程序主窗体。主窗体与应用程序对象有特殊关系。使用所有次要形式让我得到我正在寻找的行为。

在任务栏上我想要的每个表单中,我都覆盖了 CreateParams。我在我的编辑表单和用户看到的“主表单”上执行此操作

procedure TUaarSalesMain.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent := GetDesktopWindow;
end;

就 Delphi 而言,我的“主”窗体在其 Activitate 函数中加载了真正的主窗体。我使用一个成员变量来跟踪第一次激活。然后在函数结束时我隐藏启动窗体,但不要关闭它。这对我来说很重要,因为如果用户正在编辑文档并关闭主窗体,我不希望编辑屏幕同时被强制关闭。这样,所有可见的表单都得到相同的处理。

    if FFirstActivate = false then
      exit;

    FFristActivate := false;

    /* 
       Main Load code here 
       Update Splash label, repaint
       Application.CreateForm
       etc.
    */


    // I can't change visible here but I can change the size of the window
    Self.Height := 0;
    Self.Width := 0;
    Self.Enabled := false;

    //  It is tempting to set Self.Visible := false here but that is not
    // possible because you can't change the Visible status inside this
    // function.  So we need to send a message instead.
    ShowWindow(Self.Handle, SW_HIDE);

  end;

但是还是有问题。当所有其他表单关闭时,您需要关闭主/启动窗口。我对 Parent <> nil 的关闭例程进行了额外检查,因为我将表单用作插件(出于我的目的,它们比框架更好用)。

我不太喜欢使用 Idle 事件,但我没有注意到这会拖累 CPU。

{
  TApplicationManager.ApplicationEventsIdle
  ---------------------------------------------------------------------------
}
procedure TApplicationManager.ApplicationEventsIdle(Sender: TObject;
  var Done: Boolean);
begin

  if Screen.FormCount < 2 then
    Close;
end;

{
  TApplicationManager.FormCloseQuery
  ---------------------------------------------------------------------------
}
procedure TApplicationManager.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
var
  i: integer;
begin

  for i := 0 to Screen.FormCount - 1 do
  begin
    if Screen.Forms[i] <> self then
    begin
      // Forms that have a parent will be cleaned up by that parent so
      // ignore them here and only attempt to close the parent forms
      if Screen.Forms[i].Parent = nil then
      begin
        if Screen.Forms[i].CloseQuery = false then
        begin
          CanClose := false;
          break;
        end;
      end;
    end;
  end;

end;

{
  TApplicationManager.FormClose
  ---------------------------------------------------------------------------
}
procedure TApplicationManager.FormClose(Sender: TObject;
  var Action: TCloseAction);
var
  i: integer;
begin

  for i := Screen.FormCount - 1 downto 0 do
  begin
    if Screen.Forms[i] <> self then
    begin
      // Forms that have a parent will be cleaned up by that parent so
      // ignore them here and only attempt to close the parent forms
      if Screen.Forms[i].Parent = nil then
      begin
        Screen.Forms[i].Close;
      end;
    end;
  end;

end;

到目前为止,这对我很有帮助。我确实为 Vista 做了一个小改动,因为我的“主/启动画面”屏幕的图标仍在显示。我不记得那是什么了。我可能不需要在初始屏幕上设置宽度、高度、启用和发送隐藏消息。我只是想确保它没有出现 :-)。

处理关闭事件是必要的。如果我没记错的话,Windows 发送关机消息时需要这样做。我认为只有主窗体才能收到该消息。

关于windows - 多个应用程序窗口激活无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/802279/

相关文章:

java - 是否可以使用Java webstart执行.exe或dll?

java - 告诉eclipse重新加载环境变量

delphi - 如何更新 Delphi 10.4 Sydney 安装?

xml - 如何在 Delphi 中对 XML 文件使用查询?

delphi - 如何在非事件表单上显示提示

jquery - 将焦点设置为 KeyDown 和 KeyUp 事件之间的 SELECT 时出现问题(Firefox bug?)

html - 输入文本前的行

windows - 如何获取属于某个进程的打开句柄数?

c++ - pdCurses 在 Windows 中使用,与 3 个 gcc 宏混淆

javascript - 如何获取没有焦点的输入的选定文本/插入符号位置?