覆盖TPersistent的assign方法疑问 |
尚未結案
|
zzmbeyond01
中階會員 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
大大好:
我希望创建一个对象变量的副本(拷贝),请问如何实现?
查阅《Inside VCL。。》中解释利用覆盖覆盖TPersistent的assign方法,实现对象的拷贝工作。 为什么如下代码不能成功?并且报错:"can't assign a Tmymap to a tbutton."
第二是如何赋值TMap(一个axtivex控件)中的属性信息,因为其private区域全是接口或者事件类型。
type TForm1 = class(TForm) Map1: TMap; Panel1:TPanel; Button1: TButton; procedure Button1Click(Sender: TObject); end; TMyMap = class(TMap) public ZLH: string; constructor create(ZLH03:string); procedure assign(Source:TPersistent); overload; override; end; var Form1: TForm1; implementation { ************************************ TMyMap ************************************ } constructor TMyMap.create(ZLH03:string); begin zlh:=zlh03; end; procedure TMyMap.assign(Source:TPersistent); var aMyMap: TMyMap; begin //复制构造函数创建Map1的副本 aMyMap:=TMyMap(Source); self.ZLH:=aMyMap.ZLH; //inherited assign(source); end; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var aaMyMap,bMyMap:TMyMap; begin aaMyMap:=TMyMap.create('1234'); bMyMap.assign(aaMyMap); end;谢谢! |
speedup
資深會員 發表:19 回覆:259 積分:280 註冊:2003-07-04 發送簡訊給我 |
引言: 大大好: 我希望创建一个对象变量的副本(拷贝),请问如何实现? 查阅《Inside VCL。。》中解释利用覆盖覆盖TPersistent的assign方法,实现对象的拷贝工作。 为什么如下代码不能成功?并且报错:"can't assign a Tmymap to a tbutton." 第二是如何赋值TMap(一个axtivex控件)中的属性信息,因为其private区域全是接口或者事件类型。混心雜欲 棄修身~唉type TForm1 = class(TForm) Map1: TMap; Panel1:TPanel; Button1: TButton; procedure Button1Click(Sender: TObject); end; TMyMap = class(TMap) public ZLH: string; constructor create(ZLH03:string); procedure assign(Source:TPersistent); overload; override; end; var Form1: TForm1; implementation { ************************************ TMyMap ************************************ } constructor TMyMap.create(ZLH03:string); begin zlh:=zlh03; end; procedure TMyMap.assign(Source:TPersistent); var aMyMap: TMyMap; begin //复制构造函数创建Map1的副本 aMyMap:=TMyMap(Source); self.ZLH:=aMyMap.ZLH; //請保留 inherited assign(source); end; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var aaMyMap,bMyMap:TMyMap; begin aaMyMap:=TMyMap.create('1234'); //Delphi 中Object必須先建構才能使用 bMyMap := TMyMap.Create; bMyMap.assign(aaMyMap); end;谢谢!
------
唉~ |
zzmbeyond01
中階會員 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
|
hagar
版主 發表:143 回覆:4056 積分:4445 註冊:2002-04-14 發送簡訊給我 |
參考這篇看看:
http://groups.google.com.tw/groups?hl=zh-TW&lr=&ie=UTF-8&selm=3bb64b36_2%40dnews&rnum=7
function CopyComponent(Source : TComponent) : TComponent; var PropStream : TMemoryStream; OldText, OldName : String; begin Result := Nil; if assigned(Source) then begin PropStream := TMemoryStream.Create; try //Save the "stored" properties to memory PropStream.WriteComponent(Source); //e.g. TEdit will change it's content if renamed if IsPublishedProp(Source,'Text') then OldText := GetStrProp(Source,'Text') else //Some Captions may face the same problem if IsPublishedProp(Source,'Caption') then OldText := GetStrProp(Source,'Caption'); OldName := Source.Name; //prevent doubled component names Source.Name := ''; Result := TComponentClass(Source.ClassType).Create(Source.Owner); PropStream.Position := 0; PropStream.ReadComponent(Result); Result.Name := ''; Source.Name := OldName; //Handle Components with a "Text" or "Captrion" -property; //e.g. TEdit, TLabel if IsPublishedProp(Source,'Text') then begin SetStrProp(Source,'Text',OldText); SetStrProp(Result,'Text',OldText); end else if IsPublishedProp(Source,'Caption') then begin SetStrProp(Source,'Caption',OldText); SetStrProp(Result,'Caption',OldText); end; //restore the parent (not included in the component-stream) //to make the copy visible (coordinates should be manipulated) if Result is TControl then TControl(Result).Parent := TControl(Source).Parent; finally PropStream.Free; end; end; end; function CopyCompleteComponent(Source : TComponent) : TComponent; var i, PropCount : Integer; PropList : TPropList; begin Result := Nil; if assigned(Source) then begin Result := CopyComponent(Source); PropCount := GetPropList(Source.ClassInfo,tkAny, @PropList); i := 0; while i < PropCount do begin if CompareStr(PropList[i].Name,'Name') <> 0 then case PropList[i].PropType^.Kind of tkLString, tkWString, tkVariant: SetPropValue(Result,PropList[i].Name, GetPropValue(Source,PropList[i].Name)); tkInteger, tkChar, tkWChar : SetOrdProp(Result,PropList[i].Name, GetOrdProp(Source,PropList[i].Name)); tkFloat: SetFloatProp(Result,PropList[i].Name, GetFloatProp(Source,PropList[i].Name)); tkString: SetStrProp(Result,PropList[i].Name, GetStrProp(Source,PropList[i].Name)); tkMethod : //to prevent event-handlers from beeing copied,comment this out SetMethodProp(Result,PropList[i].Name, GetMethodProp(Source,PropList[i].Name)); tkInt64: SetInt64Prop(Result,PropList[i].Name, GetInt64Prop(Source,PropList[i].Name)); tkEnumeration : SetEnumProp(Result,PropList[i].Name, GetEnumProp(Source,PropList[i].Name)); tkSet : SetSetProp(Result,PropList[i].Name, GetSetProp(Source,PropList[i].Name)); end; { tkClass is a special problem. Font, Contraints, PopumpMenu a.s.o. are handled via the streaming subsystem (CopyComponent) } inc(i); end; end; end; |
speedup
資深會員 發表:19 回覆:259 積分:280 註冊:2003-07-04 發送簡訊給我 |
引言: 请问如何实现将 TMap(一个axtivex控件)中的属性信息,拷贝呢?因为其private区域全是接口或者事件类型。你是要將一個ActiveX控件的屬性複製至另外一個嗎 如果該ActiveX控件支援Dual interface應該是可以撰寫一個萬用的Copy屬性程序來做這件事,先透過IDispatch介面的GetTypeInfo方法取得ActiveX控件全部的屬性,再透過IDispatch介面的GetIDsOfNames/Invoke方法讀出屬性與寫入屬性 不過這3個方法(GetTypeInfo/GetIDsOfNames/Invoke)都很難用... 混心雜欲 棄修身~唉
------
唉~ |
zzmbeyond01
中階會員 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
触发:"Privileged instruction"是怎么回事?
TMyMap = class(TMap) private ZLH: string; public Function GetZLH:String; procedure SetZLH(Value:String); constructor create(AOwner:TComponent);override; procedure assign(Source:TPersistent); override; end; procedure TForm1.Button2Click(Sender: TObject); begin aaMyMap:=TMyMap.create(self); aaMyMap.Parent:=self.Panel1; <----Error aaMyMap.Geoset:='United States'; end; |
zzmbeyond01
中階會員 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
大大帮忙看看: 程序运行到这里:
aaMyMap.Parent:=self.Panel1;
事儿好,事儿报错(access violation at address 0041F04Bin model 'Project.exe'. write of address 00000280),而且连续报错几次。。。
aaMyMap对象变量也可以在panel1中显示。
真不明白是怎么回事? < class="code">
//用于将aaMyMap变量拷贝到bMyMap
procedure TForm1.Button1Click(Sender: TObject);
begin
//Delphi 中Object必須先建構才能使用
bMyMap := TMyMap.create(self);
//*********************************
//这里报一次错
bMyMap.Parent:=self.Panel2;
//运行到这里好像进入了死循环,一直抱错,地址冲突??
bMyMap.Align:=alClient; bMyMap.assign(aaMyMap);
showmessage(bmymap.ZLH)
end; 有劳大大了!!
|
zzmbeyond01
中階會員 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
源码如下:
type TForm1 = class(TForm) Panel1: TPanel; Button1: TButton; Panel2: TPanel; Button2: TButton; Map1: TMap; Map2: TMap; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); end; TMyMap = class(TMap) private ZLH: string; public function GetZLH: string; procedure SetZLH(Value: string); constructor create(AOwner: TComponent); override; procedure assign(Source: TPersistent); override; end; var Form1: TForm1; aaMyMap: TmyMap; bMyMap: TMyMap; implementation { ************************************ TMyMap ************************************ } constructor TMyMap.create(AOwner: TComponent); begin inherited; end; procedure TMyMap.assign(Source: TPersistent); var aMyMap: TMyMap; i: integer; lyrCopy: CMapXLayerinfo; lyr: CMapXLayer; begin //复制构造函数创建Map1的副本 aMyMap := TMyMap(Source); self.ZLH := aMyMap.ZLH; //将控件Map1中的图层拷贝 for i := 1 to aMyMap.Layers.Count do begin lyr := aMyMap.Layers.Item(i); lyrCopy := CoLayerinfo.Create; lyrCopy.Type_ := miLayerInfoTypeTemp; self.Layers.Add(lyrCopy, i); end; self.ZoomTo(aMyMap.Zoom,aMyMap.CenterX,aMyMap.CenterY); inherited assign(source); end; {$R *.dfm} //用于将aaMyMap变量拷贝到bMyMap procedure TForm1.Button1Click(Sender: TObject); begin //Delphi 中Object必須先建構才能使用 bMyMap := TMyMap.create(self); bMyMap.Parent:=self.Panel2; bMyMap.Align:=alClient; bMyMap.assign(aaMyMap); showmessage(bmymap.ZLH) end; 创建aaMyMap 对象变量 procedure TForm1.Button2Click(Sender: TObject); begin aaMyMap := TMyMap.create(self); aaMyMap.Parent := self.Panel1; aaMyMap.Geoset := 'United States'; end; function TMyMap.GetZLH: string; begin result := zlh; end; procedure TMyMap.SetZLH(Value: string); begin zlh := value; end; |
speedup
資深會員 發表:19 回覆:259 積分:280 註冊:2003-07-04 發送簡訊給我 |
|
zzmbeyond01
中階會員 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
大大 :
TMAP 是一個ActiveX的Wrapper Class 非標準的VCL Componentactivex控件。
封装的类wrapper class太复杂了。
创建aaMyMap 对象变量 procedure TForm1.Button2Click(Sender: TObject); begin aaMyMap := TMyMap.create(self); aaMyMap.Parent := self.Panel1; <--执行正常 aaMyMap.Geoset := 'United States'; end; //用于将aaMyMap变量拷贝到bMyMap procedure TForm1.Button1Click(Sender: TObject); begin //Delphi 中Object必須先建構才能使用 bMyMap := TMyMap.create(self); //********************************* //这里报一次错 bMyMap.Parent:=self.Panel2; <--这里还是报错,按说和创建aaMyMap 对象变量类似,为什么不对?怎么办呢? //运行到这里好像进入了死循环,一直抱错,地址冲突?? //干脆屏蔽掉了 bMyMap.Align:=alClient; bMyMap.assign(aaMyMap); showmessage(bmymap.ZLH) end; |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |