Introduction

Après une première partie sur les développements qu'il est possible de faire dans vista, nous allons continuer à découvrir ce qu'il est possible de faire sous ce système d'exploitation.

1. Travailler avec les adaptateurs réseaux

Pour ceux qui connaissent bien WMI (Windows Management Instrumentation), ils doivent savoir qu'il est relativement aisé de lister les adaptateurs réseaux de la machine ainsi que les informations sur ces derniers. Dorénavant, sous Vista, il existe une API qui permet de travailler non pas sur les adaptateurs, mais directement sur les connexions. Cela permet entre autre de savoir très facilement si un ordinateur est connecté à Internet sans nécessiter de faire un PING sur un quelconque site Web.
J'ai trouvé cette astuce sur le blog de Max Knor qui décrit comment, avec une librairie système, il est possible de rendre son application "network aware".

Commencez par créer un nouveau projet pour lequel vous ajouterez une référence vers la librairie "Network List Manager 1.0 Type Library" puis ajoutez le namespace correspondant ("NETWORKLIST").

Image non disponible

Créez alors un objet NetworkListManagerClass, puis instanciez-le:

initialisation de notre objet
Sélectionnez

NetworkListManagerClass _networkListManager;
_networkListManager = new NetworkListManagerClass();

Sur cet objet nouvellement créé, il est déjà possible de connaitre le statut des connexions, pour savoir si par exemple il est possible d'accéder à Internet

 
Sélectionnez

lblReseau.Text = (_networkListManager.IsConnected) ? "Oui" : "Non";
lblInternet.Text = (_networkListManager.IsConnectedToInternet) ? "Oui" : "Non";

Mais, même si cette propriété est très importante puisque pour les applications ayant besoin de faire une mise à jour ou autre cela permet très rapidement de savoir si cela sera possible ou non, d'autres fonctionnalités se cachent au sein de cet objet.
Ainsi, nous allons voir qu'il devient facile de récupérer des informations très facilement sur les connexions de l'ordinateur. Nous allons d'abord les lister et pour cela nous allons itérer sur une collection d'objets INetworkConnection

Dans mon cas, je stocke les informations qui m'intéressent (le nom et l'id de la connexion) dans une classe interne afin de binder ma collection d'objets sur une combobox (j'aurai besoin de ces infos peu après)

on liste les connexions actuelles
Sélectionnez

List<Reseau> malist = new List<Reseau>();
foreach (INetworkConnection c in _networkListManager.GetNetworkConnections())
{
	malist.Add(new Reseau(c.GetNetwork().GetName(),c.GetConnectionId()));  
}

Enfin, implémenter l'événèment qui, une fois une connexion sélectionnée, permet de lister certaines de ses informations

Listing des informations détaillées
Sélectionnez

 private void getInfo(Guid gu)
{
    INetworkConnection c = _networkListManager.GetNetworkConnection(gu);

    lblNom.Text = c.GetNetwork().GetName();
    lblDesc.Text = c.GetNetwork().GetDescription();
    lblType.Text = c.GetNetwork().GetDomainType().ToString();
}

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    getInfo((Guid)comboBox1.SelectedValue);
}

