2015-01-08 41 views
4

我有以下類:如何知道TPNGObject是否有有效的頭文件?

TPNGButton = class(TNeoGraphicControl) 
    private 
     FImageDown: TPNGObject; 
     fImageNormal: TPNGObject; 
     fImageOver: TPNGObject; 
    ... 

    public 
    ... 
     constructor Create(AOwner: TComponent); override; 
     destructor Destroy; override; 
    published 
     property ImageNormal: TPNGObject read fImageNormal write SetImageNormal; 
     property ImageDown: TPNGObject read FImageDown write SetImageDown; 
     property ImageOver: TPNGObject read FImageOver write SetImageOver; 
    ... 
end; 

我使用下面的函數到objFrom的屬性複製到objTo作爲參數。

procedure CopyObject(ObjFrom, ObjTo: TObject); 
var 
    PropInfos: PPropList; 
    PropInfo: PPropInfo; 
    Count, Loop: Integer; 
    OrdVal: Longint; 
    StrVal: String; 
    FloatVal: Extended; 
    MethodVal: TMethod; 
begin 
    { Iterate thru all published fields and properties of source } 
    { copying them to target } 

    { Find out how many properties we'll be considering } 
    Count := GetPropList(ObjFrom.ClassInfo, tkAny, nil); 
    { Allocate memory to hold their RTTI data } 
    GetMem(PropInfos, Count * SizeOf(PPropInfo)); 
    try 
    { Get hold of the property list in our new buffer } 
    GetPropList(ObjFrom.ClassInfo, tkAny, PropInfos); 
    { Loop through all the selected properties } 
    for Loop := 0 to Count - 1 do 
    begin 
     PropInfo := GetPropInfo(ObjTo.ClassType, PropInfos^[Loop]^.Name); 
     { Check the general type of the property } 
     { and read/write it in an appropriate way } 
     case PropInfos^[Loop]^.PropType^.Kind of 
     tkInteger, tkChar, tkEnumeration, 
     tkSet, tkClass{$ifdef Win32}, tkWChar{$endif}: 
     begin 
      OrdVal := GetOrdProp(ObjFrom, PropInfos^[Loop]); 
      if Assigned(PropInfo) and (Assigned(PropInfo^.SetProc)) then 
      SetOrdProp(ObjTo, PropInfo, OrdVal); //here happens the bug... 
     end; 
     tkFloat: 
     begin 
      FloatVal := GetFloatProp(ObjFrom, PropInfos^[Loop]); 
      if Assigned(PropInfo) and (Assigned(PropInfo^.SetProc)) then 
      SetFloatProp(ObjTo, PropInfo, FloatVal); 
     end; 
     {$ifndef DelphiLessThan3} 
     tkWString, 
     {$endif} 
     {$ifdef Win32} 
     tkLString, 
     {$endif} 
     tkString: 
     begin 
      { Avoid copying 'Name' - components must have unique names } 
      if UpperCase(PropInfos^[Loop]^.Name) = 'NAME' then 
      Continue; 
      StrVal := GetStrProp(ObjFrom, PropInfos^[Loop]); 
      if Assigned(PropInfo) and (Assigned(PropInfo^.SetProc)) then 
      SetStrProp(ObjTo, PropInfo, StrVal); 
     end; 
     tkMethod: 
     begin 
      MethodVal := GetMethodProp(ObjFrom, PropInfos^[Loop]); 
      if Assigned(PropInfo) and (Assigned(PropInfo^.SetProc)) then 
      SetMethodProp(ObjTo, PropInfo, MethodVal); 
     end 
     end 
    end 
    finally 
    FreeMem(PropInfos, Count * SizeOf(PPropInfo)); 
    end; 
end; 

但是,當PNGObject屬性在SetOrdProp過去了,德爾福返回以下異常: Exception

我的問題是: 我怎麼能知道,如果PNGObject有SetOrdProp前一個有效的頭?或以另一種方式來解決這個問題...

其他評論

  • 使用Assign方法如下面的代碼和註釋的CopyObject功能:

    TControl(objCtrlZ.Referencia).Assign(Component); 
        // "Component" is objFrom and objCtrlZ.Referencia is objTo 
        // CopyObject(Component, objCtrlZ.Referencia); 
    

德爾福發現以下例外情況:

Exception 2

+4

如果您想複製'TPNGObject',請使用'Assign'方法。 – TLama

+1

嗯,'CopyObject'看起來像是你問題的根源。一個合理的舉動就是把它扔掉。 –

+0

的確,這不是「TPersistent」的目的嗎? –

回答

2

我解決了我的問題。

要驗證TPNGObject有一個有效報頭我使用此代碼:

objTemp := GetObjectProp(ObjFrom,PropInfos^[Loop]); 
if ((TPNGObject(objTemp).Chunks.Count <> 0) and (TPNGObject(objTemp).Chunks.Item[0] is TChunkIHDR)) then begin ... end; 

第一行我得到的屬性和TPNGObject一如既往的對象被分配的objTemp不能得到的AV。

驗證標題我驗證在塊中如果計數是不同的零和如果Item [0]是TChunkIHDR知道如果是一個有效的頭或沒有。

謝謝!

+0

你深感困惑。 RTTI是錯誤的。你不能用它來制定一個你認爲的普通克隆方法。然後編寫TPNGObject(objTemp)意味着你只有通用性的錯覺。編寫一個類型安全的Assign方法。 –

+0

'TPNGObject'具有一個公共'Header'屬性,如果它存在則返回'TChunkIHDR'塊。 –

相關問題