Delphi, возможно сделать форму модальной только для определенной родительской формы?

У меня есть приложение, где есть основная фоновая форма, оттуда пользователь может использовать только немодальные формы, которые поддерживают другую часть системы. Немодальные формы переопределяют метод 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, но могут использовать форму обслуживания апельсинов?

Спасибо

Ответ 1

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

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

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

Ответ 2

У этого сообщения есть хороший трюк, чтобы удовлетворить ваши потребности: http://blogs.teamb.com/deepakshenoy/2006/08/21/26864

Резюме заключается в том, чтобы повторно использовать немодальное окно, которое вы хотите, когда модальное окно отключило его.

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

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

Итак, если у вас есть набор форм, которые должны жить в отдельном потоке, поместите их в одну dll, скомпилируйте его без пакетов и используйте! Он будет работать, и он будет потокобезопасным.