★★★怎么把dfm放在单独的文件或dll中,而不编译到程序里,运行时再载入★★★(100)

C

chbqq

Unregistered / Unconfirmed
GUEST, unregistred user!
怎么把dfm文件(注:不包含pas)放在单独的文件或dll中,而不编译到程序里,运行时再载入或根据需要载入。我用bpl实现了,但bpl要把pas和dfm都包含进去,我只是想把dfm文件包含进去,我看delphi编译成exe的文件都可以原原本本地看到原dfm文件,所以想干脆把dfm直接拿出来放在单独的文件中,这样可以减小exe文件的体积。注:如果是硬叫我吧pas和dfm都放在dll里面或bpl里面再调用的人就不用回答了,因为这个我知道,参考资料也多,同时这个也比较麻烦我不考虑。
 
可以用动态桌面技术{*****************************************模块编号:J001DfmFunc模块名称:Dfm窗体函数集单元作者:刘爱军建立日期:2002年12月2日最后修改日期: 2010-11-14修改人:祁书锋说明:本Unit包含了一些函数,用于根据Delphi窗体文件格式的文件动态创建窗体*******************************************}unit J001DfmFunc;interfaceusesWindows, Messages, SysUtils, Variants, //自定义控件 //DBNavPlus,// Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls, Buttons, Menus, Mask, Grids, CheckLst, MPlayer, ExtDlgs, Gauges, ColorGrd, Spin, ActnList, OleCtnrs, AppEvnts, ValEdit, ActnMan, ActnMenus, ActnCtrls, ActnColorMaps, CustomizeDlg, dblookup, Tabs, Outline, TabNotBk, FileCtrl, DirOutln, Calendar, DBGrids, DBCtrls, dbcgrids ;typeTUnknown = class(TCustomControl) ;function ComponentToString(Component: TComponent): string;function StringToComponent(Value: string; Instance:TComponent): TComponent;function GetObjectString(list:TStrings;BegLine:Integer=0;TypeString:string=''):string;function LoadTextForm(FileName:String):TForm;function LoadTextForm2(FileName:String;out ErrMsg:string):TForm;procedure DeleteErrorLines(list:TStrings);procedure ReadForm(aFrom : TComponent;aFileName :string='');implementationfunction ComponentToString(Component: TComponent): string;var BinStream:TMemoryStream; StrStream: TStringStream; s: string;begin BinStream := TMemoryStream.Create; try StrStream := TStringStream.Create(s); try BinStream.WriteComponent(Component); BinStream.Seek(0, soFromBeginning); ObjectBinaryToText(BinStream, StrStream); StrStream.Seek(0, soFromBeginning); Result:= StrStream.DataString; finally StrStream.Free; end; finally BinStream.Free end;end;function StringToComponent(Value: string; Instance:TComponent): TComponent;var StrStream:TStringStream; BinStream: TMemoryStream;begin StrStream := TStringStream.Create(Value); try BinStream := TMemoryStream.Create; try ObjectTextToBinary(StrStream, BinStream); BinStream.Seek(0, soFromBeginning); Result := BinStream.ReadComponent(Instance); finally BinStream.Free; end; finally StrStream.Free; end;end;function GetObjectString(list:TStrings;BegLine:Integer=0;TypeString:string=''):string;var i,iBegCount,iEndCount:Integer; ObjString,Line,ClassStr:String;begin iBegCount:=0; iEndCount:=0; ClassStr := Trim(UpperCase(TypeString)); for i:=BegLine to list.Count-1 do begin line := UpperCase(list); if Pos('OBJECT',line)>0 then begin if (TypeString='') or (Pos(': '+ClassStr,line)>0) then Inc(iBegCount); end else if (iBegCount>iEndCount) and (trim(line)='END') then Inc(iEndCount); if iBegCount>0 then Result := Result + list + #13#10; if (iBegCount>0) and (iBegCount=iEndCount) then Exit; end;end;procedure DeleteErrorLines(list:TStrings);var i:Integer; line:String;begin if list.Count=0 then Exit; i:=0; while i<list.Count do begin line := Trim(list); if Copy(line,1,2)='On' then list.Delete(i) else Inc(i); end;end;procedure ReadForm(aFrom : TComponent;aFileName :string='');varFrmStrings : TStrings;begin RegisterClass(TPersistentClass(aFrom.ClassType)); FrmStrings:=TStringlist.Create ; try FrmStrings.LoadFromFile(aFileName); while aFrom.ComponentCount>0 do aFrom.Components[0].Destroy ; aFrom:=StringToComponent(FrmStrings.Text,aFrom) finally FrmStrings.Free; end; UnRegisterClass(TPersistentClass(aFrom.ClassType));end;function LoadTextForm(FileName:String):TForm;var list:TStrings; FirstLine:String; iPos : Integer; Form : TForm;begin Result := nil; if FileExists(FileName)=False then Exit; Form := TForm.Create(Application); list := TStringList.Create; try list.LoadFromFile(FileName); if list.Count=0 then Exit; FirstLine := list[0]; iPos := Pos(': ',FirstLine); if iPos = 0 then //找不到': ',格式不对 Exit; list[0]:=Copy(FirstLine,1,iPos)+' TForm'; DeleteErrorLines(list); StringToComponent(list.Text,Form); Result := Form; except Form.Free; Result := nil; end; list.Free;end;function LoadTextForm2(FileName:String;out ErrMsg:string):TForm;var list:TStrings; FirstLine:String; iPos : Integer; Form : TForm;begin Result := nil; if FileExists(FileName)=False then begin ErrMsg := '无效的文件名!'; Exit; end; Form := TForm.Create(Application); list := TStringList.Create; try list.LoadFromFile(FileName); if list.Count=0 then Exit; FirstLine := list[0]; iPos := Pos(': ',FirstLine); if iPos = 0 then //找不到': ',格式不对 begin ErrMsg := '找不到'': '',文件格式不对'; Exit; end; list[0]:=Copy(FirstLine,1,iPos)+' TForm'; DeleteErrorLines(list); StringToComponent(list.Text,Form); Result := Form; except on e:exception do begin Form.Free; Result := nil; ErrMsg := '读入文件错误:'+e.Message; end; end; list.Free;end;initializationbeginRegisterClasses([ TUnknown, TForm, TFont, // Standard TFrame, TMainMenu, TPopupMenu, TLabel, TEdit, TMemo, TButton, TCheckBox, TRadioButton, TListBox, TComboBox, TScrollBar, TGroupBox, TRadioGroup, TPanel, TActionList, // Sub-item TMenuItem, TAction, // System TTimer, TPaintBox, TMediaPlayer, TOleContainer, // Additional TBitBtn, TSpeedButton, TMaskEdit, TStringGrid, TDrawGrid, TImage, TShape, TBevel, TScrollBox, TCheckListBox, TSplitter, TStaticText, TControlBar, TApplicationEvents, TValueListEditor, TColorBox, TActionManager, TActionMainMenuBar, TActionToolBar, TXPColorMap, TStandardColorMap, TTwilightColorMap, TCustomizeDlg, // Win32 TTabControl, TPageControl, TImageList, TTrackBar, TProgressBar, TUpDown, THotKey, TAnimate, TDateTimePicker, TMonthCalendar, TTreeView, TListView, THeaderControl, TStatusBar, TToolBar, TCoolBar, TPageScroller, TComboBoxEx, // Sub-item TTabSheet, TToolButton, // Win 3.1 TDBLookupList, TDBLookupCombo, TTabSet, TOutline, TTabbedNotebook, TNotebook, THeader, TFileListBox, TDirectoryListBox, TDriveComboBox, TFilterComboBox, // Dialogs TOpenDialog, TSaveDialog, TOpenPictureDialog, TSavePictureDialog, TFontDialog, TColorDialog, TPrintDialog, TPrinterSetupDialog, TFindDialog, TReplaceDialog, TPageSetupDialog, // Samples TGauge, TColorGrid, TSpinButton, TSpinEdit, TDirectoryOutline, TCalendar, // Data Controls TDBGrid, TDBNavigator, TDBText, TDBEdit, TDBMemo, TDBImage, TDBListBox, TDBComboBox, TDBCheckBox, TDBRadioGroup, TDBLookupListBox, TDBLookupComboBox, TDBRichEdit, TDBCtrlGrid]);end;finalizationUnRegisterClasses([ TUnknown,TForm, TFont, // Standard TFrame, TMainMenu, TPopupMenu, TLabel, TEdit, TMemo, TButton, TCheckBox, TRadioButton, TListBox, TComboBox, TScrollBar, TGroupBox, TRadioGroup, TPanel, TActionList, // Sub-item TMenuItem, TAction, // System TTimer, TPaintBox, TMediaPlayer, TOleContainer, // Additional TBitBtn, TSpeedButton, TMaskEdit, TStringGrid, TDrawGrid, TImage, TShape, TBevel, TScrollBox, TCheckListBox, TSplitter, TStaticText, TControlBar, TApplicationEvents, TValueListEditor, TColorBox, TActionManager, TActionMainMenuBar, TActionToolBar, TXPColorMap, TStandardColorMap, TTwilightColorMap, TCustomizeDlg, // Win32 TTabControl, TPageControl, TImageList, TTrackBar, TProgressBar, TUpDown, THotKey, TAnimate, TDateTimePicker, TMonthCalendar, TTreeView, TListView, THeaderControl, TStatusBar, TToolBar, TCoolBar, TPageScroller, TComboBoxEx, // Sub-item TTabSheet, TToolButton, // Win 3.1 TDBLookupList, TDBLookupCombo, TTabSet, TOutline, TTabbedNotebook, TNotebook, THeader, TFileListBox, TDirectoryListBox, TDriveComboBox, TFilterComboBox, // Dialogs TOpenDialog, TSaveDialog, TOpenPictureDialog, TSavePictureDialog, TFontDialog, TColorDialog, TPrintDialog, TPrinterSetupDialog, TFindDialog, TReplaceDialog, TPageSetupDialog, // Samples TGauge, TColorGrid, TSpinButton, TSpinEdit, TDirectoryOutline, TCalendar, // Data Controls TDBGrid, TDBNavigator, TDBText, TDBEdit, TDBMemo, TDBImage, TDBListBox, TDBComboBox, TDBCheckBox, TDBRadioGroup, TDBLookupListBox, TDBLookupComboBox, TDBRichEdit, TDBCtrlGrid])end.
 
使用上面函数可以把界面设计与代码设计分开。可以存入文件也可以存入数据库使用方法:procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);var s:TStrings;begin s:=TStringlist.Create ; s.Add(J001DfmFunc.ComponentToString(self)); s.SaveToFile('./dfm/Unit2.dfm'); Self.Destroy;end;procedure TForm2.FormCreate(Sender: TObject);begintry J001DfmFunc.ReadForm(Self,'./dfm/Unit2.dfm' );exceptend;end;
 
你在EXE中看到的是DFM资源,你也可以把自己的东西放到里面去,只要编辑RC文件,再用drcc32.exe编译后再链接到EXE中即可。如果你要把DFM放到独立文件,那么应该需要对载入dfm的机制做一下手脚,同时把dfm不编译进EXE。
 
to:qisfeng, 像你这样做主窗体会没掉啊,而我是想让主窗体还保留着重新再创建个窗体,而且像这样每加个控件就要引用下单元,而且要加控件类很麻烦,有没有更简单的做法?
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
I
回复
0
查看
757
import
I
D
回复
0
查看
2K
DelphiTeacher的专栏
D
顶部