Delphi XE3 e suas novidades – Parte 2

Dando sequência no review do Delphi XE3, vamos conhecer as novidades relacionadas ao IDE, VCL e RTL.

IDE

O IDE agora traz alguns novos Wizard para criação de aplicações Metropolis para VCL e FireMonkey, você verá dois novos tipos de assistentes (wizards):

  • VCL Metropolis UI Application
  • FireMonkey Metropolis UI Application

Assinatura da Aplicação na Apple Mac Store

Nas opções do projeto você verá algumas novas opções relacionados a compilação de aplicações para Mac OS que irá lhe ajudar a fazer o sandbox, code sign e preparação da aplicação para ser enviada à Apple Mac Store, a Apple exige que seja feito o sandbox e code sign, assim este recurso facilita e melhora a experiência do desenvolvedor no processo como um todo.

Conversão de Forms VCL e FireMonkey para Metropolis

No Designer do Formulário ao clicar com o botão direito você terá a opção “Convert to UI Metropolis Form”, essa opção converte seu Form VCL ou FireMonkey para o estilo metropolis.

RTL

Record Helpers para tipos simples

Delphi XE3 traz uma novidade bem legal que permite extender tipos primitivos ou simples através do uso de Record Helpers, se você não está familiarizado com Record ou Class Helpers leia este artigo.

[quote style=”boxed”]Aproveite e me siga no Twitter  [/quote]

Vamos usar o TStringHelper que é um dos record helpers que vem na RTL do XE3, com ele vamos basicamente acessamos diversos métodos diretamente a partir de uma String como se ele fosse um “objeto”, por exemplo em vez de escrever Length(Nome) para saber o tamanho da variável Nome, vamos escrever Nome.Length e obter como retorno o tamanho da mesma, basicamente o TStringHelper extende o tipo String implementando uma série de métodos que nos permite fazer isso.

Abaixo a definição original da RTL para o TStringHelper.

TStringHelper = record helper for string
private
  function GetChars(Index: Integer): Char; inline;
  function GetLength: Integer; inline;
  class function CharInArray(const C: Char; const InArray: array of Char): Boolean; static;
  function IndexOfAny(const Values: array of string; var Index: Integer): Integer; overload;
