Delphi: Показать окно без активации
Я изо всех сил стараюсь показать вторую форму выше основной формы, не теряя при этом фокуса.
Я пробовал ShowWindow(second.handle, SW_SHOWNOACTIVATE)
, но основная форма теряет фокус.
Если во втором окне установить Visible := false
, вызов ShowWindow
не активирует вторую форму, но окна будут пустыми, когда будет показано...
У кого-нибудь есть хороший рецепт для этого?
UPDATE: то, что я пытаюсь сделать, показывает окно уведомления в данном событии. Крайне важно, чтобы основная форма не теряла фокуса в любое время.
Ответы
Ответ 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;