2016-08-31 13 views
18

Delphi'de Live Templates'i çok kullanıyorum ama GUIDS'i şablonlara eklemek için bir çözüm bulmaya çalıştım. Bunu yapmayı bilen var mı?Delphi'de bir Canlı Şablon çağrıldığında nasıl bir GUID oluşturabilirim?

Şablonun altında şimdi GUID ile kelime var el ile değiştirmeniz gerekir.

<?xml version="1.0" encoding="utf-8" ?> 
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" 
      version="1.0.0"> 
<template name="iacc" surround="false" invoke="manual"> 
    <point name="name"> 
     <text> 
      IntfAccessors 
     </text> 
     <hint> 
      Accessors name 
     </hint> 
    </point> 
    <description> 
     accessor declaration 
    </description> 
    <author> 
     PMH 
    </author> 
    <code language="Delphi" context="methoddecl" delimiter="|"> <![CDATA[I|name|Accessors = interface(IInterface) 
GUID <-- here I want a GUID 
end; 


I|name| = interface(I|name|Accessors) 
GUID <-- here I want a GUID 
end; 
    ]]> 
     </code> 
    </template> 
</codetemplate> 
+0

+100, ne harika bir soru! – Johan

+0

Çoğunlukla, Canlı Şablonlar statiktir. Bir Şablon çağrıldığında bazı komut dosyası olayları olsa da ve bu tür komut dosyalarının dinamik olarak içerik oluşturmak için çağırabileceği bazı işlevler olsa da, bir GUID oluşturmak mevcut işlevlerden biri değildir. Daha fazla ayrıntı için [Live Templates Technical Info] 'a bakın (http://delphi.wikia.com/wiki/Live_Templates_Technical_Info). –

+0

Canlı Şablonlar Teknik Bilgisi'ni okudum ve ayrıca komut dosyası altyapısını okudum ama aslında bir komut dosyası altyapısı oluşturmamı gerektirmeyen bir çözüm bekledim. –

cevap

22

Bunu yapmak için özel bir komut dosyası yazarak IDE'yi genişletebilirsiniz. (Here Nick Hodges tarafından yazılmış bir makaleyi, geçerli tarihi ekleyen benzer bir örnekle yazılmıştır.)

Örnek şablonunuzdaki iki farklı arabirimin iki farklı IID'ye gereksinim duyduğunu varsayalım, böylece nokta adlarını yüklemek için komut dosyası altyapısını yazdım. "komut dosyası" dan (sadece isminin adın ve ismin nerede olduğu göz önüne alındığında yeni bir değer olan isim = değer çiftleri listesidir), böylece her biri ayrı bir yeni IID alan birden fazla noktaya sahip şablonlar oluşturabilirsiniz.

Örnek şablon intf.xml:

<?xml version="1.0" encoding="utf-8" ?> 
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0"> 
<template name="iacc" surround="false" invoke="manual"> 
    <point name="name"> 
     <text> 
      Accessor 
     </text> 
     <hint> 
      Accessors name 
     </hint> 
    </point> 
    <point name="guid1"/> 
    <point name="guid2"/> 
    <description> 
     accessor declaration 
    </description> 
    <author> 
     PMH 
    </author> 
    <script language="NewGuidScript" onvalidate="true"> 
     guid1=NewGuid 
     guid2=NewGuid 
    </script> 
    <code language="Delphi" context="any" delimiter="|"> <![CDATA[I|name|Accessors = interface(IInterface) 
|*||guid1| 
end; 

I|name| = interface(I|name|Accessors) 
|*||guid2| 
end;]]> 
    </code> 
    </template> 
</codetemplate> 

NewGuidScriptEngine.pas:

unit NewGuidScriptEngine; 

interface 

uses 
    Classes, SysUtils, 
    ToolsApi, CodeTemplateApi, DesignEditors; 

type 
    TNewGuidScriptEngine = class(TNotifierObject, IOTACodeTemplateScriptEngine) 
    public 
    procedure Execute(const ATemplate: IOTACodeTemplate; const APoint: IOTACodeTemplatePoint; const ASyncPoints: IOTASyncEditPoints; const AScript: IOTACodeTemplateScript; var Cancel: Boolean); 
    function GetIDString: WideString; 
    function GetLanguage: WideString; 
    end; 

