2

好的,我正在从事一个最初在 D7 中完成的项目。我在这里做双重职责,因为我正在修复原始代码中的错误并尝试将其移植到 XE3/4。当原作者为项目使用一些非开源工具包时,有点难。

但无论如何,该应用程序是一个脚本/宏程序。作为客户脚本/宏语言的一部分。可以为用户输入创建非常简单的基本表单。表单是在运行时根据脚本/宏作者创建的脚本/宏动态创建的。我已经修复了创建表单的代码中的一些错误。但是,有一个我就是想不通。

在为父窗体创建 TComboBox 并设置 Text 属性时创建组件。不显示 Text 属性中的文本。

这是创建表单的代码:

procedure CreateForm(var wFrm: TForm; sName: String);
var
  iLoop, iPos, iLen: Integer;
  iFormHeight, iFormWidth: Integer;
  lh, hresult1, hresult2: Integer;
  sWork, sWork2, sLine, CmdName: String;
  lstForm, lst: TStringList;
  pnl: TPanel;

begin
  iFormHeight := 80;
  iFormWidth := 400;
  hresult1 := 0;
  lst := TStringList.Create;

  iLoop := lstForms.IndexOf(Trim(UpperCase(sName)));
  if iLoop < 0 then
  begin
    AbortError('Form "' + sName + '" could not be found!');
    Exit;
  end;

  lstForm := TStringList(lstForms.Objects[iLoop]);

  for iLoop := 0 to lstForm.Count - 1 do
  begin
    sLine := lstForm[iLoop];
    iPos := Pos('=', sLine);
    iLen := Length(sLine);
    if iPos = 0 then
      continue;

    CmdName := Uppercase(Trim(Copy(sLine, 1, iPos - 1)));
    sWork2 := Trim(Copy(sLine, iPos + 1, iLen));

    if CmdName = 'FORMCAPTION' then
    begin
      with wfrm do
      begin
        Caption := Trim(Copy(sLine, iPos + 1, iLen));
        Name := Trim(sName);
        Height := iFormHeight;
        Width := iFormWidth;
        Tag := 10;
        BorderStyle := bsSizeable;
        BorderIcons := [biSystemMenu];
        Position := poDesktopCenter;
        pnl := TPanel.Create(wfrm);
        with pnl do
        begin
          Parent := wfrm;
          Caption := '';
          Align := alBottom;
          BevelInner := bvNone;
          BevelOuter := bvNone;
          Height := 30;
        end;
        with TButton.Create(wfrm) do
        begin
          Parent := pnl;
          Caption := '&OK';
          Default := True;
          ModalResult := mrOK;
          Left := 235;
          Top := 0;
        end;
        with TButton.Create(wfrm) do
        begin
          Parent := pnl;
          Caption := '&Cancel';
          Cancel := True;
          ModalResult := mrCancel;
          Left := 310;
          Top := 0;
        end;
        pnl := TPanel.Create(wfrm);
        with pnl do
        begin
          Parent := wfrm;
          Caption := '';
          Align := alClient;
          BevelInner := bvRaised;
          BevelOuter := bvNone;
          BorderWidth := 5;
        end;
      end;
    end
    else
    begin
      lst.Clear;
      StringToList(sWork2, lst, ':');
      if UpperCase(lst[0]) = 'EDITBOX' then
        CreateEditBox
      else if UpperCase(lst[0]) = 'CHECKBOX' then
        CreateCheckBox
      else if UpperCase(lst[0]) = 'COMBOBOX' then
        CreateComboBox
      else if UpperCase(lst[0]) = 'LABEL' then
        CreateLabel;
    end;
  end;

  with wfrm do
  begin
    if hresult1 > 1 then
      hresult2 := 5
    else
      hresult2 := 9;
    Tag := Tag + hresult2;
    Height := Height + hresult2;
  end;

  lst.Free;
end;

下面是为表单创建带有 TLabel 的 TComboBox 的具体代码:

  procedure CreateComboBox;
  var
    iPos: Integer;
  begin
    with TLabel.Create(wfrm) do
    begin
      Parent := pnl;
      Caption := lst[1];
      Left := 15;
      if hresult1 > 1 then
        hresult2 := 5 * hresult1
      else
        hresult2 := 3 * hresult1;
      Top := wfrm.Tag + hresult2;
      Name := 'lbl' + CmdName;
      Width := 150;
      WordWrap := True;
      AutoSize := True;
      lh := Height;
    end;
    hresult1 := Trunc(lh/13);
    with TComboBox.Create(wfrm) do
    begin
      Parent := pnl;
      Left := 170;
      Width := 200;
      if hresult1 > 1 then
        hresult2 := 5 * hresult1
      else
        hresult2 := 3 * hresult1;
      Top := wfrm.Tag + hresult2;
      Style := csDropDownList;
      Name := UpperCase(CmdName);
      Text := 'Test Text';
      sWork := lst[3];
      lst.Clear;
      StringToList(sWork, lst, ',');
      for iPos := 0 to lst.Count - 1 do
        lst[iPos] := lst[iPos];
      Items.Assign(lst);
