線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1962
推到 Plurk!
推到 Facebook!

覆盖TPersistent的assign方法疑问

尚未結案
zzmbeyond01
中階會員


發表:98
回覆:167
積分:53
註冊:2003-09-07

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-05-18 14:10:40 IP:218.70.xxx.xxx 未訂閱
大大好: 我希望创建一个对象变量的副本(拷贝),请问如何实现? 查阅《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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-05-18 14:46:40 IP:61.224.xxx.xxx 未訂閱
引言: 大大好: 我希望创建一个对象变量的副本(拷贝),请问如何实现? 查阅《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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-05-18 16:03:59 IP:218.70.xxx.xxx 未訂閱
请问如何实现将 TMap(一个axtivex控件)中的属性信息,拷贝呢?因为其private区域全是接口或者事件类型。
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-05-18 17:46:06 IP:202.39.xxx.xxx 未訂閱
參考這篇看看: 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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-05-18 17:50:47 IP:61.224.xxx.xxx 未訂閱
引言: 请问如何实现将 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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-05-18 18:48:15 IP:218.70.xxx.xxx 未訂閱
触发:"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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-05-19 00:31:33 IP:218.70.xxx.xxx 未訂閱
大大帮忙看看:    程序运行到这里:   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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-05-19 00:36:06 IP:218.70.xxx.xxx 未訂閱
源码如下:  
     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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-05-19 09:51:08 IP:61.224.xxx.xxx 未訂閱
引言: 源码如下: ...
看不出來,你要不要公佈一下TMap的Source Code 或是 TMAP 是一個ActiveX的Wrapper Class 非標準的VCL Component? 混心雜欲 棄修身~唉
------
唉~
zzmbeyond01
中階會員


發表:98
回覆:167
積分:53
註冊:2003-09-07

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-05-19 12:55:10 IP:218.70.xxx.xxx 未訂閱
大大 : 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;        
系統時間:2024-07-03 13:57:28
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!