#delphi #modal-dialog #delphi-2010
#delphi #модальный диалог #delphi-2010
Вопрос:
Я динамически создаю форму, которая переопределяет CreateParams, чтобы она отображалась на панели задач. Из динамически созданной формы я вызываю TColorDialog, но как только он отобразится, моя форма перейдет под основную форму с ColorDialog поверх нее.
После закрытия ColorDialog динамическая форма вернется обратно поверх основной формы.
Я вижу, что в методе выполнения ColorDialog есть дескриптор, который можно передать, но я не уверен, что я на правильном пути с этим?
Если я нажму под диалогом в основной форме, он будет мигать, но как я могу заставить динамически созданную форму «владеть» этим диалогом с основной формой сзади?
Я создаю форму следующим образом:
procedure TMain.Button1Click(Sender: TObject);
var
SEMArcF: TWriteSEMArcFrm;
begin
SEMArcF := TWRiteSEMArcFrm.Create(nil);
SEMArcF.Show;
end;
и он освобождается при событии OnClose:
procedure TWriteSEMArcFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
Я переопределяю CreateParams следующим образом:
procedure TWriteSEMArcFrm.CreateParams(var Params: TCreateParams);
begin
inherited;
if (FormStyle = fsNormal) then begin
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
Params.WndParent := GetDesktopWindow;
end;
end;
и чтобы показать ColorDialog, я либо создаю его, либо просто добавляю компонент TColorDialog в форму, в любом случае результат будет одинаковым. Я хочу, чтобы он принадлежал динамической форме.
РЕДАКТИРОВАТЬ Я теперь добавляю:
Application.ModalPopupMode := pmAuto;
Полный код:
procedure TWriteSEMArcFrm.btnBackColourClick(Sender: TObject);
var
ColorDlg: TColorDialog;
begin
Application.ModalPopupMode := pmAuto;
ColorDlg := TColorDialog.Create(nil);
try
if ColorDlg.Execute then
re.Color := ColorDlg.Color;
finally
ColorDlg.Free;
end;
end;
Это работает нормально, но может ли быть какое-либо необычное поведение при установке этого параметра?
Спасибо
Крис
Комментарии:
1. Не должен ли «SEMArcF := TWRiteSEMArcFrm.Create (nil);» быть «SEMArcF:= TWRiteSEMArcFrm.Create (self);»
2. @mj2008 — Я удостоверяюсь, что форма освобождена с помощью:
Action := caFree
Основная форма может быть помещена в лоток, поэтому я хочу, чтобы она была освобождена, как только она будет закрыта. Если пользователь похож на меня и оставляет компьютер включенным навсегда, он никогда не освободится!
Ответ №1:
TColorDialog
происходит от TCommonDialog
, в котором доступны две перегруженные версии Execute()
— устаревшая версия без параметров, которая существует годами, и более новая перегрузка, которая принимает родительский HWND
параметр в качестве входного параметра. Скорее всего, вы вызываете первое. Эта перегрузка использует Handle
свойство текущего активного TForm
(только если TApplication.ModalPopupMode
для свойства не установлено значение pmNone
), возвращаясь к Handle
MainForm
значению, если это необходимо. Если вы хотите больше контроля, вам следует вызвать другую перегрузку напрямую, тогда вы можете передать свойство динамической формы Handle
в качестве значения параметра.
Комментарии:
1. Большое вам спасибо за ответ. Теперь я вызываю
Application.ModalPopupMode := pmAuto;
непосредственно перед созданием и отображением ColorDialog, и это работает. Я приму это как ответ, но хотел бы спросить — может ли это вызвать какое-либо необычное поведение в дальнейшем? Я отредактирую вопрос, чтобы показать полный код создания ColorDialog.2. Вам не нужно устанавливать свойство каждый раз, когда вы вызываете диалоговое окно. Вместо этого вы можете установить его один раз в файле main .dpr. Или просто проигнорируйте свойство и используйте
TColorDialog.Execute(HWND)
вместо него метод, например:ColorDlg.Execute(Self.Handle);
.3. Спасибо за объяснение этого и за ваше время, потраченное на то, чтобы помочь мне. Это здорово, и я многому здесь учусь 🙂