2012-07-12 24 views
7

डेल्फी हिस्सा:पास्कल स्क्रिप्ट फ़ंक्शन कॉल पर इंटरफेस्ड ऑब्जेक्ट को कैसे पास किया जाए?

मैं घटना के साथ एक वर्ग है और उस घटना से मैं एक प्रक्रिया यह करने के लिए interfaced वस्तु गुजर कॉल करने के लिए की जरूरत है। यह डेल्फी में ठीक काम करता है लेकिन मुझे पास्कल स्क्रिप्ट में इसे घोषित करने में समस्याएं हैं।

पृष्ठभूमि करने के लिए - IGPGraphics इंटरफ़ेस Delphi GDI+ library का एक हिस्सा है और तरीकों के बिना इस तरह परिभाषित किया गया है:

type 
    IGdiplusBase = interface 
    ['{24A5D3F5-4A9B-42A2-9F60-20825E2740F5}'] 
    IGPGraphics = interface(IGdiPlusBase) 
    ['{57F85BA4-CB01-4466-8441-948D03588F54}'] 

निम्नलिखित सिर्फ एक सरल बनाया है कि मैं क्या पास्कल स्क्रिप्ट में क्या करने की जरूरत के डेल्फी स्यूडोकोड है:

type 
    TRenderEvent = procedure(Sender: TObject; const GPGraphics: IGPGraphics) of object; 
    TRenderClass = class(TGraphicControl) 
    private 
    FOnRender: TRenderEvent; 
    public 
    property OnRender: TRenderEvent read FOnRender write FOnRender; 
    end; 

// when the TRenderClass object instance fires its OnRender event I want to call 
// the RenderObject procedure passing the IGPGraphics interfaced object to it; I 
// hope I'm doing it right, I'm just a newbie to this stuff - but it works so far 
// in Delphi (since I didn't get it to work in Pascal Script) 

procedure TForm1.RenderClass1Render(Sender: TObject; const GPGraphics: IGPGraphics); 
begin 
    RenderObject(GPGraphics, 10, 10); 
end; 

// what I need in Pascal Script is between these two lines; just pass the interface 
// object from the event fired by component to the procedure called from inside it 

procedure RenderObject(const GPGraphics: IGPGraphics; X, Y); 
begin 
    // and here to work with the interfaced object somehow 
end; 

पास्कल स्क्रिप्ट संकलन हिस्सा:

मेरा लक्ष्य कक्षा के साथ पास्कल स्क्रिप्ट में उपलब्ध होना है और उस इंटरफ़ेस ऑब्जेक्ट को उस प्रक्रिया में बस ऊपर की तरह पारित करने की आवश्यकता है, इसलिए पहले मैंने संकलन समय के लिए घोषणा करने की कोशिश की है (लेकिन मैं नहीं हूं

// the interface 
PS.AddInterface(Cl.FindInterface('IUnknown'), StringToGuid('{57F85BA4-CB01-4466-8441-948D03588F54}'), 'IGPGraphics'); 
// the type for the event 
PS.AddTypeS('TRenderEvent', 'procedure(Sender: TObject; const GPGraphics: IGPGraphics)'); 
// and the class with the event itself 
with PS.AddClassN(PS.FindClass('TGraphicControl'), 'TRenderClass') do 
begin 
    RegisterProperty('OnRender', 'TRenderEvent', iptrw); 
end; 

पास्कल स्क्रिप्ट रनटाइम हिस्सा:

मैं निश्चित रूप से कहाँ खो रहा हूँ क्रम हिस्सा है भी यकीन है कि अगर यह है कि ऐसा करने के लिए) सही तरीका है। मैं पता लगा सकते हैं कि कैसे कॉल स्टैक से interfaced वस्तु पाने के लिए और यह मेरे RenderObject प्रक्रिया को पारित:

function RenderClassProc(Caller: TPSExec; Proc: TPSExternalProcRec; Global, 
    Stack: TPSStack): Boolean; 
var 
    PStart: Cardinal; 
begin 
    PStart := Stack.Count-1; 
    Result := True; 
    if Proc.Name = 'RENDEROBJECT' then 
    begin 
    // how do I get the interfaced object from Stack (or whatever else) and pass 
    // it to the RenderObject proc here ? I can't find anything related about it 
    // except functions that has no parameter index 
    RenderObject(Stack.Get ?, Stack.GetInt(PStart-2), Stack.GetInt(PStart-3)); 
    end; 
end; 

और सवाल यह है:

किसी को भी मुझे सुझाव है कि कैसे करने के लिए कर सकते हैं इस मामले के लिए संकलन और रनटाइम भाग को सही ढंग से परिभाषित करें या किसी भी तरह इंटरफेस्ड ऑब्जेक्ट को पास करने के साथ मुझे सही करें?

