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 Seguir @andreanolanusse [/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.
- InflateRect, IntersectRectF, MultiplyRect
- NormalizeRect, NormalizeRectF, UnionRectF
- RectCenter
- ScalePoint
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!!!
Como de costume o Andreano faz um excelente trabalho resumindo as coisas mais importantes
Parabens
Obrigado Ageu
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.
Olá Alexandre, obrigado pela lembrança.
Infelizmente não vai dar, estarei viajando nesta semana
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…
@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
Bem interessantes esses novos helpers.
Parabens pelo artigo Andreano !!
Ele domina muito bem o assunto
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.
@Leandro, obrigado pelas palavras.
No próximo post vou falar sobre as novidades do LiveBinding no XE3
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ê.
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
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
Thiago como você está começando melhor começar pelo que tem de mais atual, Delphi XE3 seria o caminho pra começar