荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Peter (小飞侠), 信区: Program
标  题: Delphi动态DFM文件应用(二)
发信站: BBS 荔园晨风站 (Fri Jan 22 13:45:05 1999), 转信


  2. 动态DFM文件应用之一:超媒体系统的卡片设计
  Delphi多种类型的可视部件,如文本部件、编辑部件、图形图像部件、数据库部
件、媒体媒放部件和OLE部件等,每一种部件在屏幕中占据一定的区域,具有相当丰富的
表现能力,可以作为卡片中的一种媒体,因此可以利用这些可视部件进行超媒体系统的
卡片设计。
  超媒体卡片设计要求卡片中的媒体数目和媒体种类是不受限制的,而且必须能够修
改和存取卡片,因此,采用动态DFM文件是比较合适的。而且如果利用Stream对象,将卡
片存储在数据库BLOB字段中,就为把超文本与关系数据库技术结合起来创造了契机。
  下面是超媒体卡片设计子系统中的部分源程序,它演示了如何创建对象、插入对象
和存取动态DFM文件。
  ⑴ 在应用程序中注册对象

        procedure TMainForm.FormCreate(Sender: TObject);
        begin
          RegisterClass(TLabel);
          RegisterClass(TEdit);
          RegisterClass(TMemo);
          RegisterClass(TButton);
          RegisterClass(TPanel);
          RegisterClass(TPanelP);
          RegisterClass(TBitBtn);
           …
        end;

   ⑵ 创建和插入对象

        procedure TMDIChild.FormClick(Sender: TObject);
        var
          Ctrl : TControl;
          Point: TPoint;
        begin
          GetCursorPos(Point);
          Point := BackGround.ScreenToClient(Point);
          case  CurToolIndex of
            1 : begin
                Ctrl := TLabel.Create(self);
                TLabel(Ctrl).AutoSize := False;
                TLabel(ctrl).Caption := 'Label'+S;
                TLabel(ctrl).Name := 'Label 1';
                TLabel(ctrl).Top := Point.Y;
                TLabel(ctrl).Left := Point.X;
                TLabel(Ctrl).Height := Round(100*Res/1000/Ratio);
                TLabel(Ctrl).Width := Round(600*Res/1000/Ratio);
                TLabel(Ctrl).Color := clWhite;
                TLabel(Ctrl).Font.Color := clBlack;
                TLabel(Ctrl).Font.Name := 'Roman';
                TLabel(Ctrl).Font.Height := -TLabel(Ctrl).Height;
                TLabel(Ctrl).Font.Pitch := fpFixed;
                TLabel(Ctrl).Enabled := False;
                TLabel(Ctrl).OnClick := LabelClick;
                TLabel(Ctrl).OnMouseMove := ReportPos;
                BackGround.InsertControl(Ctrl);
                CurTool.Down := False;
                CurTool := nil;
              …
              end;
            2: begin
            Ctrl := TEdit.Create(self);
            TEdit(ctrl).AutoSize := True;
            TEdit(ctrl).Top := Point.Y;
            TEdit(ctrl).Left := Point.X;
            TEdit(Ctrl).Height := 20;
            BackGround.InsertControl(Ctrl);
             …
          end;
        3:
           …
          end;
    end;

  ⑵ 存取动态DFM文件

        procedure TMainForm.FileOpen(Sender: TObject);
        begin
          if OpenDialog.Execute then
          begin
            DesignWin := TMDIChild.Create(Application);
            ReadComponentResFile(OpenDialog.FileName, DesignWin);
            DesignWin.Init;
            FileName := OpenDialog.FileName;
            DesignWin.Caption := FFileName;
          end;
        end;

  DesignWin是在TMainForm中定义的TMDIChild类型的窗体部件,是卡片设计平台;FFi
leName是私有变量,用来保存当前编辑的卡片文件名。DesignWin的Init方法实现如下:

        procedure TMDIChild.Init;
        var
          I: Integer;
          Ctrl: TControl;
        begin
          BackGround.BringToFront;
          with BackGround do
            for I:= 0 to ControlCount - 1 do
              if Controls[I].Name <> ''then
                ObjectIns.ObjectList.Items.AddObject(Controls[I].Name, Controls
                        [I]);
        end;

  BackGround是TPanel类型的部件,所有的动态创建对象都插入到BackGround中,所
