好的,我正在从事一个最初在 D7 中完成的项目。我在这里承担双重职责,因为我正在修复原始代码中的错误并尝试将其移植到 XE3/4。当原作者在项目中使用一些非开源工具包时,有点困难。
但无论如何,该应用程序是一个脚本/宏程序。作为客户脚本/宏语言的一部分。能够为用户输入创建非常简单的基本表单。表单是在运行时根据脚本/宏作者创建的脚本/宏动态创建的。我已经修复了用于创建表单的代码中的一些错误。但是,有一点我就是想不通。
为父窗体创建 TComboBox 并设置 AT 组件创建的 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;
下面是为表单创建 TComboBox(带 TLabel)的具体代码:
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 属性。
正是因为以上这些,我才感到困惑。为什么在创建表单之后它会在此时起作用。但不是在创建表单时?p>
最佳答案
这是一个下拉列表,因为您将样式设置为csDropDownList
。这意味着组合框的编辑控件只能显示其列表控件中包含的项目。
对于下拉列表组合,设置 Text
属性无效。您应该指定 ItemIndex
,而不是使用 Text
属性。
关于forms - Delphi:在运行时以动态创建的形式创建TComboBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18868133/