按表单名称操作表单组件

时间:2012-01-22 09:21:55

标签: forms delphi ado

我有一个Form类,用于从中生成多个表单对象。我重命名每个生成的表单。

我不知道如何访问指定的表单组件而不影响其他生成的表单组件。

我使用过这段代码,但最后创建的表单的组件总是会受到影响:

procedure TmainForm.OFBloqueButtonClick(Sender: TObject);
begin
    if (mainForm.tabSheetBool = True) AND (mainForm.OFID <> '') then begin
       if OF_bloque = False then begin
           Application.CreateForm(TOFOperationsForm, OFOperationsForm);
           OFOperationsForm.Caption := 'Bloquer OF';
           OFOperationsForm.Name := 'OFBloqueForm';
           OF_bloque := True;
       end;
       OFOperationsForm.BringToFront;
       OFOperationsForm.ADOOF.SQL.Text := 'SELECT * FROM OFTab WHERE ID=''' + OFID + '''';
       OFOperationsForm.ADOOF.Open;
    end;
end;

我的目标是完成所需表单的指定ADOQuery。

谢谢。

3 个答案:

答案 0 :(得分:4)

当您创建表单类的多个实例时,不应使用表单单元中IDE声明的变量。事实上,我知道的大多数Delphi开发人员在创建新表单后立即删除var,只有应用程序的mainform保留它,因为dpr需要它。

此外,您无需使用FindWindow查找表单,甚至无需遍历应用程序或屏幕表单。只需在创建本地var时使用:

procedure TmainForm.OFBloqueButtonClick(Sender: TObject);
var
  NewForm: TOFOperationsForm;
begin
    NewForm := nil;
    if (mainForm.tabSheetBool = True) AND (mainForm.OFID <> '') then begin
       if OF_bloque = False then begin
           NewForm := TOFOperationsForm.Create(Application);
           NewForm.Caption := 'Bloquer OF';
           NewForm.Name := 'OFBloqueForm';  //<== You'll need to make this unique!
           OF_bloque := True;
       end;
       if Assigned(NewForm) then begin
         NewForm.BringToFront;
         NewForm.ADOOF.SQL.Text := 'SELECT * FROM OFTab WHERE ID=''' + OFID + '''';
         NewForm.ADOOF.Open;
       end;
    end;
end;

修改

为上述代码添加了一些安全措施以防止AV。就目前而言,这意味着除非创建表单,否则不会更改查询。如果打算设置新表单的查询或更改最后创建的表单的查询,那么您需要TmainForm中的成员字段:

TmainForm = class(TForm)
private
  FLastFormCreated: TOFOperationsForm;
//...

并将ButtonClick处理程序中的代码更改为:

procedure TmainForm.OFBloqueButtonClick(Sender: TObject);
begin
    if (mainForm.tabSheetBool = True) AND (mainForm.OFID <> '') then begin
       if OF_bloque = False then begin
           FLastFormCreated := TOFOperationsForm.Create(Application);
           FLastFormCreated.Caption := 'Bloquer OF';
           FLastFormCreated.Name := 'OFBloqueForm';
           OF_bloque := True;
       end;
       if Assigned(FLastFormCreated) then begin
         FLastFormCreated.BringToFront;
         FLastFormCreated.ADOOF.SQL.Text := 'SELECT * FROM OFTab WHERE ID=''' + OFID + '''';
         FLastFormCreated.ADOOF.Open;
       end;
    end;
end;

我已经离开了Assigned check,因为如果没有剩余的代码,我无法判断在没有FLastFormCreated至少接收过一次引用的情况下,在逻辑上是否可以到达BringToFront(例如,如果是OF_Blogue在其他地方设置为True。

答案 1 :(得分:0)

我认为发生的事情是你创建了多个表单来擦除指向前一个表单的指针,最后你会得到一个指向最后创建表单的指针。

您可以迭代Screen.Forms以获取对所需表单的引用,这是一个示例:

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  NewForm: TForm2;
begin
  // create two forms, then show the first form
  Application.CreateForm(TForm2, NewForm);
  NewForm.Name := 'FirstForm';
  NewForm.Caption := 'This form was created 1st';
  Application.CreateForm(TForm2, NewForm);
  NewForm.Name := 'SecondForm';
  NewForm.Caption := 'This form was created 2nd';
  // iterate Screen.Forms to access the first form by name
  for i := 0 to Screen.FormCount - 1 do
    if Screen.Forms[i].Name = 'FirstForm' then
      Screen.Forms[i].Show;  // shows the first form
end;

答案 2 :(得分:0)

解决方案是:

unit main;

interface

uses
    Windows, Messages, ... , OF_operations;

type
    TmainForm = class(TForm)
    ...
    ...
    ...
    private 
    ...
    public
         OFBloqueForm, OFCancelForm, OFDelaisClientForm, OFInspectionForm: TOFOperationsForm;
    end;

// Bloquer OF
procedure TmainForm.OFBloqueButtonClick(Sender: TObject);
begin
    if (mainForm.tabSheetBool = True) AND (mainForm.OFID <> '') then begin
        if OF_bloque = False then begin
            OFBloqueForm := TOFOperationsForm.Create(Application);
            OFBloqueForm.Caption := 'Bloquer OF';
            OFBloqueForm.Name := 'OFBloqueForm';
            OF_bloque := True;
        end;
        OFBloqueForm.BringToFront;
        OFBloqueForm.ADOOF.SQL.Text := 'SELECT * FROM OFTab WHERE ID=''' + OFID + '''';
        OFBloqueForm.ADOOF.Open;
    end;
end;