public
  const Empty = '';
  // Methods
  class function Create(C: Char; Count: Integer): string; overload; inline; static;
  class function Create(const Value: array of Char; StartIndex: Integer; Length: Integer): string; overload; static;
  class function Create(const Value: array of Char): string; overload; static;
  class function Compare(const StrA: string; const StrB: string): Integer; overload; static;
  class function Compare(const StrA: string; const StrB: string; IgnoreCase: Boolean): Integer; overload; static;
  class function Compare(const StrA: string; IndexA: Integer; const StrB: string; IndexB: Integer; Length: Integer): Integer; overload; static;
  class function Compare(const StrA: string; IndexA: Integer; const StrB: string; IndexB: Integer; Length: Integer; IgnoreCase: Boolean): Integer; overload; static;
  class function CompareOrdinal(const strA: string; const strB: string): Integer; overload; static;
  class function CompareOrdinal(const strA: string; indexA: Integer; const strB: string; indexB: Integer; length: Integer): Integer; overload; static;
  function CompareTo(const strB: string): Integer;
  function Contains(const Value: string): Boolean;
  class function Copy(const Str: string): string; inline; static;
  procedure CopyTo(SourceIndex: Integer; var destination: array of Char; DestinationIndex: Integer; Count: Integer);
  class function EndsText(const ASubText, AText: string): Boolean; static;
  function EndsWith(const Value: string): Boolean; overload;
  function EndsWith(const Value: string; IgnoreCase: Boolean): Boolean; overload;
  function Equals(const Value: string): Boolean; overload;
  class function Equals(const a: string; const b: string): Boolean; overload; static;
  class function Format(const Format: string; const args: array of const): string; overload; static;
  function GetHashCode: Integer;
  function IndexOf(value: Char): Integer; overload; inline;
  function IndexOf(const Value: string): Integer; overload; inline;
  function IndexOf(Value: Char; StartIndex: Integer): Integer; overload;
  function IndexOf(const Value: string; StartIndex: Integer): Integer; overload;
  function IndexOf(Value: Char; StartIndex: Integer; Count: Integer): Integer; overload;
  function IndexOf(const Value: string; StartIndex: Integer; Count: Integer): Integer; overload;
  function IndexOfAny(const AnyOf: array of Char): Integer; overload;
  function IndexOfAny(const AnyOf: array of Char; StartIndex: Integer): Integer; overload;
  function IndexOfAny(const AnyOf: array of Char; StartIndex: Integer; Count: Integer): Integer; overload;
  function Insert(StartIndex: Integer; const Value: string): string;
  function IsDelimiter(const Delimiters: string; Index: Integer): Boolean;
  function IsEmpty: Boolean;
  class function IsNullOrEmpty(const Value: string): Boolean; static;
  class function IsNullOrWhiteSpace(const Value: string): Boolean; static;
  class function Join(const Separator: string; const values: array of const): string; overload; static;
  class function Join(const Separator: string; const Values: array of string): string; overload; static;
  class function Join(const Separator: string; const Values: IEnumerable): string; overload; static;
  class function Join(const Separator: string; const value: array of string; StartIndex: Integer; Count: Integer): string; overload; static;
  function LastDelimiter(const Delims: string): Integer;
  function LastIndexOf(Value: Char): Integer; overload;
  function LastIndexOf(const Value: string): Integer; overload;
  function LastIndexOf(Value: Char; StartIndex: Integer): Integer; overload;
  function LastIndexOf(const Value: string; StartIndex: Integer): Integer; overload;
  function LastIndexOf(Value: Char; StartIndex: Integer; Count: Integer): Integer; overload;
  function LastIndexOf(const Value: string; StartIndex: Integer; Count: Integer): Integer; overload;
  function LastIndexOfAny(const AnyOf: array of Char): Integer; overload;
  function LastIndexOfAny(const AnyOf: array of Char; StartIndex: Integer): Integer; overload;
  function LastIndexOfAny(const AnyOf: array of Char; StartIndex: Integer; Count: Integer): Integer; overload;
  function PadLeft(TotalWidth: Integer): string; overload; inline;
  function PadLeft(TotalWidth: Integer; PaddingChar: Char): string; overload; inline;
  function PadRight(TotalWidth: Integer): string; overload; inline;
  function PadRight(TotalWidth: Integer; PaddingChar: Char): string; overload; inline;
  function Remove(StartIndex: Integer): string; overload; inline;
  function Remove(StartIndex: Integer; Count: Integer): string; overload; inline;
  function Replace(OldChar: Char; NewChar: Char): string; overload;
  function Replace(OldChar: Char; NewChar: Char; ReplaceFlags: TReplaceFlags): string; overload;
  function Replace(const OldValue: string; const NewValue: string): string; overload;
  function Replace(const OldValue: string; const NewValue: string; ReplaceFlags: TReplaceFlags): string; overload;
  function Split(const Separator: array of Char): TArray; overload;
  function Split(const Separator: array of Char; Count: Integer): TArray; overload;
  function Split(const Separator: array of Char; Options: TStringSplitOptions): TArray; overload;
  function Split(const Separator: array of string; Options: TStringSplitOptions): TArray; overload;
  function Split(const Separator: array of Char; Count: Integer; Options: TStringSplitOptions): TArray; overload;
  function Split(const Separator: array of string; Count: Integer; Options: TStringSplitOptions): TArray; overload;
  function StartsWith(const Value: string): Boolean; overload;
  function StartsWith(const Value: string; IgnoreCase: Boolean): Boolean; overload;
  function Substring(StartIndex: Integer): string; overload;
  function Substring(StartIndex: Integer; Length: Integer): string; overload;
  function ToCharArray: TArray; overload;
  function ToCharArray(StartIndex: Integer; Length: Integer): TArray; overload;
  function ToLower: string;
  function ToLowerInvariant: string;
  function ToUpper: string;
  function ToUpperInvariant: string;
  function Trim: string; overload;
  function Trim(const TrimChars: array of Char): string; overload;
  function TrimEnd(const TrimChars: array of Char): string;
  function TrimStart(const TrimChars: array of Char): string;
  property Chars[Index: Integer]: Char read GetChars;
  property Length: Integer read GetLength;
end;

Abaixo um exemplo prático:

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

var
  s1 :string;
begin

  s1 := 'Usando TStringHelper no Delphi XE3';
  Writeln( Format('O tamanho da string é is %d',[s1.Length] ));

  Writeln(Format('Convertendo para Maiúsculo %s',[s.ToUpper]));

  //Usando a função Contains
  if s1.Contains('XE3') then
      Writeln(Format('A string "%s" contém a string "%s"',[s1,'XE3']));

  Readln;
end.

O mais importante neste novo recurso é poder extender os tipos simples, mas eu diria também que isso abre as portas para podermos utilizar os tipos primitivos (simples) como objetos, eles ainda não são, mas fique atento, pois as portas estão abertas.

A RTL ainda traz diversos outros record helpers:

  • System – TSingleHelper = record helper para Single
  • System – TDoubleHelper = record helper para Double
  • System – TExtendedHelper = record helper para Extended
  • System.Classes – TUInt32Helper = record helper para UInt32
  • System.SyncObjs – TCriticalSectionHelper = record helper para TRTLCriticalSection
  • System.SyncObjs – TConditionVariableHelper = record helper para TRTLConditionVariable
  • System.Mac.CFUtils – CFGregorianDateHelper = record helper para CFGregorianDate
  • System.SysUtils – TGuidHelper = record helper para TGUID
  • Winapi.D2D1 – D2DMatrix3x2FHelper = record helper para TD2DMatrix3X2F
  • Vcl.Themes – TElementMarginsHelper = record helper para TElementMargins

