【问题标题】:Delphi: Show window without activationDelphi:显示没有激活的窗口
【发布时间】:2010-10-16 14:06:08
【问题描述】:

我很难在不失去焦点的情况下在主窗体上方显示第二个窗体。

我试过ShowWindow(second.handle, SW_SHOWNOACTIVATE),但主窗体失去焦点。 如果我在第二个窗口上设置Visible := false,对ShowWindow 的调用不会激活第二个窗体,但显示时窗口是空的...

有人有这方面的好方法吗?

更新:我正在尝试做的是在给定事件中显​​示通知窗口。关键是主窗体在任何时候都不会失去焦点。

【问题讨论】:

  • 嗯...我的一个编辑不见了...我猜SO之前有一些问题...?

标签: delphi focus window


【解决方案1】:

丹尼尔斯代码工作直到 ...

ShowWindow(Form2.Handle, SW_SHOWNOACTIVATE);
Form2.Visible := True;

直到您的第二个表单动态创建。然后您的第二个表单位于位置 0,0,默认宽度和高度。

ShowWindow被执行时,你会在屏幕上看到第二个表单,在执行下一行时消失。

我正在使用动态创建的透明覆盖表单的代码。以下代码是给定答案的组合,并将未激活的第二个表单放在父表单上。

SetWindowPos(Form2.Handle, HWND_TOP, Left, Top, Width, Height, SWP_NOACTIVATE);
Form2.Visible := True;

【讨论】:

    【解决方案2】:

    你的代码一定有问题。

    我测试了这段代码,它可以工作:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      ShowWindow(Form2.Handle, SW_SHOWNOACTIVATE);
      Form2.Visible := True;
    end;
    

    小心使用Visible,而不是Show!否则它将覆盖SW_SHOWNOACTIVATE

    【讨论】:

    • 很抱歉,它仍然处于激活状态:-(
    • 我修改了答案并测试了它:)
    • 哇,太神奇了 :-) 技巧似乎是在设计时让 visible 为 false,并在调用 showwindow() 后将其设置为 true。谢谢!
    • 太棒了。除了设置可见标志之外,我尽一切努力让它为我工作。它还有助于在我遇到显示问题之前修复屏幕外渲染和重新定位。给我一个 :)
    • 正好需要这样的例子:)
    【解决方案3】:

    我过去做过这个,但我没有代码,因为它在上一份工作中是专有的(抱歉)。

    如果我没记错的话,我所做的是:

    1. 从客户端类 A 调用不属于任何类的过程(或函数)(传统的 Pascal 方法)。
    2. 从该方法调用不从 TForm 继承的 B 类中的某个方法
    3. 从 B 中的方法,创建弹出窗体 P 的实例,但没有父或所有者;并调用实例中的方法。
    4. 从实例中调用的方法中,显示自身。

    (第 3 步的)代码可能是这样的:

    var p: TPopupForm;
    begin
      p := TPopupForm.Create(nil);
      p.ShowWindow;
      p.Release;
    end;
    

    如果这不起作用,我很抱歉,我也没有 Delphi。

    【讨论】:

      【解决方案4】:

      你在这里:

        // you have set your 2nd form as non resizable, without border nor title etc...
        Form2.Enabled := False; // prevent the 2nd form to grab focus even when clicked
        SetWindowPos(Form2.Handle, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOMOVE);
        // be sure to hide it automatically when done as it is disabled...
      

      【讨论】:

      • 这让它在不设置Form Visible的情况下真正可见?
      【解决方案5】:

      如果可能,您应该考虑使用某种工具提示窗口来显示通知信息。工具提示在显示或用户单击时不会从您的主窗口中窃取焦点。默认情况下,常规表单将具有边框,如果用户单击该边框,您的主表单将失去焦点。

      这里有一些基本的代码来做到这一点。调用 free 时提示消失;但是你最好设置一个计时器而不是使用睡眠。

      with THintWindow.Create(nil) do
        try
          ActivateHint(MyRect, 'My Notification');
          Sleep(DisplayTime);
        finally
          Free;
        end
      

      【讨论】:

      • 也许这是最简单的方法,但我必须自定义提示窗口以显示不仅仅是简单的文本......
      【解决方案6】:

      我以前用过这个

      SetWindowPos(WindowHandle, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOMOVE);
      

      不过,我还没有用最新版本的 Delphi 对此进行过测试......

      【讨论】:

        【解决方案7】:

        您可以显示窗口(非模态)并将焦点重置到主窗口。

        procedure TMainForm.ButtonClick(Sender: TObject);
        begin
          OtherForm.Show;
          SetFocus;
        end;
        

        在 2006 年测试。

        这不会在顶部显示其他表单。但是在顶部有一个没有焦点的窗口是非常违反直觉的。

        【讨论】:

        • 但这足以触发事件和数据存储等,我不希望那样......
        • 这在各种情况下都不起作用,例如,如果您在主窗体的子窗体中工作(例如编辑文本)并且主窗体需要弹出通知。你丢失了你正在输入的任何字符加上将焦点设置回主窗体并没有将焦点设置回你正在编辑的原始子窗体。这个问题困扰了我很长时间,直到我发现 DR 的简单(我应该想到的)修复。
        猜你喜欢
        • 2013-04-11
        • 2021-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多