I. Introduction▲
Delphi 2009 avait frappé fort en proposant de nombreuses nouveautés techniques (Unicode, génériques, méthodes anonymes, etc.).
Cette année, l'équipe de CodeGear a décidé d'améliorer un ensemble de petits points, un peu à la manière d'un tisserand (Weaver en anglais, le nom de code de Delphi 2010) qui assemblerait les petites mailles pour former la belle robe.
Deux axes majeurs peuvent se tracer : le souhait de répondre aux attentes de ses utilisateurs (représenté par de nombreux ajouts dans l'EDI, corrections de bogues, etc.) et la préparation vers l'avenir (comme le framework de Gesturing, le mot clé delayed, etc.).
Un bémol cependant, car la compatibilité 64 bits (projet Commodore) ainsi que le cross-platform (projet X) n'ont pas pu être intégrés à cette version.
Voici l'EDI tel qu'il apparaît en standard :
Beaucoup d'utilisateurs ont toujours été frileux d'abandonner leur Delphi 7, notamment à cause de l'interface. Delphi 2010 se veut être la version de la réconciliation puisque l'utilisateur peut personnaliser l'EDI pour qu'il ressemble un maximum à ce qui se faisait sous Delphi 7 comme le montre ce bureau remanié par mes soins :
II. Nouveautés dans l'EDI▲
Nous allons maintenant présenter les différentes nouveautés de l'EDI.
II-A. IDE Insight▲
La plus importante des nouveautés, l'IDE Insight est la fonctionnalité qui répond à la problématique : « j'ai le nom d'un truc, mais je ne sais plus où c'est ».
En clair, appuyez sur F6 et rentrez le nom (même partiellement) et Delphi se charge de retrouver tout ce qui pourrait correspondre.
De nombreuses informations présentes dans l'EDI sont analysées ce qui comprend : les actions menus, les fichiers projets, les composants sur la palette, les modèles de code et même les options de l'EDI ou du projet.
II-B. Formateur de code▲
Jusqu'à présent, le formatage de code a toujours été assuré par un plugin externe. Aujourd'hui c'est terminé, l'EDI se dote enfin d'un formateur de code en standard, complètement personnalisable. Un petit coup de CTRL+ALT+F et votre code est formaté.
II-C. Recherche intégrée▲
La recherche à l'intérieur d'un fichier est maintenant intégrée à la fenêtre d'édition de code comme le montre la capture ci-dessous :
Bien sûr la recherche multifichier est toujours disponible, il faut maintenant utiliser le raccourci CTRL+SHIFT+F.
II-D. Palette des composants▲
Une des grandes différences entre Delphi 7 et les versions supérieures fut de faire passer la palette des composants horizontale vers une fenêtre indépendante « verticale ». Ce changement d'interface ayant même été un critère pour ne pas passer à une version plus évoluée de Delphi pour certains utilisateurs. Avec Delphi 2010, la palette horizontale fait son grand retour en plus du système « vertical » afin de contenter tout le monde.
Absente par défaut, il suffit de faire un clic droit sur la barre principale de l'EDI et de cocher « Composants » pour faire apparaître la fameuse barre horizontale.
II-E. Explorateur de classes pour C++ Builder▲
L'explorateur de classes de C++ Builder a été complètement réécrit pour correspondre aux attentes des utilisateurs.
La fenêtre présente la liste complète de toutes les classes avec possibilité de les grouper de différentes façons et même de créer et sauvegarder vos propres groupes.
En cliquant sur un élément, vous avez la possibilité d'aller voir sa définition ou bien les endroits où il est utilisé.
Enfin le clic droit vous permet d'effectuer différentes actions, dont l'ajout de champs, méthodes et propriétés à votre classe.
III. Débogueur▲
Cette section va vous présenter les nouveautés apportées au débogueur.
III-A. Déboguer les threads▲
L'une des nouveautés phares concernant le débogueur est sa capacité à maintenant déboguer plus efficacement les threads.
En effet comme le montre la capture ci-dessous, il est maintenant possible de rattacher un point d'arrêt à un thread particulier.
La liste des threads disponibles évolue au fur et à mesure que le programme instancie et termine des threads.
Attention cependant, par défaut sera affiché l'id du thread qui, par nature, changera d'une instanciation à l'autre. Néanmoins vous pouvez associer un nom de débogage à un thread au moyen de la nouvelle méthode NameThreadForDebugging. Il est bien sûr hautement conseillé de le faire.
En effet le lien entre un point d'arrêt et un thread est matérialisé par une simple chaîne (id ou nom de débogage) qui est conservée dans le paramétrage du point d'arrêt d'une exécution à l'autre. De fait, si votre thread porte le même nom de débogage, le point d'arrêt se « souvient » de ne s'arrêter que pour ce thread en particulier à chaque exécution.
Il est également possible de visualiser l'ensemble des threads de l'application et surtout de pouvoir les figer et les libérer à volonté si vous ne voulez voir l'exécution que de quelques threads en particulier.
L'appel à NameThreadForDebugging peut se faire à n'importe quel moment, vous pouvez même l'appeler de l'extérieur du thread.
Néanmoins gardez en mémoire que tant que la méthode ne sera pas appelée vous ne pourrez voir que l'id du thread au niveau du débogueur. Le mieux étant donc de l'appeler au niveau du constructeur ou bien de la méthode Execute du thread.
III-B. Visualiseurs▲
Le débogueur se dote de visualiseurs qui lui permettent d'afficher l'élément inspecté de manière plus efficace.
Pour le moment il n'existe que deux visualiseurs : pour les TStrings et les TDateTime.
Il est possible de rajouter des visualiseurs personnalisés à l'EDI via les API Open Tools.
IV. RTTI▲
Le système de RTTI a été complètement révisé et apporte son lot de nouveautés comme les attributs. Voyons cela plus en détail.
IV-A. Extensions des possibilités▲
Une nouvelle unité, RTTI.pas, a fait son apparition et contient toutes les fonctionnalités liées au RTTI. Rassurez-vous TypInfo.pas est toujours là et ses routines n'ont pas bougé de place, car le nouveau système utilise désormais comme point d'entrée un record : le TRttiContext.
Le nombre de choses couvertes par les RTTI a sensiblement augmenté, mais surtout il n'est plus obligatoire que les éléments soient déclarés en publié.
Via le TRttiContext on peut maintenant avoir accès à toutes les propriétés, champs, méthodes, mais aussi les classes parentes et même les packages où est définie la classe.
Le nouveau système apporte aussi beaucoup de possibilités de recherche par nom des différents éléments plutôt que de faire les parcours nous-même.
IV-B. Les attributs▲
Un attribut est conceptuellement une sorte d'annotation que le développeur ajoute au niveau de la déclaration d'une classe, d'une méthode ou d'une propriété.
On peut ensuite y accéder au moment de l'exécution via le nouveau système de RTTI.
Voici comment procéder.
IV-B-1. Déclaration d'un attribut▲
Un attribut est une classe qui doit hériter de la classe de base TCustomAttribute et doit se terminer par 'Attribute'. Par exemple :
TFieldAliasAttribute = class
(TCustomAttribute)
private
FAliasName: String
;
public
Constructor
Create( const
AAliasName: String
);
property
AliasName: String
read
FAliasName;
end
;
Ses propriétés ne peuvent être que des types simples, pas d'objet ou de record.
IV-B-2. Affectation d'un attribut▲
Un attribut s'ajoute au niveau d'une classe, d'une méthode ou d'une propriété de la manière suivante (ici pour une propriété) :
TEntity = class
(TObject)
private
FID: Integer
;
FEntCode: String
;
published
[TFieldAlias('ID'
)]
property
ID: Integer
read
FID write
FID;
[TFieldAlias('CODE'
)]
property
EntCode: String
read
FEntCode write
FEntCode;
end
;
Notez que le nom de l'attribut ici doit correspondre au nom de la classe que vous avez déclarée sans le 'Attribute'.
Notez enfin que les paramètres attendus sont ceux du ou des constructeurs de la classe d'attribut.
IV-B-3. Récupération des attributs via RTTI▲
Voici un exemple complet permettant de récupérer les « AliasName » de n'importe quel objet :
procedure
ShowAliasesNames(AEnt: TObject);
var
Context: TRttiContext;
Rtti: TRttiType;
Props: TArray<TRttiProperty>;
Prop: TRttiProperty;
PropAttrs: TArray<TCustomAttribute>;
PropAttr: TCustomAttribute;
begin
Context := TRttiContext.Create;
try
Rtti := Context.GetType(AEnt.ClassInfo);
Props := Rtti.GetProperties;
for
Prop in
Props do
begin
PropAttrs := Prop.GetAttributes;
for
PropAttr in
PropAttrs do
if
PropAttr is
TFieldAliasAttribute then
ShowMessageFmt('Nom de la propriété : %s, nom de l''alias : %s'
, [Prop.Name, TFieldAliasAttribute(PropAttr).AliasName]);
end
;
finally
Context.Free;
end
;
end
;
V. Le nouveau framework de Gesturing▲
Le Gesturing (mouvement en français) traité ici est en rapport avec la reconnaissance et la réaction aux mouvements de l'utilisateur, que ce soit à la souris ou sur un écran tactile.
Ainsi, en plus du clic et de la molette, l'utilisateur a maintenant la possibilité de donner des ordres à l'application en effectuant certains mouvements précis.
V-A. Le composant TGestureManager▲
Le TGestureManager est le composant non visuel sur lequel repose toute la mise en place du Gesturing.
Vu que la réponse à un mouvement doit passer par l'intermédiaire d'un TAction, vous aurez besoin de déposer également un TActionList sur votre fiche.
Par défaut vous avez accès aux 34 mouvements préenregistrés standards (glissement droit ou gauche, carré, cercle, triangle, chevron, etc.), mais vous pourrez également définir vos propres mouvements par l'intermédiaire du TGestureManager. Nous aborderons ce point dans la suite de l'article.
V-B. La propriété Touch▲
Une nouvelle propriété a fait son apparition au niveau de TControl : Touch, c'est grâce à elle que vous allez pouvoir configurer les contrôles pour qu'ils puissent répondre aux mouvements de l'utilisateur.
La première des choses à faire est donc de renseigner le TGestureManager au niveau de la sous-propriété GestureManager, ensuite pour chaque mouvement à prendre en charge affectez un TAction qui répondra lorsque l'utilisateur reproduira le mouvement. Les actions sont accessibles via la sous-propriété Gestures.
Touch définit également d'autres sous-propriétés de configuration qui n'auront de sens que si le programme tourne sur un matériel vraiment tactile plutôt qu'un PC standard.
V-C. Exemple d'implémentation▲
Imaginons une application simple affichant une image, lorsque l'utilisateur fait un mouvement vers la droite ou vers la gauche alors l'image suivante ou précédente s'affichera.
Nous déposons donc un TGestureManager, un TActionList, un TImageList contenant les différentes images et un TImage pour l'affichage.
Ne mettez pas le TImage en align client. Nous allons uniquement configurer le Gesturing sur le TImage afin de montrer que seul ce composant réagit aux mouvements utilisateurs, et non l'ensemble de l'application.
Après avoir assigné le TGestureManager à la propriété Touch du TImage, nous ajoutons une action pour les mouvements standards left et right
Côté code nous avons simplement les choses suivantes :
// utilitaire pour dessiner l'image courante sur le TImage
procedure
TForm1.DrawImage(const
Index
: Integer
);
begin
ImageList1.Draw(image1.Canvas, 0
, 0
, Index
);
Image1.Refresh;
end
;
// initialisations
procedure
TForm1.FormCreate(Sender: TObject);
begin
FIndexCourant := 0
;
DrawImage(FIndexCourant);
end
;
// l'utilisateur fait un mouvement gauche, passer à l'image précédente dans le TImageList
procedure
TForm1.SwingLeftExecute(Sender: TObject);
begin
if
FIndexCourant > 0
then
begin
Dec(FIndexCourant);
DrawImage(FIndexCourant);
end
;
end
;
// l'utilisateur fait un mouvement droit, passer à l'image suivante dans le TImageList
procedure
TForm1.SwingRightExecute(Sender: TObject);
begin
if
(FIndexCourant + 1
) < ImageList1.Count then
begin
Inc(FIndexCourant);
DrawImage(FIndexCourant);
end
;
end
;
Compilez et exécutez. Positionnez la souris sur le TImage, faites un clic droit, restez appuyé et déplacez un peu la souris horizontalement vers la droite puis relâchez. L'image devrait passer à la suivante.
Répétez le mouvement, mais cette fois-ci vers la gauche. C'est l'image précédente qui devrait s'afficher.
V-D. Mouvements personnalisés▲
Le TGestureManager vous permet également de concevoir vos propres évènements personnalisés. Pour cela, double-cliquez sur le composant pour activer l'expert vous permettant d'ajouter des mouvements.
La création d'un mouvement se fait assez aisément. Cliquez sur « enregistrer un mouvement » puis dessinez le mouvement que devra suivre l'utilisateur à la souris.
Attention à ne pas créer de mouvement qui ressemblerait de trop près à un déjà existant. En effet si deux mouvements sont trop proches, le système aura du mal à distinguer qui est qui lorsque l'utilisateur fera son mouvement et risque de rediriger vers le mauvais gestionnaire de mouvements ou aucun.
Lorsque vous avez fini d'enregistrer votre mouvement, l'expert vous indiquera le cas échéant les conflits qu'il détecte et le pourcentage de similitude.
Pour utiliser votre nouveau mouvement, il suffit de procéder comme avant, la seule différence est qu'au niveau de la sous-propriété Gestures il faut chercher votre mouvement sous « Custom » et non sous « Standard ».
VI. Base de données▲
Dans cette section nous allons voir tout ce qui a été amélioré concernant les bases de données.
VI-A. Mise à jour de dbExpress▲
Les pilotes de dbExpress ont été mis à jour pour inclure de nouveaux SGBD. Sont maintenant supportés :
- Firebird 1.5 et 2.1 ;
- InterBase 2009 ;
- Microsoft SQL Server 2008 ;
- MySQL 5.1 ;
- Oracle 11g ;
- Tous les autres SGBD précédemment supportés.
VI-B. MIDAS.dll▲
Le code source de MIDAS (en C++) a été rendu public dans cette version. Vous pouvez le trouver dans {$BDS}\source\db\midas.
VI-C. DataSnap▲
DataSnap, pour ceux qui l'ignorent, est un framework de composants permettant la communication n-tiers entre une base de données et un ou plusieurs applicatifs, pas forcement en Delphi.
Avec D2009, DataSnap avait opéré un gros changement en délaissant son architecture COM au profit d'une implémentation basée sur TCP/IP avec Indy.
Avec D2010, DataSnap permet maintenant de choisir comme protocole de transport HTTP et HTTPS. Le serveur supporte aussi l'architecture REST et peut retourner des flux JSON.
De plus l'on peut maintenant ajouter des filtres au niveau des flux de données échangés afin de compresser ou crypter les données par exemple.
Les CallBacks entre clients et serveurs sont dorénavant possibles également.
Comme dit précédemment, DataSnap permet de renvoyer des flux JSON. Tous les outils de sérialisation/désérialisation de ce format se trouvent dans l'unité DBXJSON.pas si par hasard vous en aviez besoin.
VII. Les autres nouveautés du langage▲
Ici nous verrons tout ce que Delphi 2010 apporte comme autre nouveauté au langage.
VII-A. Support des images étendu▲
En plus des formats jusqu'à présent supportés viennent maintenant s'ajouter le TIFF ainsi que le WICWindows Imaging Component. De plus la transparence alpha pour les PNG et les BMP est également supportée.
Pour ce qui est des WIC, une nouvelle unité WinCodec.pas a fait son apparition pour sa gestion.
WIC est implanté dans Windows à partir de XP SP3, Vista et plus récent. Pour les autres systèmes, vous devez prévoir son installation depuis le site de Microsoft (gratuitement).
VII-B. Nouvelle directive delayed▲
Avec le mot clé external il est possible de lier l'exécutable avec des routines d'une DLL. Ces liaisons sont effectuées avant le démarrage du programme en lui-même cependant si la DLL ou la routine en question n'existe pas sur le système alors l'application crashe inévitablement et ce avant même que le développeur ait la main pour agir.
C'est pour rendre la gestion des liaisons plus souple que la directive delayed est maintenant disponible. Une routine déclarée avec cette directive n'est maintenant liée qu'au moment de son appel.
De fait le développeur peut maintenant prendre des précautions avant de lancer l'appel par exemple :
if
OSVersion=WINDOWS_7 then
CloseTouchInputHandle
else
MyInternalSimplerClose;
On pourra noter que le nouveau framework de Gesturing tire profit de cette nouvelle directive. Ainsi, sous Windows 7, le framework utilise les API de Gesturing propres à ce Système d'Exploitation (SE) tandis que sous les autres SE le framework utilise le moteur développé par CodeGear.
VII-C. Localisation▲
Tous les descendants de TWinControl traitent à présent le message WM_INPUTLANGCHANGE qui notifie l'application que l'utilisateur vient de changer la langue du bureau.
De fait le composant qui intercepte ce message renvoie à tous les autres un message CM_INPUTLANGCHANGE que vous pouvez implémenter dans votre composant pour qu'il réagisse au changement de langue.
procedure
CMInputLangChange(var
Message
: TMessage); message
CM_INPUTLANGCHANGE;
Le paramètre LParam du message contient le Language Identifier que l'utilisateur vient de choisir.
Vous pouvez récupérer l'identifiant de langue primaire et secondaire via les routines PRIMARYLANGID et SUBLANGID. Les constantes correspondantes de langue primaire (LANG_XXX) et secondaire (SUBLANG_XXX) sont déclarées dans windows.pas.
Pour plus d'informations sur les Language Identifier vous pouvez consulter cet article sur la MSDN. Pour consulter la liste des constantes de langues, regardez cet article.
Notez enfin que l'unité SysUtils se dote d'une nouvelle classe TLanguages qui permet de récupérer une chaîne de caractères représentant la langue, mais attention elle fonctionne avec des Locale Identifier ce qui est différent des Language Identifier. Consultez cet article pour plus de détails sur la différence entre les deux.
procedure
TForm1.CMInputLangChange(var
Message
: TMessage);
var
LangId, ASubLangID: Word
;
begin
LangId := PRIMARYLANGID(Message
.LParam);
ASubLangID := SUBLANGID(Message
.LParam);
ShowMessageFmt('%d_%d'
, [LangId, ASubLangID]);
ShowMessage(Languages.NameFromLocaleID[MAKELCID(Message
.LParam, SORT_DEFAULT)]);
end
;
VII-D. TTouchKeyboard▲
Le TTouchKeyboard est un composant qui joue le rôle de clavier virtuel. L'appui sur une touche renvoie la touche vers le composant actif sans que ce dernier ne perde le focus.
Notez que le clavier change suivant que vous changez la langue du système. Il est également possible de configurer le composant pour qu'il n'affiche que le pavé numérique.
Bien sûr on pourrait s'interroger sur l'intérêt d'un clavier virtuel dans une application. Déployé sur un PC normal aucun, mais si vous l'imaginez déployé sur un mobile, un Tablet PC ou même une borne tactile l'intérêt d'un tel clavier devient tout de suite évident.
Ceci, comme le framework de Gesture est bien sûr là pour poser les bases de l'avenir.
VII-E. Transtyper une interface vers sa classe d'implémentation▲
Les opérateurs is et as sont maintenant possibles pour transtyper une interface vers la classe qui l'implémente. Par exemple :
type
IMonInteface = interface
procedure
Toto;
end
;
TMaClasse = class
(TInterfacedObject, IMonInteface)
procedure
Toto;
procedure
Titi;
end
;
procedure
FaisQuelqueChose(AMonInterface: IMonInteface);
begin
if
AMonInterface is
TMaClasse then
TMaClasse(AMonInterface).Titi;
end
;
VII-F. Autres nouvelles unités et traductions de header▲
Ici nous verrons brièvement les nouvelles unités présentes dans Delphi 2010 ainsi que les traductions de header incluses.
- Direct2D.pas : contient le TDirect2DCanvas qui implémente les Microsoft Direct2D API. Malheureusement cette implémentation ne fonctionne que sous Windows 7, là où ces API existent.
- DirectX : les derniers headers ont été inclus dans les unités Direct3D.pas, D3DX9.pas et D2D1.pas
- Manipulations.pas : Traduction des headers pour les technologies de manipulation et inertie de Windows Touch.
- IOUtils.pas : définit les classes utilitaires TDirectory, TPath et TFile
VIII. Informations et téléchargements▲
Si vous souhaitez télécharger la version architecte entièrement fonctionnelle pendant 30 jours, vous pouvez vous rendre sur le site de téléchargement de CodeGear :
Télécharger la trial de delphi 2010
Bien que la page de téléchargement soit en anglais, Delphi 2010 Trial est bien en français.
En complément d'information, vous pouvez consulter la fiche technique en anglais de Delphi 2010 :
CodeGear Delphi 2010 Fiche Technique
Comparez les caractéristiques des différentes versions Architecte, Entreprise et Professionnelle afin de mieux guider votre choix sur la version qui vous convient :
CodeGear Delphi 2010 matrice des fonctionnalités
Retrouvez toutes les vidéos et les billets blogs parlant du nouveau Delphi 2010.
IX. Remerciements▲
Je tenais à remercier Ero-sennin, Laurent Dardenne, Franck Soriano, Evarisnea, Pedro et Nono40 pour leur relecture et leurs conseils avisés.