पीएस उस Inno- सेटअप टैग के लिए खेद है, लेकिन से इस तरह से InnoSetup को कस्टमाइज़ करने का प्रयास किया।

बहुत बहुत धन्यवाद!

उत्तर

1

यदि मैं समझता हूं कि आप क्या पूछ रहे हैं, तो आप किसी विधि को पैरामीटर के रूप में इंटरफ़ेस पास करना चाहते हैं। दुर्भाग्यवश, मेरे पास इसका सटीक उत्तर नहीं है, लेकिन मुझे पता है कि पास्कलस्क्रिप्ट के लिए वैश्विक चर में इंटरफ़ेस कैसे असाइन किया जाए। यहां बताया गया है कि मैं इसे कैस्टेलिया में कैसे करता हूं:

PSScript ऑनकंपाइल ईवेंट में, PS.Comp.AddInterface के साथ इंटरफ़ेस जोड़ें, और उसके बाद प्रत्येक आवश्यक विधियां जोड़ें। उसके बाद, इंटरफ़ेस प्रकार का एक चर जोड़ें।यह इस तरह दिखता है उदाहरण के लिए,:

with PS.Comp.AddInterface(ARunner.Comp.FindInterface('IUnknown'), 
    StringToGUID('{0346F7DF-CA7B-4B15-AEC9-2BDD680EE7AD}'), 
    'ICastaliaMacroClipboardAccess') do 
begin 
    RegisterMethod('function GetText: string', cdRegister); 
    RegisterMethod('procedure SetText(AText: string)', cdRegister); 
end; 
PS.AddRegisteredVariable('Clipboard', 'ICastaliaMacroClipboardAccess'); 

फिर, OnExectute घटना में, उदाहरण के लिए पूर्व में बने चर बाँध:

P := PS.GetVariable('Clipboard'); //P is type PIFVariant 
SetVariantToInterface(P, Implementing object as ICastaliaMacroClipboardAccess);  

किया है, स्क्रिप्ट interfaced वस्तु की पहुंच है चर के माध्यम से, इसलिए इस उदाहरण में, स्क्रिप्ट में क्लिपबोर्ड.गेटटेक्स्ट पर कॉल हो सकता है, और यह काम करता है जैसा आप उम्मीद करेंगे।

यह परीक्षण और काम करता है।

अब, मैं अनुमान लगाता हूं कि आप ऊपर से PIFVariant में गुजरने वाले TPSScript.ExecuteFunction का उपयोग करने में सक्षम हो सकते हैं, जो आप चाहते हैं उसके करीब पहुंचने के लिए। हालांकि, मैंने ऐसा कुछ नहीं किया है जिसे मैंने परीक्षण किया है।

शुभकामनाएं!

1

यह मानना ​​कठिन है, लेकिन मुझे पता चला यह

procedure TApp.CallProcedureWithClassArg(x: TPSExec); 
var 
    o: TSampleObject; 
    argumentList: TPSList; 
    arg1: TPSVariantClass; 
    proc: Integer; 
begin 
    o := TSampleObject.Create; 
    o.X := 1; // do something with the object maybe 
    proc := x.GetProc('TakeThis'); 
    argumentList := TPSList.Create; 
    arg1.VI.FType := x.FindType2(btClass); 
    arg1.Data := o; 
    argumentList.Add(@arg1); 
    x.RunProc(argumentList, proc); 
    argumentList.Free; 
end; 

यह मूलतः क्या किया जाना चाहिए है कैसे करना है।

  • उपयोगकर्ता अपने TPSExec उदाहरण, मान लें कि एक्स
  • फिर x.GetProc पद्धति का उपयोग करके प्रक्रिया संख्या प्राप्त
  • तो TPSList प्रकार के तर्क सूची
  • TPSVariantClass वर बनाएं, अपने वर्ग उदाहरण आवंटित (बनाने के जो अपने डेटा फ़ील्ड के लिए पारित किया जाना चाहिए)
  • भी अपने VI.FType क्षेत्र के लिए x.FindType2 (btClass) आवंटित (बिल्कुल पता नहीं क्यों यह काम करता है)
  • TPSList सूची TPSVariantClass चर के लिए सूचक जोड़ने
  • और ....... प्रक्रिया को कॉल करें x.RunProc (argList, proc); जहां proc प्रक्रिया प्राप्त की संख्या है पहले

इस वर्ग के लिए काम करता है, लेकिन यह इंटरफेस के लिए बहुत अलग नहीं होना चाहिए, बस TPSVariantClass के बजाय तर्क चर के लिए TPSVariantInterface प्रकार का उपयोग करें; बाकी सब कुछ होना चाहिए

मुझे उम्मीद है कि यह किसी की मदद करेगा।

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