Как обрабатывать выравнивание компонентов во время выполнения после изменения размера экрана delphi - PullRequest
0 голосов
/ 14 февраля 2020

Я много искал в Google, чтобы получить более четкую информацию о том, как мне решить мою текущую проблему, но я получил масштабируемость компонентов как лучший ответ, это ... еще не моя проблема.

Итак Короче говоря, я хочу перестроить компоненты в моей форме после того, как пользователь изменит размер окна, форма динамически заполняется из запроса SQL, это код конструктора:

procedure TForm2.MakeWindow;
var
  dummyMaskedit, dummyEdit: TEdit;
  dummyMemo: TMemo;
  dummyCombobox: TComboBox;
  dummyLabel: TLabel;
  dummyLBox: TListBox;
  dummybutton: TButton;
  i, f: integer;
  buffer, workarea: double;
begin
  FDQDB.Close;
  FDQDB.Open('SELECT * FROM Defs WHERE active = 1');

  i := 0;
  f := 1;
  buffer := Layout1.Width;
  workarea := Layout1.Width;
  SetLength(aMasks, 0);
  while not FDQDB.Eof do
  begin
    case AnsiIndexStr(FDQDB.FieldByName('comptype').AsString,
      ['tedit', 'tcombobox', 'tmaskedit', 'tlistbox']) of
      0: // TEdit
        begin
          dummyEdit := TEdit.Create(self);
          dummyEdit.Parent := Form2.Layout1;
          dummyEdit.Width := FDQDB.FieldByName('size').AsInteger;
          if buffer - dummyEdit.Width >= 0 then
          begin
            buffer := buffer - dummyEdit.Width - 8;
            dummyEdit.Position.Y := Panel2.Position.Y + 22 + (45 * i);
            dummyEdit.Position.X := workarea - buffer - dummyEdit.Width + 5;
          end
          else
          begin
            inc(i);
            buffer := workarea;
            buffer := buffer - dummyEdit.Width - 8;
            dummyEdit.Position.Y := Panel2.Position.Y + 22 + (45 * i);
            dummyEdit.Position.X := workarea - buffer - dummyEdit.Width + 5;
          end;
          dummyEdit.Name := 'field' + IntToStr(f);
          inc(f);

          dummyLabel := TLabel.Create(self);
          with dummyLabel do
          begin
            Parent := dummyEdit.Parent;
            Text := FDQDB.FieldByName('Descricao').AsString;
            Position.Y := dummyEdit.Position.Y - 17;
            Position.X := dummyEdit.Position.X;
          end;
        end;

      1: // TComboBox
        begin
          dummyCombobox := TComboBox.Create(self);
          dummyCombobox.Parent := Form2.Layout1;
          dummyCombobox.Width := FDQDB.FieldByName('size').AsInteger;
          if buffer - dummyCombobox.Width >= 0 then
          begin
            buffer := buffer - dummyCombobox.Width - 8;
            dummyCombobox.Position.Y := Panel2.Position.Y + 22 + (45 * i);
            dummyCombobox.Position.X := workarea - buffer -
              dummyCombobox.Width + 5;
          end
          else
          begin
            inc(i);
            buffer := workarea;
            buffer := buffer - dummyCombobox.Width - 8;
            dummyCombobox.Position.Y := Panel2.Position.Y + 22 + (45 * i);
            dummyCombobox.Position.X := workarea - buffer -
              dummyCombobox.Width + 5;
          end;
          dummyCombobox.Name := 'field' + IntToStr(f);
          dummyCombobox.Items.Delimiter := '|';
          dummyCombobox.Items.StrictDelimiter := true;
          dummyCombobox.Items.DelimitedText :=
            AnsiUpperCase(FDQDB.FieldByName('combovalue').AsString);
          inc(f);

          dummyLabel := TLabel.Create(self);
          with dummyLabel do
          begin
            Parent := dummyCombobox.Parent;
            Text := FDQDB.FieldByName('Descricao').AsString;
            Position.Y := dummyCombobox.Position.Y - 17;
            Position.X := dummyCombobox.Position.X;
          end;
        end;

      2: // TMaskEdit
        begin
          dummyMaskedit := TEdit.Create(self);
          dummyMaskedit.Parent := Form2.Layout1;
          dummyMaskedit.Width := FDQDB.FieldByName('size').AsInteger;
          if buffer - dummyMaskedit.Width >= 0 then
          begin
            buffer := buffer - dummyMaskedit.Width - 8;
            dummyMaskedit.Position.Y := Panel2.Position.Y + 22 + (45 * i);
            dummyMaskedit.Position.X := workarea - buffer -
              dummyMaskedit.Width + 5;
          end
          else
          begin
            inc(i);
            buffer := workarea;
            buffer := buffer - dummyMaskedit.Width - 8;
            dummyMaskedit.Position.Y := Panel2.Position.Y + 22 + (45 * i);
            dummyMaskedit.Position.X := workarea - buffer -
              dummyMaskedit.Width + 5;
          end;
          dummyMaskedit.Name := 'field' + IntToStr(f);
          inc(f);

          SetLength(aMasks, length(aMasks) + 1);
          Masks.field := dummyMaskedit.Name;
          Masks.mask := FDQDB.FieldByName('mask').AsString;
          aMasks[length(aMasks) - 1] := Masks;

          dummyMaskedit.OnExit := MaskTextExit;

          dummyLabel := TLabel.Create(self);
          with dummyLabel do
          begin
            Parent := dummyMaskedit.Parent;
            Text := FDQDB.FieldByName('Descricao').AsString;
            Position.Y := dummyMaskedit.Position.Y - 17;
            Position.X := dummyMaskedit.Position.X;
          end;
        end;

      3: // TListBox
        begin
          dummyLBox := TListBox.Create(self);
          dummyLBox.Parent := Form2.Layout1;
          dummyLBox.Width := FDQDB.FieldByName('size').AsInteger;
          inc(i);
          buffer := workarea;
          if buffer - dummyLBox.Width >= 0 then
          begin
            buffer := buffer - dummyLBox.Width - 8;
            dummyLBox.Position.Y := Panel2.Position.Y + 22 + (45 * i);
            dummyLBox.Position.X := workarea - buffer - dummyLBox.Width + 5;
          end
          else
          begin
            inc(i);
            buffer := workarea;
            buffer := buffer - dummyLBox.Width - 8;
            dummyLBox.Position.Y := Panel2.Position.Y + 22 + (45 * i);
            dummyLBox.Position.X := workarea - buffer - dummyLBox.Width + 5;
          end;
          dummyLBox.Name := 'field' + IntToStr(f);
          inc(f);

          SetLength(aMasks, length(aMasks) + 1);
          Masks.field := dummyLBox.Name;
          Masks.mask := FDQDB.FieldByName('mask').AsString;
          aMasks[length(aMasks) - 1] := Masks;

          dummyLabel := TLabel.Create(self);
          with dummyLabel do
          begin
            Parent := dummyLBox.Parent;
            Text := FDQDB.FieldByName('Descricao').AsString;
            Position.Y := dummyLBox.Position.Y - 17;
            Position.X := dummyLBox.Position.X;
          end;

          dummybutton := TButton.Create(self);
          with dummybutton do
          begin
            Parent := dummyLBox.Parent;
            Text := '+';
            Width := 20;
            Position.X := dummyLBox.Width + dummyLBox.Position.X + 3;
            Position.Y := dummyLBox.Position.Y;
            Name := 'ba' + dummyLBox.Name;
            OnClick := ButtonsAddClick;
          end;

          dummybutton := TButton.Create(self);
          with dummybutton do
          begin
            Parent := dummyLBox.Parent;
            Text := '-';
            Width := 20;
            Position.X := dummyLBox.Width + dummyLBox.Position.X + 3;
            Position.Y := dummyLBox.Position.Y + 28;
            Name := 'br' + dummyLBox.Name;
            OnClick := ButtonsRemClick;
          end;
        end;
    end;
    FDQDB.Next;
  end;
  FDQDB.Close;
