Delphi, возможно сделать форму модальной только для конкретной родительской формы? - PullRequest
11 голосов
/ 21 января 2009

У меня есть приложение, в котором есть основная фоновая форма, оттуда пользователь может только немодальные формы, которые поддерживают другую часть системы. Немодальные формы переопределяют метод CreateParams, поэтому каждая из них отображает кнопку на панели задач запуска:

procedure TfmMaterialsPlanning.CreateParams(var Params: TCreateParams);
begin
   inherited;
   //create a new window on the task bar when this form is created
   Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
end;

По сути, пользователь может открыть немодальную форму, которая поддерживает «Яблоки», еще одну немодальную форму, которая поддерживает «Апельсины», и использовать панель меню «Пуск» для простого переключения между ними.

Однако, если они открывают модальную форму из формы «Яблоки», например, чтобы задать параметры, предпочтения и т. д., они не смогут использовать формы «Апельсины», пока не закроют модальную форму.

Можно ли сделать модальную форму модальной только для родительской формы? Так что, если они откроют форму параметров Apple, они не смогут использовать форму обслуживания Apple, но все равно смогут использовать форму обслуживания «Апельсины»?

Ответы [ 5 ]

6 голосов
/ 21 января 2009

Если вы посмотрите на исходный код TCustomForm.ShowModal (), вы увидите, что VCL не использует вызов Windows API для отображения модальных диалогов, но вместо этого отключает все другие формы в приложении, в то время как модальная форма показана. Конечно, вы можете попробовать то же самое, просто Показать () диалоговое окно формы-моды, затем отключить родительский элемент, а затем снова включить его после закрытия диалогового окна формы-режима. Там должно быть центральное место, где вы будете отслеживать формально-модальные диалоги, формы, которые необходимо повторно включить и так далее. Однако вам следует тщательно проверить, действительно ли код выполняет то, что вам нужно, даже при переключении между приложениями, при минимизации приложения и т. Д.

Сказав это, я не думаю, что это хорошая идея. Это нарушает все предположения пользователя Windows относительно поведения приложений. В отличие от Mac OS X, в Windows нет различий между диалоговыми окнами приложений и модальностей, и вам следует придерживаться поведения, совместимого с платформой, для которой вы программируете.

Скорее всего, есть лучший способ структурировать ваш интерфейс. Взгляните на соответствующую страницу для диалоговых окон в «Руководстве по взаимодействию с пользователем». Модальные диалоги лучше избегать, насколько это возможно, связанные рекомендации показывают лучшие альтернативы для многих вариантов использования. Если вы ограничиваете использование модальных диалогов, возможно, вам больше не нужны формально-модальные диалоги.

3 голосов
/ 15 сентября 2010

В этом посте есть хороший прием для удовлетворения ваших потребностей: http://blogs.teamb.com/deepakshenoy/2006/08/21/26864

Суть в том, чтобы снова включить немодальное окно, которое вы хотите, когда модальное окно отключило его.

0 голосов
/ 21 января 2009

Как и в стороне (хотя это было бы очень много работы), другой подход к этой проблеме - это путь Google Chrome, где каждая «вкладка» представляет собой отдельный процесс, но представляется пользователю как единое интегрированное приложение. ,

Даже если этот подход позволит достичь того, чего вы хотели, я должен согласиться с комментарием выше, что это нарушит предположения и ожидания пользователя относительно модального поведения.

0 голосов
/ 21 января 2009

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

Редактировать: Это должно быть возможно, даже если vcl не является потокобезопасным. Пожалуйста, посмотрите на объяснение Алексея как это можно сделать:

Так что, если у вас есть набор форм, которые должны находиться в отдельном потоке, поместите их в одну dll, скомпилируйте ее без пакетов и используйте! Это будет работать, и это будет потокобезопасным.

0 голосов
/ 21 января 2009

Не могли бы вы добиться того же эффекта, не позволяя форме «Яблоки» принимать фокус, пока открыта ее дочерняя форма?

...