发信人: lofe ()感激生活(), 信区: BorlandDev
标  题: Delphi动态DFM文件应用
发信站: 哈工大紫丁香 (Mon Sep  4 16:03:39 2000), 转信

                  Delphi动态DFM文件应用(一)                                      
1. 动态DFM文件概述                                                          
    动态DFM文件是相对于静态DFM文件而言。所谓静态DFM文件是指在Delphi开发环境     
中设计的窗体文件。窗体的设计过程就是程序的编制过程。因此,动态DFM文件就是指     
在程序运行过程生成或存取的DFM文件。                                             
  动态DFM文件的创建和使用分别如下两种情况:                                   
  ● 在程序运行过程中,由Create方法动态生成窗体或部件,然后动态生成其它部     
件插入其中生成DFM文件.                                                           
  ● 在Delphi开发环境中,设计生成DFM文件,然后用DFM 文件存取函数,或者用Str   
  由Delphi的窗体设计的常规方法生成的DFM文件在程序运行一开始就规定了部件的     
结构。因为在窗体设计过程中,窗体中的每个部件都在程序的对象声明中定义了部件变    
量。这种固定的结构虽然能方便应用,但以牺牲灵活性为代价。                        
  在Delphi应用程序中有时需要在运行过程中创建控制,然后将该控制插入另一个部    
                                                                                
件中。例如:                                                                    
  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);                                               
                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;                                           
        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;                                                                  
  DesignWin是在TMainForm中定义的TMDIChild类型的窗体部件,是卡片设计平台;

        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: Boolean);                    
        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);                                          
                                                                                
        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和
ObjectTextToBinary过程可以细化到部件级的转换。因此超媒体脚本语言的编辑可以细化到媒体对象级。                                                                        
tToBinary过程可以细化到部件级的转换。因此超媒体脚本语言的编辑可以细化到媒体对象级。                                                                                  

--
※ 修改:.haojs 于 Sep  4 16:00:11 修改本文.[FROM: bbs.hit.edu.cn]
--
※ 转寄:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: bbs.hit.edu.cn]

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: haojs.bbs@bbs.whnet.]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:411.795毫秒