以,后面调用BackGround.InsertControl(Ctrl);ObjectIns是个仿Delphi 的媒体属性
编辑器。
  动态DFM文件的存储过程是这样的:

        procedure TMainForm.FileSave(Sender: TObject);
        begin
            if DesignWin.CurControl <> nil then
               DesignWin.CurControl.Enabled := True;
            WriteComponentResFile(FFilename, DesignWin);
            DesignWin.Caption := FileName;
          end;
        end;

  因为在DesignWin的Init方法中调用了InsertControl方法,所以在关闭DesignWin窗
口时要相应地调用RemoveControl,否则在关闭DesignWin窗口时会产生内存错误。

        procedure TMDIChild.FormCloseQuery(Sender: TObject; var CanClose: Boole
                                                        an);
        var
          I: Integer;
          Ctrl: TControl;
          Removed: Boolean;
        begin
          if Modified = True then
            if MessageDlg('Close the form?', mtConfirmation,
               [mbOk, mbCancel], 0) = mrCancel then
               CanClose := False;
          if CanClose = True then
          begin
            repeat
              removed := False;
              I := 0;
              repeat
                if BackGround.Controls[I].Name <> '' then
                begin
                  BackGround.RemoveControl(BackGround.Controls[I]);
                  Removed := True;
                end;
            I := I + 1
              until (I >= BackGround.ControlCount) or (Removed = True);
            until (Removed = False);
            SendMessage(ObjectIns.Handle, WM_MDICHILDCLOSED, 0, 0);
          end;
        end;

  3. 动态DFM文件应用之二:超媒体系统脚本语言设计
  超媒体脚本语言设计是超媒体系统设计的重要内容。脚本语言必须能够表达卡片中
的多种媒体对象,必须是可编程,可理解的,必须是可执行的,应该可以由脚本语言生
成超媒体系统中的卡片和链。
  DFM文件可以看作是超媒体系统的卡片,DFM脚本能够表达DFM文件中的多种控制,也
就是说能够表达卡片中的多种媒体对象,再加上DFM脚本的对象式表达,可编辑性,可转
换为DFM文件,因此用作超媒体系统脚本语言较好的形式。
  ObjectBinaryToText和ObjectTextToBinary过程提供了在部件和DFM脚本之间相互转
化的功能,ObjectResourceToText和ObjectTextToResoure过程提供了DFM文件和DFM脚本
之间相互转化的功能。这样就可以在应用程序中自如实现超媒体卡片和超媒体脚本语言
相互转化。

  下面是卡片和脚本语言相互转化的程序:

        procedure TMDIChild.CardToScript;
    var
      In, Out: TStream;
    begin
      In := TMemoryStream.Create;
      Out := TMemoryStream.Create;
      try
        In.WriteComponentRes(Self.ClassName, Self);
        ObjectResourceToText(In, out);
        ScriptForm.ScriptEdit.Lines.LoadFromStream(Out);
      finally
        In.Free;
        Out.Free;
      end;
    end;

  ScriptEdit是个文本编辑器,它的Lines属性是TStrings类型的对象。

        procedure TScriptForm.ScriptToCard;
        var
      In, Out: TStream;
    begin
      In := TMemoryStream.Create;
      Out := TMemoryStream.Create;
      try
        ScriptForm.ScriptEdit.Lines.SaveToFromStream(In);
        ObjectTextToResource(In, out);
        In.ReadComponentRes(DesignWin);
      finally
        In.Free;
        Out.Free;
      end;
    end;

  这两段程序是对整个卡片,即窗体级,进行转换的。ObjectBinaryToText和ObjectTe
xtToBinary过程可以细化到部件级的转换。因此超媒体脚本语言的编辑可以细化到媒体
对象级。

--
※ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: 192.168.1.3]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店