在RichEdit控件上放一个Image控件,用来显示图片
现在想保存整个页面信息写入文件中,包括Image控件的位置信息以及图片信息,
(也就是控件本身的信息和图片的信息都要写到一个文件中)
该如何做?
(我的方法总是报错,可能是定义的文件结构有问题)
请教大家,谢谢!
现在想保存整个页面信息写入文件中,包括Image控件的位置信息以及图片信息,
(也就是控件本身的信息和图片的信息都要写到一个文件中)
该如何做?
(我的方法总是报错,可能是定义的文件结构有问题)
请教大家,谢谢!
saving several controls to one single file?{-> Question:How can I store some TRichEdit components and TEdit Components in a single file?-> Answer:Use a filestream and a reader or writer object.These ease the tasks of writing strings to a binary stream and reading them back.}// Save routineprocedure SaveEditcontrols(const FileName: string; const Controls: array of TCustomEdit);varfs : TFilestream;writer : TWriter;i : Integer;ss : TStringstream;beginfs := TFilestream.Create(FileName, fmCreate);trywriter := TWriter.Create(fs, 4096);tryfor i := Low(Controls) to High(Controls) doif Controls[i] is TCustomRichedit thenbeginss := TStringstream.Create(EmptyStr);trywith TRichedit(Controls[i]) dobeginPlaintext := False;Lines.SaveToStream(ss);end;writer.WriteString(ss.Datastring);finallyss.Free;end;endelsewriter.WriteString(Controls[i].Text);finallywriter.Free;end;finallyfs.Free;end;end;// Load routine// Lade Routineprocedure LoadEditcontrols(const FileName: string; const Controls: array of TCustomEdit);varfs : TFilestream;reader : Treader;i : Integer;ss : TStringstream;beginfs := TFilestream.Create(FileName, fmOpenread or fmShareDenyWrite);tryreader := Treader.Create(fs, 4096);tryfor i := Low(Controls) to High(Controls) doif Controls[i] is TCustomRichedit thenbeginss := TStringstream.Create(reader.ReadString);trywith TRichedit(Controls[i]) dobeginPlaintext := False;Lines.LoadfromStream(ss);end;finallyss.Free;end;endelseControls[i].Text := reader.ReadString;finallyreader.Free;end;finallyfs.Free;end;end;// Example to store 2 TRichEdits and 3 Edit Controls to one file// Beispiel, um 3 TRichEdits und 3 TEdit Controls in einer Datei zu speichernprocedure TForm1.Button1Click(Sender: TObject);beginSaveEditControls('C:\temp\temp.dat',[richedit1, richedit2, edit1, edit2, edit3]);end;
Example:
//保存
procedure SaveComponent(Con: TWinControl; Path: string);var
BinStream:TMemoryStream;
begin
BinStream := TMemoryStream.Create;
try
BinStream.WriteComponent(Con);
BinStream.Seek(0, soFromBeginning);
BinStream.SaveToFile(Path);
finally
BinStream.Free
end;
end;
//写回
procedure ReadComponent(Path: string; Con: TWinControl);
var
BinStream: TMemoryStream;
lp: integer;
Com: TComponent;
begin
for lp := Con.ComponentCount - 1 downto 0 do
begin
Com := Con.Components[lp];
Con.RemoveComponent(Com);
Com.Free;
end;
BinStream := TMemoryStream.Create;
try
BinStream.LoadFromFile(Path);
BinStream.ReadComponent(Con);
finally
BinStream.Free;
end;
end;
//嘻嘻,简单吧!
//Power by 海天子
//保存
procedure SaveComponent(Con: TWinControl; Path: string);var
Stream:TStream;
begin
Stream := TFileStream.Create(Path, fmCreate);
try
Stream.WriteComponent(Con);
finally
Stream.Free
end;
end;
//写回
procedure ReadComponent(Path: string; Con: TWinControl);
var
Stream: TStream;
lp: integer;
Com: TComponent;
begin
for lp := Con.ComponentCount - 1 downto 0 do
begin
Com := Con.Components[lp];
Con.RemoveComponent(Com);
Com.Free;
end;
Stream := TFileStream.Create(Path, fmOpenRead);
try
Stream.ReadComponent(Con);
finally
Stream.Free;
end;
end;//嘻嘻,简单多了!
我想保存的是TImage控件和其上的图片,写入一个文件
我改写了上面的过程(我没有做过这方面,请指教!):
procedure TMainForm.Savecontrols(const FileName:string;const Controls:array of TImage);
var
fs:TFilestream;
writer:TWriter;
i:Integer;
begin
fs:=TFilestream.Create(FileName,fmCreate);
try
writer:=TWriter.Create(fs,4096);
try
for i:=0 to 99 do
with TImage(Controls[i]) do
begin
writer.WriteComponent(Controls[i]);//这里该怎么写?请教!
end;
finally
writer.Free;
end;
finally
fs.Free;
end;
end;
我想把TImage控件和图片(TPicture)分别保存为两个控件数组,然后写入一个文件,
这样可行吗?关键是打开文件时还应该能读出控件和图片,并在TImage上显示相应的图片
有高手回答出这个问题,我给他另立散分贴,请教啦!!!
万分感谢!!!
procedure TForm1.Button1Click(Sender: TObject);
var
S: TStream;
Map: TImage;
i: Integer;
begin
// 动态插入TImage元件到RichEdit,我插了3个,你可根据需要插入n个
for i := 1 to 3 do
begin
Map := TImage.Create(Self);
Map.Width := 100;
Map.Height := 100;
Map.Stretch := True;
Map.Name := 'Map' + IntToStr(i);
Map.Left := (i - 1) * 100 + 8;
Map.Top := 8;
Map.Picture.LoadFromFile('Test.bmp');
Map.Parent := RichEdit1;
end;
// 保存元件到文件
S := TFileStream.Create('test', fmCreate);
try
S.WriteComponent(RichEdit1);
for i := 0 to RichEdit1.ControlCount - 1 do
if RichEdit1.Controls[i] is TImage then
S.WriteComponent(TImage(RichEdit1.Controls[i]));
finally
S.Free;
end;
end;// 再次运行程序时操作
procedure TForm1.Button2Click(Sender: TObject);
var
S: TStream;
i: Integer;
Map: TImage;
begin
S := TFileStream.Create('test', fmOpenRead);
try
// 首先读出RichEdit
S.ReadComponent(RichEdit1);
// 读保存的Image
i := 1;
while True do// 因不知道确切的Image个数,所以采用无限循环
try
Map := TImage.Create(Self);
Map.Name := 'Map' + IntToStr(i);
S.ReadComponent(Map);
Map.Parent := RichEdit1;
Inc(i);
except //保存的Image读完,退出循环,调试时会显示错误,真正运行时不会显示错误
Map.Free;
Break;
end;
finally
S.Free;
end;
end;end.
maozefa(之源) 兄,佩服!
为了配合一叶知秋的程序,所以此例用了Panel做为Image的载体,一起存取。
因为还要把位置存取下来,所以我用了一个信息文件(.info)来存文件所包括的所有图片的宽、高、左、顶的信息。可对打开文件的所有图片再次进行缩放再次存取。调试通过^^
在此,再次感谢maozefa(之源)的引导^^
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, JvGIF, ExtDlgs, StdCtrls, ComCtrls, ExtCtrls;type
TForm1 = class(TForm)
RichEditNew: TRichEdit;
BtnOpen: TButton;
BtnSave: TButton;
OpenPictureDialog1: TOpenPictureDialog;
BtnAddPic: TButton;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
procedure BtnAddPicClick(Sender: TObject);
procedure BtnOpenClick(Sender: TObject);
procedure BtnSaveClick(Sender: TObject);
private
procedure FMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}
procedure ManipulateControl(WinControl: TControl; Shift: TShiftState;
X, Y, Precision: integer);
//Precision:精度,该方法可以在onmousemove中调用
var
SC_MANIPULATE: Word;
begin
//光标在控件的最左侧
if (X<=Precision) and (Y>Precision) and (Y<WinControl.Height-Precision) then
begin
SC_MANIPULATE := $F001;
WinControl.Cursor := crSizeWE; end
else
//光标在控件的最右侧
if (X>=WinControl.Width-Precision) and (Y>Precision) and (Y<WinControl.Height-Precision) then
begin
SC_MANIPULATE := $F002;
WinControl.Cursor := crSizeWE;
end
else
//光标在控件的最上侧
if (X>Precision) and (X<WinControl.Width-Precision) and (Y<=Precision) then
begin
SC_MANIPULATE := $F003;
WinControl.Cursor := crSizeNS;
end
else
//光标在控件的最下侧
if (X>Precision) and (X<WinControl.Width-Precision) and (Y>=WinControl.Height-Precision) then
begin
SC_MANIPULATE := $F006;
WinControl.Cursor := crSizeNS;
end
else
//光标在控件的左上角
if (X<=Precision) and (Y<=Precision) then
begin
SC_MANIPULATE := $F004;
WinControl.Cursor := crSizeNWSE;
end
else
//光标在控件的右上角
if (X>=WinControl.Width-Precision) and (Y<=Precision) then
begin
SC_MANIPULATE := $F005;
WinControl.Cursor := crSizeNESW ;
end
else
//光标在控件的左下角
if (X<=Precision) and (Y>=WinControl.Height-Precision) then
begin
SC_MANIPULATE := $F007;
WinControl.Cursor := crSizeNESW;
end
else
//光标在控件的右下角
if (X>=WinControl.Width-Precision) and (Y>=WinControl.Height-Precision) then
begin
SC_MANIPULATE := $F008;
WinControl.Cursor := crSizeNWSE;
end
else
//光标在控件的客户区(移动整个控件)
if (X>5) and (Y>5) and (X<WinControl.Width-5) and
(Y<WinControl.Height-5) then
begin
SC_MANIPULATE := $F009;
WinControl.Cursor := crSizeAll;
end
else
begin
SC_MANIPULATE := $F000;
WinControl.Cursor := crDefault;
end;
if Shift=[ssLeft] then
begin
ReleaseCapture;
WinControl.Perform(WM_SYSCOMMAND, SC_MANIPULATE, 0);
end;
end;function StrLeft(const mStr: string; mDelimiter: string): string;
{ 返回左分隔字符串 }
begin
Result := Copy(mStr, 1, Pos(mDelimiter, mStr) - 1);
end;function ListValue(mList: string; mIndex: Integer; mDelimiter: string = ','): string;
{ 返回列表指定位置的元素 }
var
I, L, K: Integer;
begin
if Pchar(mList)[Length(mList)-1] <> mDelimiter then
mList:=mList + mDelimiter;
L := Length(mList);
I := Pos(mDelimiter, mList);
K := 0;
Result := '';
while (I > 0) and (K <> mIndex) do begin
mList := Copy(mList, I + Length(mDelimiter), L);
I := Pos(mDelimiter, mList);
Inc(K);
end;
if K = mIndex then
Result := StrLeft(mList + mDelimiter, mDelimiter);
end;
有方法就行了
主要是利用FILESTREAM的WRITECOMPONENT和READCOMPONENT,然后把image想对象的属性寸起来就行了和读出来,
比如picture 和他的位置属性
这是刚才那个贴的下半部分^^//建立Image的OnMouseMove调用过程
procedure TForm1.FMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
Caption := IntToStr(X) + '/' + IntToStr(Y);
ManipulateControl((TControl(Sender).Parent as TwinControl), Shift, X, Y, 10);
end;//加图片
procedure TForm1.BtnAddPicClick(Sender: TObject);
var
AJpg: TImage;
APanel: TPanel;
begin
if Form1.OpenPictureDialog1.Execute then
begin
APanel := TPanel.Create(Self);
APanel.Align := alnone;
APanel.BevelOuter := bvNone;
APanel.Width := Trunc(100);
APanel.Height := Trunc(100);
APanel.Parent := Form1.RichEditNew; AJpg := TImage.Create(Self);
AJpg.OnMouseMove := FMouseMove;
AJpg.Parent := APanel;
AJpg.Stretch := True;
AJpg.Align := alclient;
AJpg.Picture.LoadFromFile(Form1.OpenPictureDialog1.FileName);
end;
end;//打开文件
procedure TForm1.BtnOpenClick(Sender: TObject);
var
S: TStream;
i: Integer;
Map: TImage;
Panel: TPanel;
tmpStrList: TStrings;
tmpStr, tmpLeft, tmpTop, tmpWidth, tmpHeight, tmpFileName: String;
begin
for i := 0 to RichEditNew.ControlCount - 1 do
begin
RichEditNew.Controls[0].Free;
end; if OpenDialog1.Execute then
begin
tmpFileName := OpenDialog1.FileName; tmpStrList := TStringList.Create;
S := TFileStream.Create(tmpFileName, fmOpenRead);
S.ReadComponent(RichEditNew);
tmpStrList.LoadFromFile(ExtractFilePath(tmpFileName) + ExtractFileName(tmpFileName)+'.info');
for i := 0 to tmpStrList.Count - 1 do
try
tmpStr := tmpStrList.Strings[i];
tmpLeft := ListValue(tmpStr, 2);
tmpTop := ListValue(tmpStr, 3);
tmpWidth := ListValue(tmpStr, 4);
tmpHeight := ListValue(tmpStr, 5); Panel := TPanel.Create(Self);
Panel.Parent := RichEditNew;
Panel.Name := 'myPanel' + IntToStr(i+1);
Map := TImage.Create(Self);
Map.Parent := Panel;
Map.Name := 'myMap' + IntToStr(i+1);
S.ReadComponent(Panel);
S.ReadComponent(Map);
Panel.Parent := RichEditNew;
Panel.Left := StrToInt(tmpLeft);
Panel.Top := StrToInt(tmpTop);
Panel.Width := StrToInt(tmpWidth);
Panel.Height := StrToInt(tmpHeight);
Map.OnMouseMove := FMouseMove; Map.Parent := Panel;
except
Map.Free;
Panel.Free;
end;
S.Free;
end;
end;//保存文件
procedure TForm1.BtnSaveClick(Sender: TObject);
var
S: TStream;
i: Integer;
tmpStrList: TStrings;
tmpFileName: String;
begin
if SaveDialog1.Execute then
begin
tmpFileName := SaveDialog1.FileName;
// 保存元件到文件
tmpStrList := TStringList.Create;
S := TFileStream.Create(tmpFileName, fmCreate);
try
S.WriteComponent(RichEditNew);
for i := 0 to RichEditNew.ControlCount - 1 do
begin
if RichEditNew.Controls[i] is TPanel then
begin
S.WriteComponent(TPanel(RichEditNew.Controls[i]));
if TPanel(RichEditNew.Controls[i]).Controls[0] is TImage then
begin
S.WriteComponent(TImage(TPanel(RichEditNew.Controls[i]).Controls[0]));
tmpStrList.Add('myPanel'+IntToStr(i + 1)+','+'myImage'+IntToStr(i + 1)+','
+IntToStr(TPanel(RichEditNew.Controls[i]).Left)+','
+IntToStr(TPanel(RichEditNew.Controls[i]).Top)+','
+IntToStr(TPanel(RichEditNew.Controls[i]).Width)+','
+IntToStr(TPanel(RichEditNew.Controls[i]).Height));
end;
end;
end;
tmpStrList.SaveToFile(ExtractFilePath(tmpFileName) + ExtractFileName(tmpFileName)+'.info');
finally
S.Free;
tmpStrList.Free;
end;
end;
end;end.