2009-11-03 2 views
5

Наша заявка используется для использования общей базовой формы, из которой все формы должны были наследоваться. Я хотел бы избавиться от него по ряду причин, начиная от необходимости полиции, чтобы каждый использовал ее для нескольких неприятностей, связанных с внедрением VFI Delphi. Оказывается, основная часть предлагаемых функций может быть выполнена другими, более надежными способами.Как разместить форму перед ее показом?

Тот, о котором я не очень уверен, автоматически позиционирует все формы в центре своих абонентов. Поэтому, если я открою Dialog A из своей основной формы, он должен быть размещен над центром основной формы. И если я затем открою Dialog B из диалогового окна A, он должен быть расположен над центром диалогового окна A и так далее.

Мы позаботились обо всем этом, установив свойство Position базовой формы в poOwnerFormCenter, и он отлично поработал. Но как мне это сделать?

Я думал об использовании Screen.OnActiveFormИзменить, но я думаю, что это происходит каждый раз, когда форма получает фокус. Я также думал об использовании Application.OnModalBegin, но, похоже, нет очевидного способа найти форму в точке, которую это вызвало.

Кто-нибудь пробовал это?

ответ

5

Хорошо, очевидно, что наследование предоставляется, чтобы решить точно проблема, которую вы пытаетесь решить. Любое решение, вероятно, приведет к некорректному подражанию наследования формы.

Не могли бы вы сделать что-то так же просто, как глобальный поиск кода для «= class (TForm)» и заменить класс TForm либо вашей существующей базовой формой, либо новым, упрощенным базовым классом форм, только с необходимой функциональностью?

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

+1

+1 Я избавился от базы, потому что люди ее не использовали, и было больно ее контролировать. Поэтому я действительно хотел бы побороть вашу логику здесь, но вы правы. Я до сих пор не могу найти надежный способ позаботиться о одном или двух требованиях без базы, поэтому, я думаю, мне придется вернуть его обратно. Я определенно думаю, что я должен пропустить визуальную часть наследования, потому что это просто не работает. –

+0

Я не уверен, но возможно, что IDE Delphi можно настроить, по крайней мере, на то, чтобы помочь вам в защите класса, на котором основаны новые формы. –

0

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

+0

Проблема здесь масштаб. У нас есть несколько сотен пакетов, большинство из которых содержат несколько форм.Базовый класс был (я думаю) попыткой убедиться, что все формы ведут себя согласованно, но по прошествии лет, и люди пришли и ушли, база не использовалась последовательно. Я пытаюсь обеспечить соблюдение этой последовательности. –

4

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

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

0

Обычно для этого используется событие FormShow, используя процедуру SetBounds(). С помощью других элементов управления, отличных от формы, вы можете сделать то же самое, переопределив сообщение CMShowing.

+0

Посмотрите мои комментарии на ответ Крагена для масштаба проекта. Если я не могу эффективно использовать общий базовый класс, все, что требует изменения в каждой форме, мертво в воде. В небольших проектах вы, конечно, правы. –

0

Я принял ваше представление о OnModalBegin и побежал вместе с ним. Следующее - это «Hack», но, похоже, это работает. Для проверки просто перетащите форму и нажмите кнопку.

procedure TMainForm.Button1Click(Sender: TObject); 
var 
    mForm: TForm; 
begin 
    mForm := TForm.create(self); 
    mform.width := 300; 
    mform.height := 300; 
    mForm.ShowModal; 
    mForm.Free; 
end; 

procedure TMainForm.FormCreate(Sender: TObject); 
begin 
    application.OnModalBegin := modalbegin; 
end; 

procedure TMainForm.FormShow(Sender: TObject); 
begin 
    if Screen.FormCount>1 then begin 
    screen.forms[Screen.FormCount-1].left := round((screen.forms[Screen.FormCount-2].left + screen.forms[Screen.FormCount-2].width/2) - screen.forms[Screen.FormCount-1].width/2); 
    screen.forms[Screen.FormCount-1].top := round((screen.forms[Screen.FormCount-2].top + screen.forms[Screen.FormCount-2].height/2) - screen.forms[Screen.FormCount-1].height/2); 
    application.processmessages; 
    screen.forms[Screen.FormCount-1].Caption := inttostr(screen.forms[Screen.FormCount-1].top)+','+inttostr(screen.forms[Screen.FormCount-1].left); 
    end; 
end; 

procedure TMainForm.ModalBegin(Sender: TObject); 
begin 
    if Screen.FormCount>=0 then 
    screen.forms[Screen.FormCount-1].OnShow := FormShow; 
end; 
Смежные вопросы