Mon application affiche alors le résultat suivant (Note: "pharaonix" est le nom d'une connexion Wifi)

Image non disponible

Pour finir, je tiens à signaler qu'il est possible de modifier soit même les connexions en changeant leur nom, description ou même type (Privé, Public, Bureau). Des méthodes sont là pour ça:

Modification du nom de la connexion
Sélectionnez

c.GetNetwork().SetName("DVP Rox");
Image non disponible

2. Utiliser la plate-forme RSS de Windows Vista

2.1. Présentation

Au sein de Windows Vista, Microsoft a décidé d'intégrer une plateforme commune de gestion de flux RSS. Gérant aussi bien les flux RSS au format RSS 2.0 ou même ATOM 1.0, cette plateforme, "invisible", permet de centraliser l'abonnement et l'agrégation de différents flux RSS et vous donne la possibilité de l'intégrer au sein de vos applications comme le fait Internet Explorer 7.
Il est possible de faire énormément de choses avec cette plateforme RSS et vous pouvez l'utiliser de différentes manières et dans différents contextes au sein de vos applications, néanmoins, dans cette article, je me contenterai de ne présenter que les fonctionnalités basiques. Pour plus d'informations, il vous suffira de lire l'article plus complet disponible à cette adresse.

2.2. Mise en place

2.2.1. Chargement de la plateforme dans votre application

Commencez par ajouter la libraire Microsoft Feeds à votre projet puis importez la avec :

 
Sélectionnez
using Microsoft.Feeds.Interop;

Puis créez un FeedsManager, qui sera le point central de la gestion des flux RSS comme le montre la capture suivante
Image non disponible

 
Sélectionnez
FeedsManager myFMng = new FeedsManager();

2.2.2. Lecture d'un flux

La fonctionnalité que vous utiliserez à coup sûr sera la lecture d'un flux. Bien sûr, un flux RSS n'est qu'un fichier XML disponible sur Internet et il existe de nombreuses façons de le lire, mais la façon la plus simple de le faire et surtout en gérant d'un coup plusieurs formats RSS, est d'utiliser la plateforme RSS.

Comme nous l'avons vu sur le schéma précédent, l'objet FeedsManager permet de gérer des flux (Feed) qui eux, contiennent des FeedItem. Ce sont donc ces FeedItem que nous allons chercher à récupérer.

Commençons par récupérer le répertoire racine de tous les feeds possibles

 
Sélectionnez

IFeedFolder myRootFld = (IFeedFolder)myFMng.RootFolder;

Nous allons ensuite récupérer le Feed souhaité dans ce dossier (à vous de vérifier qu'il se trouve bien dans le dossier racine)

 
Sélectionnez

IFeed  myF = (IFeed)myRootFld.GetFeed(feed);

Maintenant que nous avons notre flux, il nous suffit de boucler sur ses objets sous-jacents (innertype)

 
Sélectionnez
foreach (IFeedItem fit in (IFeedsEnum)myF.Items)
{
    // à vous de mettre le traitement de votre choix sur les items
    ListViewItem lvi = new ListViewItem(fit.Title);
    lvi.SubItems.Add(fit.Author);
    lvi.SubItems.Add(fit.PubDate.ToShortDateString());
    listView2.Items.Add(lvi);
    listView2.Items[listView2.Items.Count - 1].BackColor = 
	                 (listView2.Items.Count % 2 == 0) ? Color.Gainsboro : Color.White;
}

Et c'est tout. Lire des flux RSS d'un site web se résume à trois lignes de code, là où il fallait avant un XMLDocument et des règles de parsing différentes selon le format du flux RSS. Pensez donc à ces quelques lignes de code le jour où vous souhaitez lire un flux RSS.

2.2.3. Abonnement à un flux

Nous avons vu avant comment lire les billets des flux déjà enregistrés (souvent via Internet Explorer 7), nous allons maintenant voir comment ajouter de nouveaux flux. Pour vous abonner à un flux, rien de plus simple. Tout d'abord, pour éviter une exception de la part de la plateforme, vous allez vérifier que l'URL du flux n'est pas déjà enregistrée.

 
Sélectionnez
if (!myFMng.IsSubscribed("http://dotnet.developpez.com/rss.php"))
{
 // code d'abonnement
}

Puis, avez une seule ligne de code, vous allez enregistrer votre flux

 
Sélectionnez
   (myRootFld.CreateFeed("rubrique Dotnet", "http://dotnet.developpez.com/rss.php");

Avec cette simple ligne de code, vous vous assurez que le flux est bien gardé dans la plateforme et que celle-ci sera en mesure de vous indiquer quand ce flux a été mis à jour. Elle fait tout, toute seule.

2.3. Pour aller plus loin

Si vous souhaitez avoir un article plus complet sur l'intégration des RSS au sein de vos applications .Net alors vous pouvez visiter le lien suivant.

3. Interagir avec Windows Desktop Search

Windows Desktop Search est le système d'indexation de Microsoft qui, une fois intégré au système permet de retrouver rapidement tout type de fichier. Si Windows Desktop Search existe sous plusieurs versions, il est surtout par défaut installé sur Windows Vista. Il peut alors être très intéressant d'interroger l'index au sein de vos applications et de l'utiliser sous la forme qui vous arrange le plus.

La méthode la plus simple pour interroger une source de données en .Net reste l'utilisation d'ADO.Net. C'est non seulement la plus simple mais aussi la plus couramment utilisée. Avec Windows Desktop Search, nous ne dérogerons pas à la règle et nous n'aurons que deux petites choses sur lesquelles faire attention.
Tout d'abord en choisissant un provider adapté : il s'agit du provider OleDb, et ensuite en spécifiant une chaine de connexion particulière pour nous permettre d'interroger le gestionnaire de l'indexation de Windows Desktop Search. La chaine de connexion est particulière à WDS et reste simple: "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"

Commençons par créer notre connexion puis par l'ouvrir

 
Sélectionnez
OleDbConnection connection = new OleDbConnection("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';");
connection.Open();

Puis déclarons notre objet OleDbCommand qui représentera notre requête auprès de l'index

 
Sélectionnez
var command = new OleDbCommand {Connection = connection, CommandText = "ma requete"};

Note: notez que le code précédent provient de C# 3.0 et utilise le mot-clé var ainsi que les nouveaux initialiseurs d'objets. En 2.0, il correspondrait à

 
Sélectionnez
OleDbCommand co = new OleDbCommand();
co.Connection = connection;
co.CommandText = "ma requete";

Et enfin le code de lecture du résultat

 
Sélectionnez
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
    // traitement de votre choix sur les résultats retournés
    // exemple MessageBox.Show(reader.GetString(0));
}
reader.Close();

Cela n'est pas plus complexe que cela, et il est ainsi possible d'afficher très rapidement les informations de fichiers retrouvés via WDS à condition bien entendu que la requête soit correcte.

Windows Desktop Search est tout sauf bavard et en cas d'exception ne vous attendez pas à trouver rapidement la source du problème. Par exemple, si l'une des informations demandées (nom de colonne) était erronée, il vous renverrait une exception avec pour seul texte : E_FAIL(0x80004005). Pensez donc à vérifier les noms des colonnes lorsque vous avez cette erreur. La difficulté étant de connaitre ces noms de colonnes puisque malheureusement, d'une version à l'autre de Windows Desktop Search, celles-ci changent...

Voici donc un exemple complet de recherche

 
Sélectionnez
OleDbConnection connection = new OleDbConnection("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';");
connection.Open();
var command = new OleDbCommand { Connection = connection, 
CommandText = String.Format("SELECT Top 5  System.ItemUrle, System.ItemName,System.Title 
                             FROM systemindex WHERE CONTAINS(\"System.FileName\", '\"*{0}*\"')", "plage") };
OleDbDataReader reader = command.ExecuteReader();
lsvSearch1.Items.Clear();
while (reader.Read())
{
    lsvSearch1.Items.Add(new ListViewItem(new[] { reader.GetString(0) }));
}
reader.Close();

Il ne s'agit ici que d'une explication rapide de l'utilisation de Windows Desktop Search. Si vous voulez plus d'informations, lisez l'article suivant.

4. Amélioration des interfaces graphiques

Comme pour la première partie, nous allons finir par présenter des améliorations graphiques qu'il est possible d'ajouter à vos applications.

4.1. Modifier les progressBar

C'est en trainant sur des forums anglophones que je suis tombé sur un thread où l'une des personnes disait qu'il existait des progressbar de plusieurs couleurs sous Windows Vista. C'est en fouillant sur la MSDN que j'ai trouvé qu'il était possible de définir trois états à une progressbar. Sur ce lien, il y est justement expliqué comment, à l'aide de l'API SendMessage, il était possible d'envoyer un état à une progressbar.
Suivons alors les instructions pour importer la méthode SendMessage http://msdn2.microsoft.com/en-us/library/bb760850.aspx http://www.codeproject.com/vista/themedvistacontrols.asp

Import de la méthode SendMessage
Sélectionnez

DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern uint SendMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);

Plaçons alors trois progressBar sur un formulaire de test. Puis en cherchant en peu sur Internet, nous trouvons les valeurs des constantes nécessaires. En effet, ces valeurs se trouvent normalement dans le fichier commctrl.h qui peut être trouvé dans le SDK de Vista

Envoi de message au controle progressBar
Sélectionnez

const int WM_USER = 0x400;
const int PBM_SETSTATE = WM_USER + 16;
const int PBST_NORMAL = 0x0001;
const int PBST_ERROR = 0x0002;
const int PBST_PAUSED = 0x0003;
SendMessage(progressBar2.Handle,
            PBM_SETSTATE,
            PBST_PAUSED, // pause
            0);

SendMessage(progressBar3.Handle,
              PBM_SETSTATE,
              PBST_ERROR, // erreur
              0);

Dans le code précédent, nous mettons notre deuxième progressBar en pause tandis que nous envoyons le statut erreur à la troisème progressBar. Ceci nous donne alors trois progressBar dont les deux dernières sont immobiles mais surtout d'une couleurs différentes.

Image non disponible



Ainsi donc, il est possible d'avoir des progressBar de différentes couleurs mais avec ces méthodes, il s'agit surtout de représenter l'état d'une action de votre application via la couleur de la progressBar.

4.2. Intégrer le comportement de Vista dans vos treeview

Il est ici d'une modification fonctionnelle du Treeview plus qu'une modification visuelle. En effet, si vous avez déjà regardé le treeview de l'explorateur Windows de Vista, vous auriez remarqué deux choses:
- le thème Vista : surlignement bleutée, petites flèches en lieu et places des + et - habituels.
- un scrolling horizontal automatique. Lorsque vous choisissez un nœud enfant dont le nom n'apparait pas complètement, le treeview scroll vers la droite pour aligne le début du nœud

Il est donc ici une fois de plus question d'amélioration de "l'expérience utilisateur" et de rendre votre application encore un peu plus facile d'utilisation

Image non disponible
Explorateur Vista

Commençons par importer l'API SendMessage:

Méthode SendMessage
Sélectionnez
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern uint SendMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);

Nous allons devoir utiliser deux commandes différentes pour gérer à la fois le scroll automatique mais également le thème Vista.

Ajout du scroll automatique
Sélectionnez

const int TVM_SETEXTENDEDSTYLE = TV_FIRST + 44;
const int TVS_EX_AUTOHSCROLL = 0x0020;
SendMessage(treeView1.Handle, TVM_SETEXTENDEDSTYLE, 0, TVS_EX_AUTOHSCROLL);

Et pour le style Vista:

Ajout du thème Vista
Sélectionnez

SetWindowTheme(treeView1.Handle, "explorer", null);

Ce genre de petite amélioration peut sembler superflue à première vue, mais un bon développeur ne doit pas perdre de vue que c'est en rajoutant de petites améliorations qu'il rendra son application plus "parfaite" aux yeux des utilisateurs.
Voici la différence entre un composant TreeView avec le thème Vista (gauche) et le composant ne l'ayant pas.

Image non disponible

4.3. Utilisez le bouton Command Link dans vos applications

Après avoir vu comment ajouter un bouclier sur vos boutons dans la première partie, nous allons voir comment implémenter les "Command link" boutons que vous pouvez trouver au sein de Windows Vista. En voici un exemple.

Un bouton "Command link" se distingue par trois choses:
- une image d'une flèche
- un texte principal
- un second texte plus petit se trouvant sous le texte principal

Image non disponible

A l'inverse des autres modifications de composants, il est nécessaire ici de recréer une classe complète héritant du contrôle Bouton et dans laquelle nous devrons surcharger et redéfinir certaines méthodes comme par exemple la méthode CreateParams. Plutôt que vous embêtez à coder cette classe, j'ai déniché sur le net une classe toute faite, écrite par Max Knor et qui publie le code a cette adresse. Importez donc cette classe dans votre application puis créer le code qui ajoutera un bouton à l'endroit voulu.
Dans mon exemple, je vais créer deux commandLink buttons que je placerai dans l'un des onglets de mon application de démonstration

 
Sélectionnez

CommandLink btn = new CommandLink();
btn.Note = "sa description";
btn.Text = "ma commande";
tabControl1.TabPages[2].Controls.Add(btn);
btn.Top = 10;
btn.Left = 30;
btn.Cursor = Cursors.Hand;

CommandLink btn2 = new CommandLink();
btn2.Note = "test";
btn2.Text = "ma commande2";
tabControl1.TabPages[2].Controls.Add(btn2);
btn2.Top = 80;
btn2.Left = 30;
btn2.Cursor = Cursors.Hand;

Ce petit bout de code, aussi simple que si vous utilisiez un composant normal, vous permet de placer le bouton puis d'éditer ses propriétés en mode Design.

Image non disponible