好的,我正在从事一个最初在 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属性。
正是因为上述,我感到困惑。为什么它在创建表单之后在这一点上起作用。但不是在创建表单时?