Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Создание модального дочернего окна в Delphi 10: как предотвратить фокусирование на родительском окне и ограничить навигацию табуляцией только внутри дочернего окна

Delphi , Программа и Интерфейс , Модальные формы

 

В процессе разработки приложений на Delphi часто возникает необходимость создания модальных дочерних окон. Модальные окна должны быть способны захватывать фокус и не позволять пользователю взаимодействовать с родительским окном, пока модальное окно не будет закрыто. В этой статье мы рассмотрим, как создать модальное дочернее окно в Delphi 10.2+, которое будет ограничивать навигацию табуляцией только внутри себя, а не позволять пользователю переключаться на элементы родительского окна.

Проблема: Навигация табуляцией вне дочернего окна

Если вы создаете дочернее окно в Delphi в режиме времени выполнения и устанавливаете его родителем родительского окна, нажатие клавиши Tab может переключить фокус на элементы родительского окна. Это поведение может быть нежелательным, если вы хотите, чтобы пользователь мог взаимодействовать только с элементами дочернего окна.

Решение: Использование ShowModal и корректировка фокусировки

Delphi предоставляет метод ShowModal, который создает модальное окно и блокирует доступ к родительскому окну до тех пор, пока модальное окно не будет закрыто. Однако, если вы создаете дочернее окно в режиме времени выполнения и устанавливаете его родителем родительского окна, метод ShowModal может не работать должным образом. Вместо этого можно использовать события нажатия клавиш и перехватывать нажатия клавиши Tab, чтобы ограничить навигацию только внутри дочернего окна.

Шаг 1: Создание дочернего окна и установка родителя

Для начала создадим дочернее окно и установим его родителем родительского окна:

var
  GreenWindow: TForm;
begin
  GreenWindow := TForm.Create(Application);
  GreenWindow.Parent := Application.MainForm;
  GreenWindow.Position := poDesigned; // Устанавливаем позицию окна
  GreenWindow.BorderStyle := bsDialog; // Устанавливаем стиль окна для модального режима
  GreenWindow.Show;
end;

Шаг 2: Перехват нажатий клавиш Tab

Для того чтобы ограничить навигацию табуляцией только внутри дочернего окна, можно перехватывать нажатия клавиш в событиях OnKeyDown родительского и дочернего окон. В родительском окне можно установить KeyPreview := True, чтобы перехватывать нажатия клавиш до того, как они будут обработаны элементами формы.

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  FocusedControl: TWinControl;
  NextControl: TWinControl;
begin
  if Key = VK_TAB then begin
    FocusedControl := ActiveControl;
    if FocusedControl <> nil then begin
      NextControl := TWinControlAccess(Self).FindNextControl(FocusedControl, not (ssShift in Shift), True, True);

      if Assigned(NextControl) and ((NextControl = GreenWindow) or (GetParentForm(NextControl.Parent) = GreenWindow)) then
        NextControl.SetFocus;

      Key := 0; // Предотвращаем стандартное обработку
    end;
  end;
end;

Шаг 3: Перехват сообщений окна

Для более точного контроля за навигацией табуляцией можно перехватывать сообщения окна. В родительском окне можно перехватывать сообщение CM_DIALOG_KEY и предотвращать стандартную обработку нажатия клавиши Tab:

procedure TForm1.CMDialogKey(var Message: TCMDialogKey);
begin
  if GetKeyState(VK_MENU) >= 0 then begin
    if Message.CharCode = VK_TAB then 
      Exit;
  end;
  inherited;
end;

Шаг 4: Использование ShowModal

Если вы хотите использовать метод ShowModal, можно создать модальное окно и установить его родителем родительского окна. Это позволит автоматически блокировать доступ к родительскому окну:

var
  GreenWindow: TForm;
begin
  GreenWindow := TForm.Create(Application);
  GreenWindow.Parent := Application.MainForm;
  GreenWindow.Position := poDesigned;
  GreenWindow.BorderStyle := bsDialog;
  GreenWindow.ShowModal;
end;

Шаг 5: Сохранение состояния элементов родительского окна

Для того чтобы предотвратить взаимодействие с элементами родительского окна, можно сохранить их состояние и временно отключить:

var
  States: TDictionary<TControl, Boolean>;
  I: Integer;
  CMP: TComponent;
  CTRL: TControl ABSOLUTE CMP;
begin
  States := TDictionary<TControl, Boolean>.Create;
  try
    for I := 0 to ParentForm.ComponentCount - 1 do
    begin
      CMP := ParentForm.Components[I];
      if CMP is TControl then
      begin
        States.Add(CTRL, CTRL.Enabled);
        CTRL.Enabled := False;
      end;
    end;
    try
      GreenWindow.Parent := ParentForm;
      GreenWindow.ShowModal;
    finally
      for var P in States do
        P.Key.Enabled := P.Value;
    end;
  finally
    States.Free;
  end;
end;

Заключение

Создание модального дочернего окна в Delphi требует внимания к деталям, особенно если вы хотите ограничить навигацию табуляцией только внутри дочернего окна. Использование метода ShowModal и перехват нажатий клавиш позволяет добиться желаемого поведения. Важно также учитывать, что использование родительского окна как родителя для дочернего окна может привести к неожиданным результатам, поэтому лучше использовать метод ShowModal или корректно перехватывать сообщения окна.

Надеюсь, эта статья поможет вам создать модальные дочерние окна в Delphi и обеспечить правильное поведение приложения.

Создано по материалам из источника по ссылке.

Context: В статье описывается создание модальных дочерних окон в Delphi, блокирующих доступ к родительскому окну и ограничивающих навигацию табуляцией только внутри дочернего окна.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Модальные формы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-03-22 18:20:44/0.0035998821258545/0