21

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

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

有人有这方面的好食谱吗?

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

4

7 回答 7

29

你的代码一定有问题。

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

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

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

于 2009-03-31T13:24:40.780 回答
2

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

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

2006 年测试。

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

于 2009-03-31T12:50:12.313 回答
2

我过去用过这个

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

不过,我还没有用最新版本的 Delphi 测试过这个......

于 2009-03-31T15:42:06.363 回答
1

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

这是执行此操作的一些基本代码。调用 free 时提示消失;但是,您最好设置一个计时器而不是使用睡眠。

with THintWindow.Create(nil) do
  try
    ActivateHint(MyRect, 'My Notification');
    Sleep(DisplayTime);
  finally
    Free;
  end
于 2009-03-31T17:40:16.530 回答
1

这个给你:

  // 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...
于 2009-03-31T18:21:51.487 回答
1

我过去这样做过,但我没有代码,因为它在上一份工作中是专有的(对不起)。

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

  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。

于 2009-03-31T18:22:50.970 回答
0

丹尼尔斯代码一直有效,直到......

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;
于 2016-05-17T10:01:27.680 回答