//      ItemIndex := 0;
    end;
    wfrm.Tag := wfrm.Tag + ((hresult1 * 13)+ 13);
    wfrm.Height := wfrm.Height + ((hresult1 * 13)+ 13);
    TComboBox(wfrm
  end;

注意:上述过程是 CreateForm 过程的子过程。

该应用程序使用 TStringList 列表将表单定义存储在脚本/宏运行时。然后,当作者希望显示表单时,上面的代码检索该信息以创建表单。然后在显示之前创建表单并将表单对象放入另一个临时 TStringList 列表中。这样做是为了当用户运行脚本/宏并按照表单中的要求输入信息/设置时。作者可以在表单被销毁之前从表单中检索请求的信息/设置。

表单从 tmp TStringList 列表中删除(如果以前创建),创建,存储在 tmp TStringList 列表中,并使用以下代码模态显示:

    iPos := lstForms.IndexOf(UpperCase(sWVar2));
    if iPos < 0 then
    begin
      AbortError('Could not find form "' + Trim(sWVar2) + '" defined!');
      Exit;
    end;

    iPos := lstFormsTMP.IndexOf(UpperCase(sWVar2));
    if iPos > -1then
    begin
      TForm(lstFormsTMP.Objects[iPos]).Free;
      lstFormsTMP.Delete(iPos);
      frm.Free;
      iPos := lstFormsTMP.IndexOf(UpperCase(sWVar2));
      if iPos > -1 then
      begin
        AbortError('Form "' + Trim(sWVar2) + '" was not removed from the lstFormsTMP TStringList.');
        Exit;
      end;
    end;

    frm := TForm.Create(frmMain);
    CreateForm(frm, sWVar2);
    lstFormsTMP.AddObject(Uppercase(sWVar2), frm);
  end;

  iPos := lstFormsTMP.IndexOf(UpperCase(sWVar2));
  if iPos < 0 then
  begin
    AbortError('Could not find form "' + Trim(sWVar2) + '" defined!');
    Exit;
  end;

  hndHold := SwitchToHandle(frmMain.Handle);
  try
    Result := TForm(lstFormsTMP.Objects[iPos]).ShowModal = mrOK;
  finally
    SwitchToHandle(hndHold);
  end;

使用上面的代码集,创建并显示了运行脚本中定义的表单,没有很多错误/错误。但是,即使我已经硬编码了 TComboBox.Text 属性的文本。它没有显示。任何人都可以对我为什么会这样吗?到目前为止,所有其他表单组件 TCheckBox、TEditBox、TLabel 都可以正常显示。只是 TComboBox 让我困惑地挠头。

注意:最终 TComboBox.Text 属性将根据表单组件定义中该属性的作者设置动态设置。

提前致谢。

2013 年 8 月 18 日编辑,包括以下内容:

原始代码还包括通过 TIniFile 对象保存/加载表单组件设置的能力。以下代码用于保存 TComboBox 的设置:

  if frm.Components[i] is TCombobox then
    iniWork.WriteString(frm.Name, TCombobox(frm.Components[i]).Name, TCombobox(frm.Components[i]).Text)
  else

以及以下加载 TComboBox 设置:

  if frm.Components[i] is TCombobox then
  begin
    TCombobox(frm.Components[i]).ItemIndex := TCombobox(frm.Components[i]).Items.IndexOf(
      iniWork.ReadString(frm.Name, TCombobox(frm.Components[i]).Name, TCombobox(frm.Components[i]).Text));
  end

使用上面的代码,在我看来,设置正在保存并加载回 TComboBox 的 Text 属性。现在,当加载 TComboBox 设置时,在创建表单并将其作为对象放置到 tmp TStringList 列表中并在模态显示之前更改表单。然而,当显示表单时,将显示由上述加载代码设置的Text属性。

正是因为上述,我感到困惑。为什么它在创建表单之后在这一点上起作用。但不是在创建表单时?

4

1 回答 1

2

这是一个下拉列表,因为您将样式设置为csDropDownList。这意味着组合框的编辑控件只能显示包含在其列表控件中的项目。

对于下拉列表组合,设置Text属性无效。而不是使用该Text属性,您应该指定ItemIndex.

于 2013-09-18T09:15:23.613 回答