Variáveis Globais (TFormatSettings)

Vinte variáveis globais parte da System.SysUtils foram removidas (deprecated), estas variáveis são aquelas relacionadas ao formato da data, moeda, separados de decimal e milhar, etc…, para ser mais preciso algumas delas: DateSeparator, DecimalSeparator, CurrencyFormat, etc..

A partir do XE3 você terá de usar a variável System.SysUtils.FormatSettings ou criar a sua instância de TFormatSettings, todas as variáveis anteriormente globais agora são parte do TFormatSettings.

Ao compilar você receberá um erro de identificador não declarado, assim é só fazer a mudança já mencionado. Particularmente eu gosto desta mudança, variáveis globais não são uma boa prática.

Refactoring FireMonkey

Diversos tipos do FireMonkey e funções matemáticas relacionadas ao FireMonkey foram movidas para a RTL (unit System), alguns exemplos:

  • Vector passou de FMX.Types para System.Types.Vector
  • Os seguintes tipos TMatrix3D, Point3D, TQuaternion3D, TVector3D, Vector3D sairam da unit FMX.Types3D e foram para System.Types.

Novos métodos e helpers

Abaixo alguns métodos adicionados a RTL e o link para a documentação explicando cada um.

Três novos helper types (TSingleHelper,TDoubleHelper, and TExtendedHelper) que substituem os seguintes records: TSingleRec, TDoubleRec, TExtendedRec.

VCL

Além dos suporte a UI Metropolis que comentei na parte 1 das novidades do XE3, alguns refactoring aconteceram na VCL também e a razão disto é o suporte a Actions no FireMonkey, desta forma Actions agora passa a ser independente de plataforma e com isso abre a possibilidade de suportar outras plataformas futuramente.

Outra novidade é o suporte a efeitos quando você passa o mouse sobre controles da VCL, por exemplo o TBitBtn ou TButton, basta mudar a propriedade AnimationOnControls para True e seus controles irão se comportar conforme definido no estilo corrente.

Vou ficando por aqui com a segunda parte e em breve volto com a terceira e última parte do das novidades do XE3.

Até breve!!!

14 respostas
  1. Alexandre Macário
    Alexandre Macário says:

    Saudações.

    Cara você fará falta na Delphi Conference deste ano aqui em SP.

    Tem chance de você aparecer por lá dia 23.10.2012????

    Abraço.

    Responder
  2. Laercio Guerço Rodrigues
    Laercio Guerço Rodrigues says:

    Estou um pouco confuso com relação ao suporte a desenvolvimento para iPhone e iOS. XE3 tem suporte total, ou será complementado em relese desta mesma versão em futuro próximo?

    Ainda com relação a este possível relese, poderemos desenvolver e compilar para Android diretamente?

    Abraços…

    Responder
    • Andreano Lanusse
      Andreano Lanusse says:

      @Laercio, o XE3 não tem suporte, a Embarcadero está prometendo para o 1o semestre do ano que vem o suporte completo a iOS e Android. Por agora para fazer algo para iOS você tem que usar o XE2

      Responder
  3. Leandro
    Leandro says:

    Olá Andreano, você faz muita falta a comunidade Delphi, parabéns pelo post.
    Gostaria de ver um post seu sobre as alterações no LiveBinds Delphi XE3, sinto muita falta de material na internet, principalmente na area de OO, sendo que o Delphi evoluiu muito nessa area.

    Abraço.

    Responder
  4. Julio
    Julio says:

    Ainda bem que ainda temos o seu blog Andreano, sempre muito bom. Esses MVP da Embarcadero só sabem fazer propaganda, se juntor os MVP do Brasil não dá um de você.

    Responder
  5. walter carvalho
    walter carvalho says:

    quando vamos no servidor web proprio que aquele ta l de asp é um nojo, android e executavel multportsbilidade porque o delphi ta ntrando em desuso e se cntinuar assim ai virar cobol

    Responder
  6. thiago farias
    thiago farias says:

    Olá, Andreano.

    Adorei seu blog e, ao meu ver, é o mais claro…Entretanto, estou com uma dúvida. Sou um leigo em programação, mas etou para começar a aprender afim de melhorar meu trabalho com dados financeiros. Gostaria de saber sua opnião sobre qual o melhor programa e mais completo para um iniciante: o Delphi XE2 ou XE 3?

    Espero retorno.

    Abraços

    Responder

Deixe uma resposta

Want to join the discussion?
Feel free to contribute!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *


Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.