{"id":4329,"date":"2016-11-28T20:05:03","date_gmt":"2016-11-28T12:05:03","guid":{"rendered":"http:\/\/blog.qdac.cc\/?p=4329"},"modified":"2016-11-28T20:05:03","modified_gmt":"2016-11-28T12:05:03","slug":"%e6%9d%82%e8%b0%88%e4%bb%8e-delphi-%e6%ba%90%e7%a0%81%e4%b8%ad%e8%a7%a3%e6%9e%90%e8%b5%84%e6%ba%90%e5%ad%97%e7%ac%a6%e4%b8%b2","status":"publish","type":"post","link":"https:\/\/blog.qdac.cc\/?p=4329","title":{"rendered":"[\u6742\u8c08]\u4ece Delphi \u6e90\u7801\u4e2d\u89e3\u6790\u8d44\u6e90\u5b57\u7b26\u4e32"},"content":{"rendered":"<p>\u8fd9\u662f\u5e94\u7fa4\u53cb\u7684\u8981\u6c42\u5199\u7684\u4e00\u6bb5\u4ee3\u7801\uff0c\u7528\u4e8e\u5c06 Delphi \u6e90\u7801\u4e2d resourcestring \u5b9a\u4e49\u7684\u8d44\u6e90\u5b57\u7b26\u4e32\u89e3\u6790\u51fa\u6765\u3002<\/p>\n<pre class=\"lang:delphi decode:true \">uses qstring;\r\n\r\ntype\r\n  TPascalResourceStringParser = class\r\n  private\r\n    function GetItems(const AIdx: Integer): QStringW;\r\n    function GetCount: Integer;\r\n    function GetNames(const AIdx: Integer): QStringW;\r\n    function GetValues(const AIdx: Integer): QStringW;\r\n  protected\r\n    FItems: TStringList;\r\n  public\r\n    constructor Create; overload;\r\n    destructor Destroy; override;\r\n    procedure Parse(S: QStringW);\r\n    property Items[const AIdx: Integer]: QStringW read GetItems;\r\n    property Names[const AIdx: Integer]: QStringW read GetNames;\r\n    property Values[const AIdx: Integer]: QStringW read GetValues;\r\n    property Count: Integer read GetCount;\r\n  end;\r\n\r\n{ TPascalResourceStringParser }\r\n\r\nconstructor TPascalResourceStringParser.Create;\r\nbegin\r\n  FItems := TStringList.Create;\r\nend;\r\n\r\ndestructor TPascalResourceStringParser.Destroy;\r\nbegin\r\n  FreeAndNil(FItems);\r\n  inherited;\r\nend;\r\n\r\nfunction TPascalResourceStringParser.GetCount: Integer;\r\nbegin\r\n  Result := FItems.Count;\r\nend;\r\n\r\nfunction TPascalResourceStringParser.GetItems(const AIdx: Integer): String;\r\nbegin\r\n  Result := FItems[AIdx];\r\nend;\r\n\r\nfunction TPascalResourceStringParser.GetNames(const AIdx: Integer): QStringW;\r\nbegin\r\n  Result := FItems.Names[AIdx];\r\nend;\r\n\r\nfunction TPascalResourceStringParser.GetValues(const AIdx: Integer): QStringW;\r\n  function DecodeString(S: QStringW): QStringW;\r\n  var\r\n    ps, pd: PWideChar;\r\n    V: Int64;\r\n    AIntToChar: Boolean;\r\n  begin\r\n    if Length(S) &gt; 0 then\r\n    begin\r\n      ps := PWideChar(S);\r\n      SkipSpaceW(ps);\r\n      SetLength(Result, Length(S));\r\n      pd := PWideChar(Result);\r\n      while ps^ &lt;&gt; #0 do\r\n      begin\r\n        if ps^ = '''' then\r\n        begin\r\n          Inc(ps);\r\n          while ps^ &lt;&gt; '''' do\r\n          begin\r\n            pd^ := ps^;\r\n            Inc(pd);\r\n            Inc(ps);\r\n          end;\r\n          Inc(ps);\r\n        end\r\n        else\r\n        begin\r\n          if ps^ = '#' then\r\n          begin\r\n            Inc(ps);\r\n            AIntToChar := true;\r\n          end\r\n          else if StartWithW(ps, 'char', true) then\r\n          begin\r\n            Inc(ps, 4);\r\n            SkipSpaceW(ps);\r\n            if ps^ = '(' then\r\n            begin\r\n              Inc(ps);\r\n              SkipSpaceW(ps);\r\n              AIntToChar := true;\r\n            end;\r\n          end\r\n          else if StartWithW(ps, 'chr', true) then\r\n          begin\r\n            Inc(ps, 3);\r\n            SkipSpaceW(ps);\r\n            if ps^ = '(' then\r\n            begin\r\n              Inc(ps);\r\n              SkipSpaceW(ps);\r\n              AIntToChar := true;\r\n            end;\r\n          end\r\n          else\r\n            AIntToChar := false;\r\n          if AIntToChar then\r\n          begin\r\n            if ParseInt(ps, V) &gt; 0 then\r\n            begin\r\n              pd^ := WideChar(V);\r\n              Inc(pd);\r\n            end;\r\n          end\r\n          else\r\n            Inc(ps);\r\n        end;\r\n      end;\r\n      SetLength(Result, pd - PWideChar(Result));\r\n    end\r\n    else\r\n      Result := '';\r\n  end;\r\n\r\nbegin\r\n  Result := DecodeString(FItems.ValueFromIndex[AIdx]);\r\nend;\r\n\r\nprocedure TPascalResourceStringParser.Parse(S: QStringW);\r\nvar\r\n  AHelper: TQStringCatHelperW;\r\n  ps, pl: PQCharW;\r\n  ALine: QStringW;\r\n  ALn: Integer;\r\n  AStarted: Boolean;\r\n  function DecodeStatement: QStringW;\r\n  var\r\n    AQuoter: QCharW;\r\n  begin\r\n    SkipSpaceW(ps);\r\n    AHelper.Position := 0;\r\n    while ps^ &lt;&gt; #0 do\r\n    begin\r\n      \/\/ \u8df3\u8fc7\u884c\u6ce8\u91ca\r\n      if (ps[0] = '\/') and (ps[1] = '\/') then\r\n        SkipLineW(ps)\r\n        \/\/ \u8df3\u8fc7\u5757\u6ce8\u91ca\r\n      else if ps[0] = '{' then\r\n      begin\r\n        SkipUntilW(ps, '}');\r\n        Inc(ps);\r\n      end\r\n      \/\/ \u53e6\u4e00\u79cd\u5757\u6ce8\u91ca\r\n      else if (ps[0] = '(') and (ps[0] = '*') then\r\n      begin\r\n        repeat\r\n          SkipUntilW(ps, '*');\r\n          if ps^ = '*' then\r\n            Inc(ps);\r\n        until (ps^ = ')') or (ps^ = #0);\r\n        if ps^ = ')' then\r\n          Inc(ps);\r\n      end\r\n      else if ps^ = '''' then\r\n      begin\r\n        AHelper.Cat(ps^);\r\n        AQuoter := ps^;\r\n        Inc(ps);\r\n        while ps^ &lt;&gt; #0 do\r\n        begin\r\n          AHelper.Cat(ps^);\r\n          if ps^ = '''' then\r\n          begin\r\n            Inc(ps);\r\n            if ps^ &lt;&gt; '''' then\r\n              Break\r\n            else\r\n              Inc(ps);\r\n          end\r\n          else\r\n            Inc(ps);\r\n        end;\r\n      end\r\n      else if ps^ = ';' then \/\/ \u8bed\u53e5\u7ed3\u675f\r\n      begin\r\n        Result := AHelper.Value;\r\n        Inc(ps);\r\n        SkipSpaceW(ps);\r\n        Break;\r\n      end\r\n      else\r\n      begin\r\n        if Ord(ps^) in [9, 10, 13, 32] then\r\n        begin\r\n          if AHelper.Position &gt; 0 then\r\n          begin\r\n            if AHelper.Chars[AHelper.Position - 1] &lt;&gt; ' ' then\r\n              AHelper.Cat(' ');\r\n          end;\r\n        end\r\n        else\r\n          AHelper.Cat(ps^);\r\n        Inc(ps);\r\n      end;\r\n    end;\r\n    SkipSpaceW(ps);\r\n  end;\r\n\r\nbegin\r\n  AHelper := TQStringCatHelperW.Create;\r\n  FItems.Clear;\r\n  try\r\n    ps := PQCharW(S);\r\n    ALn := 0;\r\n    AStarted := false;\r\n    while ps^ &lt;&gt; #0 do\r\n    begin\r\n      ALine := DecodeStatement;\r\n      pl := PQCharW(ALine);\r\n      if StartWithW(pl, 'interface ', true) then\r\n      begin\r\n        ALine := DeleteLeftW(ALine, 'interface ', true);\r\n        AStarted := false;\r\n      end\r\n      else if StartWithW(pl, 'implementation ', true) then\r\n      begin\r\n        ALine := DeleteLeftW(ALine, 'implementation ', true);\r\n        AStarted := false;\r\n      end;\r\n      pl := PQCharW(ALine);\r\n      if StartWithW(pl, 'resourcestring ', true) then\r\n      begin\r\n        AStarted := true;\r\n        ALine := DeleteLeftW(ALine, 'resourcestring ', true);\r\n      end\r\n      else if AStarted then\r\n        AStarted := not(StartWithW(pl, 'var ', true) or StartWithW(pl,\r\n          'function ', true) or StartWithW(pl, 'type ', true) or StartWithW(pl,\r\n          'const ', true) or StartWithW(pl, 'uses ', true));;\r\n      if AStarted then\r\n      begin\r\n        FItems.Add(ALine);\r\n        \/\/ DebugOut('Line %d:%s', [ALn, ALine]);\r\n        Inc(ALn);\r\n      end;\r\n    end;\r\n  finally\r\n    FreeAndNil(AHelper);\r\n    FItems.EndUpdate;\r\n  end;\r\nend;<\/pre>\n<p>\u7559\u6b64\u5b58\u5ff5\uff0c\u540c\u65f6\u5206\u4eab\u7ed9\u5927\u5bb6\uff0c\u6709\u7528\u7684\u5c31\u62ff\u53bb\u7528\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u8fd9\u662f\u5e94\u7fa4\u53cb\u7684\u8981\u6c42\u5199\u7684\u4e00\u6bb5\u4ee3\u7801\uff0c\u7528\u4e8e\u5c06 D [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[21],"tags":[465,78,688],"class_list":["post-4329","post","type-post","status-publish","format-standard","hentry","category-misc","tag-qlang","tag-78","tag-688"],"views":3614,"_links":{"self":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts\/4329","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4329"}],"version-history":[{"count":1,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts\/4329\/revisions"}],"predecessor-version":[{"id":4330,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts\/4329\/revisions\/4330"}],"wp:attachment":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4329"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4329"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4329"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}