Подтвердить что ты не робот

Delphi: Показать окно без активации

Я изо всех сил стараюсь показать вторую форму выше основной формы, не теряя при этом фокуса.

Я пробовал ShowWindow(second.handle, SW_SHOWNOACTIVATE), но основная форма теряет фокус. Если во втором окне установить Visible := false, вызов ShowWindow не активирует вторую форму, но окна будут пустыми, когда будет показано...

У кого-нибудь есть хороший рецепт для этого?

UPDATE: то, что я пытаюсь сделать, показывает окно уведомления в данном событии. Крайне важно, чтобы основная форма не теряла фокуса в любое время.

4b9b3361

Ответ 1

В вашем коде должно быть что-то не так.

Я протестировал этот код, он работает:

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

Будьте осторожны с использованием Visible, а не Show! В противном случае он переопределит SW_SHOWNOACTIVATE.

Ответ 2

Вы можете показать окно (не модальное) и reset фокус на главном окне.

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

Протестировано в 2006 году.

Это не отображает другую форму сверху. Но очень интригует иметь окно сверху, которое не имеет фокуса.

Ответ 3

Я использовал это в прошлом

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

Я не тестировал это с помощью последних версий Delphi, хотя...

Ответ 4

Если возможно, вам следует рассмотреть возможность использования какого-либо окна подсказки инструмента для отображения информации уведомления. Инструмент не будет крать фокус из главного окна, когда он отображается или когда пользователь нажимает на него. У обычной формы будет граница по умолчанию, и если пользователь нажмет на эту границу, ваша основная форма потеряет фокус.

Вот какой базовый код для этого. Кончик исчезает, когда набирается свобода; однако вам лучше настроить таймер, чем использовать сон.

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

Ответ 5

Здесь вы находитесь:

  // 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...

Ответ 6

Я сделал это в прошлом, но у меня нет кода, потому что он был проприетарным на последней задаче (извините).

Если я хорошо помню, то что я сделал:

  • Из класса клиента A вызовите процедуру (или функцию), которая не принадлежит ни к какому классу (традиционный метод Pascal).
  • Из этого метода вызовите некоторый метод в классе B, который не наследует от TForm
  • Из метода в B создайте экземпляр всплывающей формы P, но без родителя или владельца; и вызовите метод в экземпляре.
  • Из метода, вызванного в экземпляре, показать себя.

Код (на шаге 3) может выглядеть примерно так:

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

Извините, если это не сработает, у меня тоже нет Delphi.

Ответ 7

Код Daniels работает до...

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;