![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сохранение положения форм при последующем входе в программу. [D2005, 2003]
Abcdef123 © (2011-07-27 07:31:00)Здравствуйте, Мастера!
Некоторые клиенты наших программ стали использовать несколько мониторов на компе, и просят, чтобы мы изменили настройки положения форм на экране, так как не всегда для этих клиентов теперь удобно работать.
До сегодняшнего момента во всех рабочих проектах нашей компании главная форма проекта fsMDIForm и Position poDefault. Остальное большинство форм fsMDIChild и Position poScreenCenter. А вот клиенты хотят, чтоб если они сдвинут форму как им удобно, чтоб при последующих запусках программы положение формы такое же (измененное ими).
Думаю, что понятно объяснила проблему. В интернете я посмотрела, существуют компоненты на такой случай. Но, начальство не хочет использовать дополнительные компоненты (так как нужно будет при каждой инсталляции дельфи дополнительно еще на это время тратить, а также в будущем заботиться о совместимости версий компонента, когда версию Дельфи будем менять). Так что вопрос такой - поскольку "велосипед" уже кем-то изовретен, можно ли скачать исходники такого компонента, или программу-утилиту, которая поможет мне просто подключить это к проекту и не зависеть от сторонних инсталляций компонентов?
Принимаются любые дельные советы и замечания. Возможно я даже не в правильном направлении иду, и возможно надо бы просто использовать уже какой-то готовый компонент (хотя как я сказала, на данный момент у меня не большой выбор - это решение начальства).
Возможно, кто то уже использует что-то для решения данной задачи, какие бы посоветовали компоненты, в случае если прогу не найти? ...Буду признательна любой информации на эту тему.
Заранее благодарна,
Надежда.
SQLEXPRESS (2011-07-27 12:38:00) [21]
> Про создание форм из списка и восстановление рабочей области
> MDI речи не было
а зачем тогда весь сыр-бор? :)
> Вот пользователь закрыл некую MDI-форму, потом приложение.
НЕ!
и все, на момент закрытия приложения формы не было - потому ничего никуда не храним.
На CloseQuery вешаем сохранение открытых форм, а на старте их восстанавливаем - вот, имхо, вполне ожидаемая реакция от приложения.
> Вопрос: где она должна быть и откуда мы это узнаем?
хороший вопрос :)
Загрузка конфигурации тоже можно тогда.
ее можно как ты сказал сделать
Dennis I. Komarov (2011-07-27 12:27:00) [22]Я лишь предложил считывание координат в общем конструкторе. Про создание форм из списка и восстановление рабочей области MDI речи не было.
Вот пользователь закрыл некую MDI-форму, потом приложение. Далее, как я понимаю, все что было должно сохраниться куда-то. Теперь открыли - восстановилось что сохранили. Далее жмем некий кнопарь - открыть (создать) ту самую "некую". Вопрос: где она должна быть и откуда мы это узнаем?
З.Ы.
Если бы я делал подобное:
Загрузка конфигурации (по умолчанию)
Возможность сохранить ее и соответственно загрузить по желанию пользователя.
SQLEXPRESS (2011-07-27 12:13:00) [23]был бы признателен, если бы кто научил не регистрировать класс, прежде чем создать окно по его имени
SQLEXPRESS (2011-07-27 12:11:00) [24]автор может перебрать все формы на момент закрытия и записать их класс и положение(размеры). Что еще? По-моему, ничего.
и будет у него
Класс1, x, y
Класс2, x, y
Класс2, x, y
затем создавать, при запуске
имеем строку с именем класса - создаем. По координатам устанавливаем.
> может быть создан не один экземпляр формы от одного класса,
правильно
имеем строку с именем класса, такую же, - создаем. По координатам устанавливаем.
Но как можем создать окно, имея строку с именем?
GetClass(имя) не вернет ничего без RegisterClass(имя)
поэтому, делаем RegisterClass всех возможных MDI чайлдов, а потом getclass
ну или if в ини_старта_ встретилась строка 'TFORMX', then RegisterClass('TFORMX')
Dennis I. Komarov (2011-07-27 11:47:00) [25]
> создай форму имея s:string = 'TFormX';
Откуда такое условие? У автора нет ничего подобного. И потом, может быть создан не один экземпляр формы от одного класса, поэтому привязывать координаты формы к классу будет не правильно...
SQLEXPRESS (2011-07-27 11:25:00) [26]
> Почему?
а как?
создай форму имея s:string = 'TFormX';
Dennis I. Komarov (2011-07-27 11:15:00) [27]
> однако, все формы уже от TForm созданы,
Unit1;
....
AnyForm: TFormX;
у TFormX перекрываем конструктор(деструктор) читаем (сохраняем) позицию формы.
> еще один уровень не спасет от RegisterClass(
Почему?
SQLEXPRESS (2011-07-27 10:59:00) [28]
> Dennis I. Komarov © (27.07.11 10:40) [9]
можно, тогда еще проще создавать будет, универсальнее
однако, все формы уже от TForm созданы, еще один уровень не спасет от RegisterClass(
Dennis I. Komarov (2011-07-27 10:40:00) [29]Не проще ли сделать один класс от TForm (или какой там у MDI), подправить его маленько и остальные наследовать уже от него?
SQLEXPRESS (2011-07-27 09:55:00) [30]for i := 0 to MDIChildCount - 1 do
begin
ToXXX(IntToStr(MDIChildren[i].Left));
ToXXX(IntToStr(MDIChildren[i].Top));
ToXXX(MDIChildren[i].ClassName);
end;
имеем:
x
y
TfrmXXX
-----------
Воссоздавать
все дочки придется тупо-жестко перечислить. Не страшно, сколько там классов-окон .. не 150 же :)
RegisterClass( TfrmMDISubject );
...
RegisterClass( TfrmMDISubject N );
и далее
CL ;= GetClass('TfrmXXX');
Application.CreateForm(TFormClass(CL), OutForm);
OutForm.top := y;
OutForm.left := x;
Омлет (2011-07-27 08:33:00) [31]А еще установленные компоненты увеличивают время запуска IDE, что не приносит радости.
Омлет (2011-07-27 08:30:00) [32]> Юрий Зотов © (27.07.11 08:15) [4]
> Собственно, компоненты для того и пишутся, чтобы прикладники ими пользовались и тем самым сильно упрощали себе жизнь.
Цена такого упрощения не всегда оправдана:
1. Чтобы скомпилировать проект новому разработчику или после переустановки дельфи, надо все компоненты установить.
2. При переходе на новую версию дельфи (особенно в свете последних юникод-версий), не все старые компоненты оказываются работоспособны (не развиваются, заброшены и т.п.). Особенно весело, когда они только в dcu есть. Или приходится заново покупать под нужную версию.
3. Часто компоненты идут большими наборами. Используя всего один из набора, можно ощутимо увеличить размер exe, т.к. там тянется много зависимого кода. А это, к тому же, влияет на скорость запуска программы..
Поэтому люди сводят к минимуму использование компонентов.
> Юрий Зотов © (27.07.11 08:19) [5]
> А чтобы сохранить/восстановить ВСЕ открытые формы?
Не намного сложнее.
> А также состояние всех контролов на них?
Такой задачи не было. Сохранение предыдущей сессии (как в браузерах) - отдельная задача. И просто каким-то компонентом её не решить, в общем случае.
Юрий Зотов (2011-07-27 08:19:00) [33]> Чтобы запомнить и восстановить положение формы,
> надо несколько строк кода.
А чтобы сохранить/восстановить ВСЕ открытые формы? А также состояние всех контролов на них?
Юрий Зотов (2011-07-27 08:15:00) [34]> для мелких вещей лучше не использовать сторонние компоненты, т.к. с
> ними могут возникнуть проблемы в будущем).
Не вижу таких проблем. Особенно при наличии исходников.
Собственно, компоненты для того и пишутся, чтобы прикладники ими пользовались и тем самым сильно упрощали себе жизнь.
Омлет (2011-07-27 08:12:00) [35]Компоненты, компоненты... Зачем? Чтобы запомнить и восстановить положение формы, надо несколько строк кода.
Читаем:
IniFile := TIniFile.Create(GetIniFullFileName);
try
with IniFile do
begin
if not ReadBool(GENERAL_SECTION, MAXIMIZED_KEY, false) then
begin
SystemParametersInfo(SPI_GETWORKAREA, 0, @WorkArea, 0);
with WorkArea do
begin
DW := Right - Left;
DH := Bottom - Top;
end;
W := Min(ReadInteger(GENERAL_SECTION, WIDTH_KEY, Width), DW);
H := Min(ReadInteger(GENERAL_SECTION, HEIGHT_KEY, Height), DH);
L := Max(ReadInteger(GENERAL_SECTION, LEFT_KEY, Left), 0);
T := Max(ReadInteger(GENERAL_SECTION, TOP_KEY, Top), 0);
if (L + W > DW) then
L := Max(0, DW - W);
if (T + H > DH) then
T := Max(0, DH - H);
SetBounds(L, T, W, H);
end
else begin
WindowState := wsMaximized;
end;
finally
IniFile.Free;
end;
Сохраняем, соответственно:
WriteInteger(GENERAL_SECTION, WIDTH_KEY, Width);
WriteInteger(GENERAL_SECTION, HEIGHT_KEY, Height);
WriteInteger(GENERAL_SECTION, LEFT_KEY, Left);
WriteInteger(GENERAL_SECTION, TOP_KEY, Top);
WriteBool(GENERAL_SECTION, MAXIMIZED_KEY, WindowState = wsMaximized);
Как-то так. Не проверял на двух мониторах.
Юрий Зотов (2011-07-27 08:11:00) [36]> можно ли скачать исходники такого компонента
Можно. Такой компонент есть в RxLib, ее исходники открыты и есть в Сети. Называется он TFormPlacement. Еще обратите внимание на компонент TFormStorage, он тоже может оказаться очень полезным.
И. Павел (2011-07-27 08:06:00) [37]Сохраняю позицию форм и размеры элементов на ней с помощью TINIFile (и набора аналогичных функций из библиотеки AlphaControls - если ее использую).
Для быстрой установки новых компонент можно использовать специальные программы, например - DelphiPi (но начальство вам правильно говорит - для мелких вещей лучше не использовать сторонние компоненты, т.к. с ними могут возникнуть проблемы в будущем).