procedure Register; 

implementation 

uses 
    ActiveX, 
    ComObj; 

procedure Register; 
begin 
    (BorlandIDEServices as IOTACodeTemplateServices).RegisterScriptEngine(TNewGuidScriptEngine.Create); 
end; 

procedure TNewGuidScriptEngine.Execute(const ATemplate: IOTACodeTemplate; const APoint: IOTACodeTemplatePoint; 
    const ASyncPoints: IOTASyncEditPoints; const AScript: IOTACodeTemplateScript; var Cancel: Boolean); 
var 
    I: Integer; 
    Guid: TGUID; 
    P: IOTACodeTemplatePoint; 
    Points: TStringList; 
begin 
    Cancel := False; 
    if not Assigned(ATemplate) then 
    Exit; 

    Points := TStringList.Create; 
    try 
    Points.Text := AScript.Script; 
    for I := 0 to Points.Count - 1 do 
     Points.Strings[I] := Trim(Points[I]); 

    for I := 0 to Points.Count - 1 do 
     if Points.ValueFromIndex[I] = 'NewGuid' then 
     begin 
     P := ATemplate.FindPoint(Points.Names[I]); 
     if Assigned(P) then 
     begin 
      OleCheck(CoCreateGuid(Guid)); 
      P.Editable := False; 
      P.Value := '[''' + GUIDToString(Guid) + ''']'; 
     end; 
     end; 
    finally 
    Points.Free; 
    end; 
end; 

function TNewGuidScriptEngine.GetIDString: WideString; 
begin 
    Result := 'OndrejKelle.NewGuidScriptEngine'; 
end; 

function TNewGuidScriptEngine.GetLanguage: WideString; 
begin 
    Result := 'NewGuidScript'; 
end; 

end. 

, bir designtime sadece paket içine ünitesinin üzerine yerleştirin onun requires maddesi designide.dcp bir başvuru için ve paketi IDE'ye kurun.

Yararlı başka, benzer şablon aşağıdaki gibi görünebilir:

<?xml version="1.0" encoding="utf-8" ?> 
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0"> 
<template name="iacc" surround="false" invoke="manual"> 
    <point name="name"> 
     <text> 
     </text> 
     <hint> 
      Accessors name 
     </hint> 
    </point> 
    <point name="guid1"/> 
    <point name="guid2"/> 
    <description> 
     accessor declaration 
    </description> 
    <author> 
     PMH 
    </author> 
    <script language="NewGuidScript" onvalidate="true"> 
     guid1=NewGuid 
     guid2=NewGuid 
    </script> 
    <code language="Delphi" context="any" delimiter="|"> <![CDATA[const 
    SIID_I|name|Accessors = |guid1|; 
    IID_I|name|Accessors: TGUID = SIID_I|name|Accessors; 
    SIID_I|name| = |guid2|; 
    IID_I|name|: TGUID = SIID_I|name|; 

type 
    I|name|Accessors = interface 
    [SIID_I|name|Accessors] 
    end; 

    I|name| = interface(I|name|Accessors) 
    [SIID_I|name|] 
    end;]]> 
    </code> 
    </template> 
</codetemplate> 

Bu dize yanı sıra TGUID sabitleri beyan ve ayrıca arayüz beyanlarında bunları yeniden olacaktır. Bu durumda, eklenen GUID değerleri köşeli parantez içine alınmamalıdır.

  1. sadece
  2. ayrı yeni fonksiyon NewGuidNoBrackets tanıtmak ve
  3. bazı basit tanıtmak şablonda kullanmak köşeli parantez kullanmayın için kodu değiştirin: Bunu yapmak için komut dosyası altyapısı ayarlamak için çeşitli seçenekler vardır Motorunuzun, köşeli parantezlerin kullanılıp kullanılmayacağını belirlemek için parametre değerini ayrıştırabileceği ve kullanabileceği NewGuid (false) gibi sözdizimi.
+2

Vay, bu harika. – Johan

+1

İş için teşekkürler, olduğu gibi çalışıyor. –

İlgili konular