倾家荡产,寻(如何把一个控件的信息写入到自定义的文件中,窗体显示时又能读取出来)! ( 积分: 100 )

  • 主题发起人 主题发起人 szdnc
  • 开始时间 开始时间
S

szdnc

Unregistered / Unconfirmed
GUEST, unregistred user!
例如:
Form1: TForm1
Left = 239
Top = 430
Width = 696
Height = 480
Caption = 'Form1'
OnCreate = FormCreate
Edit1: TEdit
Left = 232
Top = 72
Width = 121
Height = 21
Text = 'Edit1'
如何把这些信息写入到自定义的文件中,当窗体显示时,又能从这个文件中读取出来,并显示出这些控件和窗体!还有事件,如何处理,最好附上源码,非常感谢,我想了2个多星期了,快疯了!
 
这就是所渭的持久化
参考下Delphi的TPersistant类和TReader,TWriter就知道原理了
 
这个问题在网上有答案,用Google,不用10分你就得到你要想要的代码了!
http://www.google.com/search?q=Delphi%B5%C4%A1%A1%B6%AF%CC%AC%B4%B0%CC%E5&hl=zh-CN&lr=lang_zh-CN&ie=gb2312
 
.savecomponent
 
其实Delphi都帮你做好了,只要调用就可以了。
参考WriteComponentResFile和ReadComponentResFile;
 
网上有已写好的,DFW上以前有人放过
 
(*
功能:读取 Delphi 窗体文件,并显示设计时原样。
对于第三方控件,怎么替换为一个可显示的控件,显示位置,提示类名
* 2006-10-11 by liqj
*)
unit u_ReadDfmMainForm;
interface
uses
SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls, StrUtils, Buttons,
ExtCtrls, ComCtrls, Graphics;

type
TfrmReadDfmMain = class(TForm)
btnLoad: TButton;
memPositionList: TMemo;
memNameList: TMemo;
dlgOpen: TOpenDialog;
memSource: TMemo;
btnConv: TButton;
btnExec: TButton;
btnExec_Source: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
chkAddHintInNoRegClass: TCheckBox;
chkAddHintInRegClass: TCheckBox;
procedure btnLoadClick(Sender: TObject);
procedure btnConvClick(Sender: TObject);
procedure btnExecClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
end;

// 未能注册的类替换为此类
TUnknown = class(TCustomControl)
public
procedure Paint;override;
published
property TabOrder;
property Align;
property Caption;
property Color;
property Popupmenu;
property ClientWidth;
property ClientHeight;
property Font;
property ShowHint;
end;

var
frmReadDfmMain: TfrmReadDfmMain;

implementation
uses
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, ShellCtrls, Chart, DBChart,
SHDocVw;

{$R *.dfm}

procedure TUnknown.Paint;
begin
inherited;
Canvas.Rectangle(0, 0, Width, Height); // 长方形
//Canvas.Font.Color := clRed;
Canvas.TextOut(2,2,Name);
end;

procedure TfrmReadDfmMain.btnLoadClick(Sender: TObject);
var
inStream,outStream :TMemoryStream;
iChar :Char;
sFileName :string;
begin
if dlgOpen.Execute then
sFileName := dlgOpen.FileName
else
Exit;