end;

Это хорошо работает и довольно в оконном состоянии приложения, этот код применяется к событию onCreate в форме:

procedure TForm2.FormCreate(Sender: TObject);
begin
  FDCDB.Params.Database := ExtractFilePath(ParamStr(0)) + 'window.db';
  MakeWindow;
end;

Первая форма, основная форма приложения, это та, которая вызывает новую форму, которая имеет компоненты, встроенные во время выполнения:

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  Application.CreateForm(TForm2, Form2);
  Form2.Layout1.parent := Self.Layout1.Parent;
  Form2.Layout1.Width := Self.Layout1.Width;
end;

Вторая форма имеет TLayout, как и первая форма. Затем, когда я создаю форму, я помещаю TLayout второй формы в первую. Пока все хорошо, это работает, когда приложение запускается в оконном режиме. Но когда я переключаю form1 в полноэкранный режим, затем нажимаю кнопку, которая создает форму2, компоненты остаются в том же положении, что и в оконном режиме. Я попытался изменить переменную рабочей области на эти:

Screen.width, //components behave as the application were in fullscreen the whole time
Screen.WorkAreaWidth, //same as screen.width
(Layout1.Parent as TLayout).Width, //invalid typecast
(Layout1.GetParentComponent as TLayout).Width //invalid typecast

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

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Но когда я переключаю форму form1 в полноэкранный режим, затем нажимаю кнопку, которая создает форму2, компоненты остаются на той же позиции, что и в оконном режиме.

На TForm1.SpeedButton1Click() вы вызов Application.CreateForm(TForm2, Form2); который вызывает TForm2.FormCreate(Sender: TObject); который вызывает MakeWindow. На данный момент Form2 знает только о размере времени проектирования.

После того, как MakeWindow завершено, TForm1.SpeedButton1Click() продолжается:

Form2.Layout1.parent := Self.Layout1.Parent;
Form2.Layout1.Width := Self.Layout1.Width;

, но это больше не влияет на макет элементов управления.

Вам необходимо установить Form2.Layout1.Width перед тем, как позвонить MakeWindow, например:

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  Application.CreateForm(TForm2, Form2);
  Form2.Layout1.parent := Self.Layout1.Parent;
  Form2.Layout1.Width := Self.Layout1.Width;
  MakeWindow; // remove it from TForm2.FormCreate()
end;
0 голосов
/ 14 февраля 2020

Форма имеет свойства ClientWidth и ClientHeight, которые хорошо работают в OnResize для динамического изменения размера элемента управления в зависимости от доступной области. OnResize срабатывает до того, как форма становится видимой. Например, чтобы иметь Memo1 с границей 100 вокруг него:

procedure TForm1.FormResize(Sender: TObject);
begin
  memo1.Position.X := 100;  // Only needs to be done once but here so all code is in one spot
  memo1.Position.Y := 100;
  memo1.Width := form1.ClientWidth - 200;
  memo1.Height := form1.ClientHeight - 200;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...