На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Обязательно выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Этот раздел предназначен для вопросов, посвященных разработке компонентов, а также для тестирования собственных бесплатных компонентов с открытым исходным кодом.

Здесь запрещается:
1. Размещать ссылки на какие-либо коммерческие компоненты, реализующие требуемую функциональность.
2. Обсуждать и тестировать коммерческие компоненты или компоненты с закрытым кодом.
3. Давать ссылки на сайты с исходным кодом компонентов. Все тестируемые исходные коды должы быть размещены на сайте ИСХОДНИКИ.RU.
Модераторы: Rouse_, DimaBr
  
> Компонент сохранения положения и размера дочерних окон
    Здравствуйте!

    Уже использовал RxLib TFormPlacement:
    http://it.kgsu.ru/DelRXTools/delrxt0003.html
    http://www.rxlib.ru/rx/rxTools/FormPlacement/index.htm
    в общем всем удовлетворял, но есть баги, хочу избавиться от RxLib по десяти причинам :D

    Нужен на замену хороший компонент сохраняющий положение и размер дочерних окон программы. Если такие уже есть среди стандартных Delphi XE или JVCL или DevExpress - пойдёт. Если нет - было бы здорово написат ьновый, только желательно компактный строго для этих целей, без нагромождений.
      Странно, что в комплекте JVCL есть нужный JvFormPlacement, но почему-то он не включен ни в одну библиотеку... как его подключить в библиотеку System?
        Цитата delphicoding @
        Странно, что в комплекте JVCL есть нужный JvFormPlacement, но почему-то он не включен ни в одну библиотеку

        Есть unit JvFormPlacement. В нём есть класс TJvFormPlacement, который используется как базовый класс для компонента TJvFormStorage (в этом же юните). В палитре компонентов он на вкладке Jv Persistence. Там же компоненты TJvApp*Storage, отвечающие за запись состояния в реестр/ini/xml.
          Погодите, не понял... если я правильно помню по унаследованному RxLib - TJvFormStorage - записывает состояние КОМПОНЕНТОВ ФОРМЫ, а не положения формы... тогда как FormPlacement делал именно то, то нужно - сохранял положение и размер окон. Так что, теперь в JVCL это делает TJvFormStorage или TJvApp*Storage? (функции FormStorage как было в RxLib сохранение параметров компонентов формы мне не нужно!)
            Да его с нуля написать - 10 минут
              Ну ты профи, тебе 10минут, кто спорит :D
              Но поскольку компонент наверняка использует какие-то другие подключаемые компоненты из общей библиотеки - боюсь это вместо 10минут займёт 10часов минимум. ;)
                Да чего там сложного для каждой формы надо хранить пять параметров:
                - WindowState
                - Left
                - Top
                - Width
                - Height
                соответственно напиши две процедуры одну для сохранения и вторую для загрузки параметров формы.
                ExpandedWrap disabled
                  procdure SaveFormState(aForm: TForm);
                  var
                    ini: TIniFile;
                  begin
                    ini := TIniFile.Create('my.ini');
                    with aForm do
                    begin
                      ini.WriteInteger(aForm.Name, 'WindowState', WindowState);
                      ini.WriteInteger(aForm.Name, 'Left', Left);
                      ini.WriteInteger(aForm.Name, 'Top', Top);
                      ini.WriteInteger(aForm.Name, 'Width', Width);
                      ini.WriteInteger(aForm.Name, 'Height', Height);
                    end;
                    ini.Free;
                  end;
                   
                  procdure LoadFormState(aForm: TForm);
                  var
                    ini: TIniFile;
                  begin
                    ini := TIniFile.Create('my.ini');
                    with aForm do
                    begin
                      WindowState := ini.ReadInteger(aForm.Name, 'WindowState', WindowState);
                      if WindowState = 2 then
                      begin
                        Left := ini.ReadInteger(aForm.Name, 'Left', Left);
                        Top := ini.ReadInteger(aForm.Name, 'Top', Top);
                        Width := ini.ReadInteger(aForm.Name, 'Width', Width);
                        Height := ini.ReadInteger(aForm.Name, 'Height', Height);
                      end;
                    end;
                    ini.Free;
                  end;

                Если надо сохранить состояние все форм то
                ExpandedWrap disabled
                    For i := 0 to Application.ComponentCount - 1 do
                     if Application.Components[i] is TForm then
                       SaveFormState(Application.Components[i]);

                Загрузка состояния формы
                ExpandedWrap disabled
                    LoadFormState(Form1);


                PS
                могут быть ошибки писал прям здесь
                потратил 9 минут

                Добавлено
                Цитата VahaC @
                могут быть ошибки

                таки они были, вот исправленный код
                ExpandedWrap disabled
                  procedure SaveFormState(aForm: TForm);
                  var
                    ini: TIniFile;
                  begin
                    ini := TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
                    with aForm do
                    begin
                      ini.WriteInteger(aForm.Name, 'WindowState', Integer(WindowState));
                      ini.WriteInteger(aForm.Name, 'Left', Left);
                      ini.WriteInteger(aForm.Name, 'Top', Top);
                      ini.WriteInteger(aForm.Name, 'Width', Width);
                      ini.WriteInteger(aForm.Name, 'Height', Height);
                    end;
                    ini.Free;
                  end;
                   
                  procedure LoadFormState(aForm: TForm);
                  var
                    ini: TIniFile;
                  begin
                    ini := TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
                    with aForm do
                    begin
                      WindowState := TWindowState(ini.ReadInteger(aForm.Name, 'WindowState', Integer(WindowState)));
                      if Integer(WindowState) = 0 then
                      begin
                        Left := ini.ReadInteger(aForm.Name, 'Left', Left);
                        Top := ini.ReadInteger(aForm.Name, 'Top', Top);
                        Width := ini.ReadInteger(aForm.Name, 'Width', Width);
                        Height := ini.ReadInteger(aForm.Name, 'Height', Height);
                      end;
                    end;
                    ini.Free;
                  end;

                сохранить состояние все форм
                ExpandedWrap disabled
                    For i := 0 to Screen.FormCount -1 do
                     SaveFormState(Screen.Forms[i]);
                  Спасибо огромное, может правда получится избавиться от этой глючащей библиотеки RxLib...

                  По поводу сохранения - я вообще-то использую не ini файл, а реестр ветвь HKEY_CURRENT_USER\Software\SoftName
                    Цитата delphicoding @
                    я вообще-то использую не ini файл, а реестр ветвь HKEY_CURRENT_USER\Software\SoftName

                    переделки на 2 минуты
                    ExpandedWrap disabled
                      procedure SaveFormState(aForm: TForm);
                      var
                        Reg: TRegistry;
                      begin
                        Reg := TRegistry.Create;
                        Reg.RootKey := HKEY_CURRENT_USER;
                        Reg.OpenKey('\Software\My App\' + aForm.Name, True);
                        with aForm do
                        begin
                          Reg.WriteInteger('WindowState', Integer(WindowState));
                          Reg.WriteInteger('Left', Left);
                          Reg.WriteInteger('Top', Top);
                          Reg.WriteInteger('Width', Width);
                          Reg.WriteInteger('Height', Height);
                        end;
                        Reg.Free;
                      end;
                      Выглядит здорово, надо тестировать!

                      Этот компонент будет просто подключаться или будет отображаться в Design иконкой и в ObjectInspector будут видны параметры ?

                      Просто хотелось бы иметь возможность там быстро клацнув мышкой выбирать что нужно сохранить - высоту / ширину / положение : сохранить / восстановить оригинальное; и очень кстати был бы параметр "Если окно вылезло за экран: восстановить оригинальный размер формы (для небольших строгих форм) / вписать в родительское окно (для больших таблиц) / ничего".
                        Цитата delphicoding @
                        Этот компонент будет просто подключаться или будет отображаться в Design иконкой и в ObjectInspector будут видны параметры ?

                        Это не компонент а просто процедуры которые "умеют" сохранять и восстанавливать состояние формы переданной в эти процедуры.

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

                          ExpandedWrap disabled
                            procedure SaveFormStateToReg(aForm: TForm);
                            var
                              Reg: TRegistry;
                              AppTitle: String;
                            begin
                              Reg := TRegistry.Create;
                              try
                                Reg.RootKey := HKEY_CURRENT_USER;
                                AppTitle := Application.Title;
                                if AppTitle = '' then
                                  AppTitle := 'My application';
                                Reg.OpenKey('\Software\' + AppTitle + '\' + aForm.Name, True);
                                with aForm do
                                begin
                                  Reg.WriteInteger('WindowState', Integer(WindowState));
                                  Reg.WriteInteger('Left', Left);
                                  Reg.WriteInteger('Top', Top);
                                  Reg.WriteInteger('Width', Width);
                                  Reg.WriteInteger('Height', Height);
                                end;
                              finally
                                Reg.Free;
                              end;
                            end;
                             
                            procedure SaveAllAppForms;
                            var
                              I: Integer;
                            begin
                              for I := 0 to Screen.FormCount - 1 do
                                SaveFormStateToReg(Screen.Forms[I]);
                            end;
                             
                            procedure CheckFormPlacement(aForm: TForm);
                            var
                              Rct: TRect;
                            begin
                              //Получаем размер рабочей области
                              SystemParametersInfo(SPI_GETWORKAREA, 0, @Rct, 0);
                              //Проверяем размеры формы чтобы небыли большими от размеров рабочей области
                              if aForm.Left + aForm.Width > Rct.Right then    //ширина
                                aForm.Left := Rct.Right - aForm.Width;
                              if aForm.Top + aForm.Height > Rct.Bottom then   //высота
                                aForm.Top := Rct.Bottom - aForm.Height;
                              //Проверяем чтобы вся форма находилась в рабочей области
                              if aForm.Left < Rct.Left then                   //левая сторона
                                aForm.Left := Rct.Left;
                              if aForm.Top < Rct.Top then                     //верхняя сторона
                                aForm.Top := Rct.Top;
                              if aForm.Width > Rct.Right then                 //правая сторона
                                aForm.Width := Rct.Right;
                              if aForm.Height > Rct.Bottom then               //нижняя сторона
                                aForm.Height := Rct.Bottom;
                            end;
                             
                            procedure LoadFormStateFromReg(aForm: TForm; const aCheckPlacement: Boolean);
                            var
                              Reg: TRegistry;
                              AppTitle: String;
                            begin
                              Reg := TRegistry.Create;
                              try
                                Reg.RootKey := HKEY_CURRENT_USER;
                                AppTitle := Application.Title;
                                if AppTitle = '' then
                                  AppTitle := 'My application';
                                if Reg.OpenKeyReadOnly('\Software\' + AppTitle + '\' + aForm.Name) then
                                  with aForm do
                                  begin
                                    WindowState := TWindowState(Reg.ReadInteger('WindowState'));
                                    if WindowState = wsNormal then
                                    begin
                                      Left := Reg.ReadInteger('Left');
                                      Top := Reg.ReadInteger('Top');
                                      Width := Reg.ReadInteger('Width');
                                      Height := Reg.ReadInteger('Height');
                                    end;
                                  end;
                              finally
                                Reg.Free;
                                if aCheckPlacement and (aForm.WindowState = wsNormal) then
                                  CheckFormPlacement(aForm);
                              end;
                            end;

                          ПС
                          Мало ли, мож кому еще пригодится.
                          Сообщение отредактировано: VahaC -
                            Ты крут!
                            Спасибо огромное!
                            :good:
                            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                            0 пользователей:


                            Рейтинг@Mail.ru
                            [ Script execution time: 0,0430 ]   [ 16 queries used ]   [ Generated: 16.04.24, 20:45 GMT ]