2012-07-02 8 views
5

मैं किसी घटक में कुछ गुण अपडेट कर रहा हूं। गायब संपत्ति त्रुटियों से बचने के लिए मैं धारा से पुरानी गुणों को पढ़ने के लिए DefineProperties का उपयोग कर रहा हूं। अधिकांश गुण ठीक काम करते हैं उदा। इंटीजर, लेकिन मुझे काम करने के लिए TPersistent पर आधारित गुण नहीं मिल सकते हैं। ReadProperty (TPersistent)में प्रक्रिया TReader सुरक्षित है, सार्वजनिक नहीं है और इसे एक्सेस करने के लिए हैक की आवश्यकता है। फिर भी, ReadFontProperty प्रक्रिया कभी नहीं कहा जाता है और गायब संपत्ति अपवाद होता है।TPersistent गुणों को प्रतिस्थापित करने के लिए DefineProperties का उपयोग करें उदा। TFont

मैं TFont संपत्ति कैसे पढ़ूं?

यहां कुछ नमूना कोड है कि मैं इसे कैसे करने की कोशिश कर रहा हूं।

... 

type 
    TMyComponent = class(TComponent) 
    strict private 
    // Removed 
    //FIntegerProperty: Integer; 
    //FFontProperty: TFont; 

    // New 
    FNewIntegerProperty: Integer; 
    FNewFontProperty: TFont; 

    procedure ReadIntegerProperty(Reader: TReader); 
    procedure ReadFontProperty(Reader: TReader); 
    protected 
    procedure DefineProperties(Filer: TFiler); override; 
    published 
    // Removed properties 
    //property IntegerProperty: Integer read FIntegerProperty write FIntegerProperty; 
    //property FontProperty: TFont read FFontProperty write SetFontProperty; 

    // New properties 
    property NewIntegerProperty: Integer read FNewIntegerProperty write FNewIntegerProperty; 
    property NewFontProperty: TFont read FNewFontProperty write SetNewFontProperty; 
    end; 

implementation 

procedure TMyComponent.DefineProperties(Filer: TFiler); 
begin 
    inherited; 

    // This works 
    Filer.DefineProperty('IntegerProperty', ReadIntegerProperty, nil, FALSE); 

    // This doesn't 
    Filer.DefineProperty('FontProperty', ReadFontProperty, nil, FALSE); 
end; 

procedure TMyComponent.ReadIntegerProperty(Reader: TReader); 
begin 
    FNewIntegerProperty:= Reader.ReadInteger; 
end; 

type 
    THackReader = class(TReader); 

procedure TMyComponent.ReadFontProperty(Reader: TReader); 
begin 
    { TODO : This doesn't work. How do we read fonts? } 
    THackReader(Reader).ReadProperty(FNewFontProperty); 
end; 

... 

अद्यतन 1

निम्नलिखित कोड का उपयोग कर दाऊद के सुझाव की कोशिश की:

Filer.DefineProperty('Font.CharSet', ReadFontCharSet, nil, False); 

...

procedure TMyComponent.ReadFontCharSet(Reader: TReader); 
begin 
    Reader.ReadInteger; 
end; 

मैं एक अमान्य गुण मूल्य त्रुटि मिलती है। मुझे लगता है कि यह वर्णसेट प्रकार TFontCharset (= System.UITypes.TFontCharset = 0..255) का होने के साथ कुछ करने के लिए है। मैं इस प्रकार की संपत्ति कैसे पढ़ूं?

उत्तर

4

आदेश में इस आप TFont के प्रत्येक व्यक्ति प्रकाशित संपत्ति के साथ काम करने की जरूरत है और आप पूरी तरह से योग्य नामों का उपयोग करने की आवश्यकता होगी करने के लिए।

Filer.DefineProperty('FontProperty.Name', ReadFontName, nil, False); 
Filer.DefineProperty('FontProperty.Height', ReadFontHeight, nil, False); 
Filer.DefineProperty('FontProperty.Size', ReadFontSize, nil, False); 
// and so on for all the other published properties of TFont 

ReadFontName, ReadFontHeight आदि नए नाम घटक में वर्ष संपत्ति मूल्यों को पढ़ना चाहिए।

procedure TMyComponent.ReadFontName(Reader: TReader); 
begin 
    FNewFontProperty.Name := Reader.ReadString; 
end; 

// etc. etc. 

अद्यतन

आप पूछ कैसे वर्णसेट संपत्ति को पढ़ने के लिए। यह जटिल है क्योंकि इसे या तो पाठ पहचानकर्ता के रूप में लिखा जा सकता है (FontCharsets ग्राफिक्स.pas में स्थिर), या एक सादे पूर्णांक मान के रूप में। यहां कुछ तेजी से एक साथ कोड हैक किया गया है जो आपके वर्णसेट को पढ़ेगा।

procedure TMyComponent.ReadFontCharset(Reader: TReader); 

    function ReadIdent: string; 
    var 
    L: Byte; 
    LResult: AnsiString; 
    begin 
    Reader.Read(L, SizeOf(Byte)); 
    SetString(LResult, PAnsiChar(nil), L); 
    Reader.Read(LResult[1], L); 
    Result := UTF8ToString(LResult); 
    end; 

    function ReadInt8: Shortint; 
    begin 
    Reader.Read(Result, SizeOf(Result)); 
    end; 

    function ReadInt16: Smallint; 
    begin 
    Reader.Read(Result, SizeOf(Result)); 
    end; 

var 
    Ident: string; 
    CharsetOrdinal: Integer; 

begin 
    Beep; 
    case Reader.ReadValue of 
    vaIdent: 
    begin 
     Ident := ReadIdent; 
     if not IdentToCharset(Ident, CharsetOrdinal) then begin 
     raise EReadError.Create('Could not read MyFont.Charset'); 
     end; 
     FNewFontProperty.Charset := CharsetOrdinal; 
    end; 
    vaInt8: 
    FNewFontProperty.Charset := ReadInt8; 
    vaInt16: 
    FNewFontProperty.Charset := ReadInt16; 
    else 
    raise EReadError.Create('Could not read FontProperty.Charset'); 
    end; 
end; 
+0

@ नोर्गपॉल आप इस पर कैसे पहुंचे? मुझे यकीन है कि यह आपके प्रश्न का उत्तर है। –

+0

हाय डेविड। जवाब के लिए धन्यवाद। मुझे यकीन है कि यह सही है, लेकिन मुझे अभी तक इसका परीक्षण करने का मौका नहीं मिला है। मैं जल्द ही इसे पाने की कोशिश करूंगा। – norgepaul

+0

ठीक है, मैंने सोचा कि क्या आप एक समस्या में आएंगे और उत्सुक थे। –

संबंधित मुद्दे

 संबंधित मुद्दे