inStream := TMemoryStream.Create;
try
inStream.LoadFromFile(sFileName);
inStream.Position := 0;
inStream.Read(iChar,SizeOf(iChar));
inStream.Position := 0;
// 检查 dfm 文件格式:第一字节是 ['o','O','i','I',' ',#13,#11,#9] 则判定为文本格式
// 二进制格式一般为 255
// GExpert 的判断方法:(前三个字节为下面几个值表示是2进制)
// TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
// if (Buf[0] = $FF) and (Buf[1] = $0A) and (Buf[2] = $00) then
// 使用 Classes.TestStreamFormat(Stream) 函数判断也行 p9193
if not (iChar in ['o','O','i','I',' ',#13,#11,#9]) then
begin
outStream := TMemoryStream.Create;
try
ObjectResourceToText(inStream, outStream); // 二进制资源转成文本格式
outStream.Position := 0;
memSource.Lines.LoadFromStream(outStream);
finally
outStream.Free;
end;
end
else
memSource.Lines.LoadFromStream(inStream);
finally
inStream.Free;
end;
end;

procedure TfrmReadDfmMain.btnConvClick(Sender: TObject);
const
// 未注册组件过滤列表 -- 仅仅. 要全小写则比较时这个不用再转化
PropertyList : array [0..20] of string =
('top','left','width','height','taborder','align','caption','color',
'popupmenu','clientwidth','clientheight','cursor','hint','showhint',
'font.charset','font.color','font.height','font.name','font.style',
'menu','action');

// 已注册组件排除属性列表
NoPropertyList :array [0..1] of string =
('datasource','formstyle');
var
iIndex,iLen,iLineCount :integer;
sLine :string;

function FindCharIndex(piChar :Char):boolean;
begin
while (iIndex<=iLen) and (sLine[iIndex] <> piChar) do
Inc(iIndex);
Result := (iIndex<=iLen) and (sLine[iIndex] = piChar);
end;
function GetLevel :integer;
begin
Result := 0;
while (iIndex<=iLen) and (sLine[iIndex] = #32) do
begin
Inc(iIndex);
Inc(Result);
end;
if Result >0 then Result := Result div 2; // 2个空格为一个层次
end;
function InPropertyList(const psValue :string):boolean;
var
iLoop :integer;
begin
Result := False;
if psValue = '' then Exit;
for iLoop :=Low(PropertyList) to High(PropertyList) do
if PropertyList[iLoop] = psValue then break;
//ToDo: CompareText(S1,S2) =0 与直接比较那个快呢?,直接比较还有一边转成小写的操作
Result := iLoop <= High(PropertyList);
end;
function InNoPropertyList(const psValue :string):boolean;
var
iLoop :integer;
begin
Result := False;
if psValue = '' then Exit;
for iLoop :=Low(NoPropertyList) to High(NoPropertyList) do
if NoPropertyList[iLoop] = psValue then break;
Result := iLoop <= High(NoPropertyList);
end;

function FindStrOfLineCount(const psValue :string;var piIndex:integer):integer;
begin
Result := piIndex;
while (piIndex < iLineCount) and
(LowerCase(Trim(memSource.Lines[piIndex])) <> psValue) do
Inc(piIndex);
Result := piIndex - Result;
end; // Local

function GetPropertyName(const psValue :string):string;
var
iPos :integer;
begin
iPos := Pos('=',psValue);
if iPos >0 then
Result := Trim(Copy(psValue,1,iPos-1))
else
Result := '';
end;
var
iLoop, iOldIndex, iLevel :integer;
sFix_6, sValue, sName,sClassName, sProperty, sPropertyValue:string;
bIsForm{,bHasHint} : boolean;
CurClass :TPersistentClass;
begin // Main

memNameList.Lines.Clear; // 名称/类名 列表
memPositionList.Lines.Clear; // 位置信息
memNameList.Lines.Add('层: 名称 [类名](*表示不能识别)');

memNameList.Lines.BeginUpdate;
memPositionList.Lines.BeginUpdate;
try

// 外循环,开始添加*对象
iLoop := 0; // 当前行数
iLineCount := memSource.Lines.Count;
while iLoop < iLineCount do
begin
sLine := TrimRight(memSource.Lines[iLoop]); // 后缀不能有空格
iLen := Length(sLine);
iIndex := 1;
iLevel := GetLevel ; // 去前缀空格

sFix_6 := LowerCase(Copy(sLine,iIndex,6));
if (sFix_6 ='object') or (sFix_6 ='inline') or
(LowerCase(Copy(sLine,iIndex,9))= 'inherited')then
begin
//memPositionList.Lines.Add(memSource.Lines[iLoop]); // 对象定义,输出

if (sLine[iIndex+3] = 'h') or (sLine[iIndex+3] = 'H') then
iOldIndex := iIndex + 10
else
iOldIndex := iIndex + 7;

if FindCharIndex(':') then
begin
sName := Trim(Copy(sLine,iOldIndex,iIndex - iOldIndex));
sClassName := Trim(Copy(sLine,iIndex +1,iLen - iIndex))
end
else
begin
sName := 'Unknown_Name' + intToStr(iLoop);
sClassName := Trim(Copy(sLine,iIndex +1,iLen - iIndex));
end;

CurClass :=GetClass(sClassName);
if (CurClass<>nil) or (iLoop =0) then // 有注册的类或第一行(一般是 Form、DataModal)
begin
// 显示层次关系
memNameList.Lines.Add(Format('%2d: %s [%s]',[iLevel,sName,sClassName]));
bIsForm := (iLoop =0);// or (sClassName='TForm');

memPositionList.Lines.Add(memSource.Lines[iLoop]); // **对象定义,输出
if (iLoop=0) and // 强制提示
(chkAddHintInNoRegClass.Checked or chkAddHintInRegClass.Checked) then
memPositionList.Lines.Add(' ShowHint = True');
// else
// memPositionList.Lines.Add(StringOfChar(' ',iLevel*2)+ ' Hint = '''+ sName+'''#13#10'''+ sClassName + '''');
Inc(iLoop);
sFix_6 := LowerCase(Copy(Trim(memSource.Lines[iLoop]),1,6)); // 当是对象时 = object

// 仅从 TControl、TMenuItem 继承才有 Hint 属性 或第一个类 Form/DM
if chkAddHintInRegClass.Checked and
(
(CurClass = nil)
or
((CurClass<>nil) and
(CurClass.InheritsFrom(TControl)))
)
then // or CurClass.InheritsFrom(TMenuItem)) then
memPositionList.Lines.Add(StringOfChar(' ',iLevel*2)+
' Hint = ''Name='+ sName+'''#13#10''ClassName='+ sClassName + '''');

// 添加所属对象:仅注册类
while (iLoop < iLineCount) and
Not ((sFix_6 ='object') or (sFix_6 ='inline') or
(LowerCase(Copy(Trim(memSource.Lines[iLoop]),1,9))= 'inherited')) do
begin
// 未到结束,不是下一个对象定义,循环加已知组件的所有属性,事件不加
if Copy(sFix_6,1,2) <> 'on' then // 非事件,继续!!!
begin
sProperty := LowerCase(GetPropertyName(Trim(memSource.Lines[iLoop])));// 属性名称
if not InNoPropertyList(sProperty) then // 排除列表外,继续!
begin
if not bIsForm then
memPositionList.Lines.Add(memSource.Lines[iLoop]) // 非Form,加!!!
else if sProperty <> 'visible' then
memPositionList.Lines.Add(memSource.Lines[iLoop]); // Form不能放 visible.
end;
end;
Inc(iLoop);
sFix_6 := LowerCase(Copy(Trim(memSource.Lines[iLoop]),1,6));
end;
Continue;
end
else
begin
// 未注册的类,使用 TUnknown 类替换类名

// 显示层次关系 多一个*号表示不能识别
memNameList.Lines.Add(Format('%2d: %s [%s]*',[iLevel,sName,sClassName]));

if (sLine[iIndex+3] = 'h') or (sLine[iIndex+3] = 'H') then //
sValue := 'inherited ' + sName
else
sValue := sFix_6 +' '+ sName; // = object Name

// 组合未注册的类的源码对象定义
sValue := Format('%s%s : %s',[StringOfChar(' ',iLevel*2),sValue,'TUnknown']);

memPositionList.Lines.Add(sValue); // 对象定义!

if chkAddHintInNoRegClass.Checked then // 加入提示!
memPositionList.Lines.Add(StringOfChar(' ',iLevel*2)+
' Hint = ''Name='+ sName+'''#13#10''ClassName='+ sClassName + '*''');
end;


// 内循环,添加所属对象:仅未注册类、预定义部份
Inc(iLoop);
while (sLine <> 'end') and (iLoop < iLineCount) do
begin
sLine := memSource.Lines[iLoop];
iLevel := GetLevel;
sLine := LowerCase(Trim(sLine)); // 两边不要空格,并转为小写
iLen := Length(sLine);
iIndex := 1;
if sLine = 'end' then // 对象定义结束,输出
begin
memPositionList.Lines.Add(memSource.Lines[iLoop]);
Inc(iLoop);
while LowerCase(Trim(memSource.Lines[iLoop])) ='end' do // 加完所有一行是 end 的行
begin // 因为有嵌套部份!!!
memPositionList.Lines.Add(memSource.Lines[iLoop]);
Inc(iLoop);
end;
Continue;
end;

sFix_6 := LowerCase(Copy(sLine,iIndex,6));
// 包含对象,需要重新执行外循环
if (sFix_6 ='object') or (sFix_6 ='inline') or
(LowerCase(Copy(sLine,iIndex,9))= 'inherited')then
break;
if FindCharIndex('=') then // 是否有 属性 = 值 对!
begin
sProperty := Trim(Copy(sLine,1,iIndex -1));
if InPropertyList(sProperty) then // 属性名称为预定义,输出
memPositionList.Lines.Add(memSource.Lines[iLoop]);
sPropertyValue := Trim(Copy(sLine,iIndex +1,iLen - iIndex));
if sPropertyValue='<' then // 集合属性,跳过直到 end>行 例:<#13#10Item1#13#10Item#13#10end>
begin
FindStrOfLineCount('end>',iLoop);
end;
end;
Inc(iLoop);
end;
Continue;
end;
if sLine = 'end' then // 对象定义结束,输出
memPositionList.Lines.Add(memSource.Lines[iLoop]);
Inc(iLoop);
end;

finally
memPositionList.Lines.EndUpdate;
memNameList.Lines.EndUpdate;
end;
end;

procedure TfrmReadDfmMain.btnExecClick(Sender: TObject);
var
frmExec : TForm;
inStream, outStream :TMemoryStream;
begin
if Trim(memPositionList.Lines.Text)= '' then Exit;

frmExec := TForm.Create(nil);
try
inStream := TMemoryStream.Create;
outStream := TMemoryStream.Create;
try
if Sender = btnExec_Source then
memSource.Lines.SaveToStream(inStream)
else
memPositionList.Lines.SaveToStream(inStream);
inStream.Position := 0;
ObjectTextToResource(inStream,outStream); // 窗体定义 -> 资源
outStream.Position := 0;
OutStream.ReadComponentRes(frmExec); // 资源 -> 显示的窗体
finally
inStream.Free;
outStream.Free;
end;

frmExec.ShowModal;
finally
frmExec.Free;
end;
end;

procedure TfrmReadDfmMain.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Action := caFree;
frmReadDfmMain := nil;
end;


initialization

// 注册自带类
RegisterClasses([
TUnknown, TForm, TFont, //TControl,
// Standard
TFrame, TMainMenu, TPopupMenu, TLabel, TEdit, TMemo, TButton,
TCheckBox, TRadioButton, TListBox, TComboBox, TScrollBar, TGroupBox,
TRadioGroup, TPanel, TActionList,
// Standard: Sub-item
TMenuItem, TAction,
// Additional
TBitBtn, TSpeedButton, TMaskEdit, TStringGrid, TDrawGrid, TImage,
TShape, TBevel, TScrollBox, TCheckListBox, TSplitter, TStaticText, TControlBar,
{TApplicationEvents,} TValueListEditor, TLabeledEdit, TColorBox, TChart,
TActionManager, TActionMainMenuBar,TActionToolBar, TXPColorMap, TStandardColorMap,
TTwilightColorMap, TCustomizeDlg,
// Win32
TTabControl, TPageControl, TImageList, TRichEdit, TTrackBar, TProgressBar, TUpDown, THotKey,
TAnimate, TDateTimePicker, TMonthCalendar, TTreeView, TListView, THeaderControl,
TStatusBar, TToolBar, TCoolBar, TPageScroller, TComboBoxEx,
// Win32: Sub-item
TTabSheet, TToolButton,
// System
{TTimer,} TPaintBox, TMediaPlayer,TOleContainer,
// Dialogs
{TOpenDialog, TSaveDialog, TOpenPictureDialog, TSavePictureDialog, TFontDialog,
TColorDialog, TPrintDialog, TPrinterSetupDialog, TFindDialog, TReplaceDialog,
TPageSetupDialog,}
// Win 3.1
TDBLookupList, TDBLookupCombo, TTabSet, TOutline, TTabbedNotebook, TNotebook,
THeader, TFileListBox, TDirectoryListBox, TDriveComboBox, TFilterComboBox,
// Samples
TGauge, TColorGrid, TSpinButton, TSpinEdit, TDirectoryOutline, TCalendar,
TShellTreeView, TShellComboBox, TShellListView, TScroller,
// Data Controls
TDBGrid, TDBNavigator, TDBText, TDBEdit, TDBMemo, TDBImage, TDBListBox,
TDBComboBox, TDBCheckBox, TDBRadioGroup, TDBLookupListBox, TDBLookupComboBox,
TDBRichEdit, TDBCtrlGrid, TDBChart,
// Other
// Internet
TWebBrowser
]);


end.

// 窗体
object frmReadDfmMain: TfrmReadDfmMain
Left = 94
Top = 43
Width = 889
Height = 606
Caption = 'frmMain'
Color = clBtnFace
Font.Charset = GB2312_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = #23435#20307
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
OnClose = FormClose
PixelsPerInch = 96
TextHeight = 12
object Label1: TLabel
Left = 80
Top = 32
Width = 90
Height = 12
Caption = 'dfm'#28304#25991#20214#20195#30721#65306
end
object Label2: TLabel
Left = 296
Top = 32
Width = 84
Height = 12
Caption = #32452#20214#21517#31216#21015#34920#65306
end
object Label3: TLabel
Left = 648
Top = 21
Width = 84
Height = 12
Caption = #36716#25442#32467#26524#20195#30721#65306
end
object memPositionList: TMemo
Left = 520
Top = 40
Width = 353
Height = 521
Align = alCustom
ScrollBars = ssBoth
TabOrder = 1
end
object memNameList: TMemo
Left = 296
Top = 48
Width = 217
Height = 513
Align = alCustom
Lines.Strings = (
'memNameList')
ScrollBars = ssBoth
TabOrder = 2
end
object btnLoad: TButton
Left = 8
Top = 3
Width = 89
Height = 25
Caption = #25171#24320'dfm'#25991#20214
TabOrder = 0
OnClick = btnLoadClick
end
object memSource: TMemo
Left = 0
Top = 48
Width = 281
Height = 513
Hint = '|'#25105#13#10#20182
Lines.Strings = (
'memSource')
ScrollBars = ssBoth
TabOrder = 3
end
object btnConv: TButton
Left = 111
Top = 3
Width = 75
Height = 25
Caption = #36716#25442
TabOrder = 4
OnClick = btnConvClick
end
object btnExec: TButton
Left = 200
Top = 2
Width = 75
Height = 25
Caption = #25191#34892#32467#26524
TabOrder = 5
OnClick = btnExecClick
end
object btnExec_Source: TButton
Left = 288
Top = 2
Width = 113
Height = 25
Caption = 'btnExec_Source'
TabOrder = 6
Visible = False
OnClick = btnExecClick
end
object chkAddHintInNoRegClass: TCheckBox
Left = 416
Top = 8
Width = 153
Height = 17
Caption = #21152#25552#31034'('#20165#26410#33021#35782#21035#30340#31867')'
TabOrder = 7
end
object chkAddHintInRegClass: TCheckBox
Left = 416
Top = 24
Width = 153
Height = 17
Caption = #21152#25552#31034'('#20165#33021#35782#21035#30340#31867')'
TabOrder = 8
end
object dlgOpen: TOpenDialog
DefaultExt = '*.dfm'
Filter = 'Delphi Form(*.dfm)|*.dfm'
Left = 32
Top = 56
end
end
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
763
SUNSTONE的Delphi笔记
S
后退
顶部