giovedì 30 dicembre 2010

Creare uno shortcut con VB.NET

Prendendo spunto da un post comparso sul forum MSDN vorrei proporvi un tip su come creare uno shortcut utilizzando VB.NET.

Per poter creare uno shortcut possiamo procedere in due modi: o ci studiamo la struttura del file .lnk e scriviamo una classe che è in grado di ricreare tale struttura oppure utilizziamo Windows Scripting Host.

La prima soluzione è percorribile ma laboriosa perchè la struttura di un file lnk non è banale. Chi fosse interessato a vedere come è composto, internamente, un file lnk può scaricare la seguente reference guide (link).

Io vorrei proporvi la seconda strada e realizzerò una classe che incapsula l’utilizzo di Windows Scripting Host.

L’object model di Windows Scripting Host è contenuto nella dll IWshRuntimeLibrary che può essere referenziata, nel nostro progetto, utilizzando il tab COM della finestra di aggiunta delle reference:

image

Tra gli oggetti che troviamo all’interno della libreria utilizzeremo la classe WshShell e la classe WshShortcut.

La prima delle due rappresenta la vera e propria shell di Windows Scripting Host e, tra i tanti metodi messi a disposizione, ha il metodo CreateShortcut() che prevede come argomento il nome dello shortcut completo di path ed estensione e restituisce un oggetto di classe WshShortcut o di classe WshUrlShortcut (in realtà il metodo, essendo COM, restituisce un object ma possiamo castare il risultato alla classe WshShortcut o WshUrlShortcut a nostro piacimento).

La chiamata al metodo CreateShortcut non crea fisicamente il link ma tale link è creato utilizzando l’oggetto restituito dal metodo. Per maggiori info sulla classe WshShell fare riferimento al seguente link.

L’oggetto WshShortcut rappresenta, quindi, un link (il WshUrlShortcut, di fatto, ha un sottoinsieme di proprietà del WshShortcut ed è pensato per il link web) e mette a disposizione tutte quelle proprietà che ci servono per definire il link stesso (ad esempio l’icona, la directory di lavoro, la descrizione, etc., etc.). Per maggiori info sulla classe WshShortcut fare riferimento al seguente link.

La classe che vogliamo realizzare prevede una serie di proprietà per la definizione dello shortcut e un metodo per il salvataggio dello stesso (in maniera del tutto analoga a quanto fa la WshShortcut) e incapsulerà l’utilizzo delle due precedenti classi di scripting.

  1. Imports IWshRuntimeLibrary
  2.  
  3. Public Class Shortcut
  4.  
  5.     Public Sub New(ByVal shortcutFullName As String)
  6.         Me.ShortcutFullName = shortcutFullName
  7.     End Sub
  8.  
  9.     Private _ShortcutFullName As String
  10.     Public Property ShortcutFullName As String
  11.         Get
  12.             Return _ShortcutFullName
  13.         End Get
  14.         Set(ByVal value As String)
  15.             If String.IsNullOrWhiteSpace(value) Then Throw New ArgumentNullException("ShortcutFullName", "ShortcutFullName non può essere vuoto!")
  16.             _ShortcutFullName = value
  17.         End Set
  18.     End Property
  19.  
  20.     Public Property TargetPath As String
  21.     Public Property WindowStyle As ShortcutWindowsStyle = ShortcutWindowsStyle.NormalFocus
  22.     Public Property Hotkey As String
  23.     Public Property IconPath As String
  24.     Public Property IconIndex As Int16 = 0
  25.     Public Property Description As String
  26.     Public Property WorkingDirectory As String
  27.     Public Property Arguments As String
  28.  
  29.     Public Function Save() As Boolean
  30.         Dim retval = False
  31.         Dim shortCut As IWshShortcut = Nothing
  32.         Dim shell As WshShell = Nothing
  33.         Try
  34.             shell = New WshShell()
  35.         Catch ex As Exception
  36.             Throw
  37.         End Try
  38.         If shell IsNot Nothing Then
  39.             Try
  40.                 shortCut = CType(shell.CreateShortcut(Me.ShortcutFullName), IWshShortcut)
  41.             Catch ex As Exception
  42.                 Throw
  43.             End Try
  44.             If shortCut IsNot Nothing Then
  45.                 shortCut.TargetPath = Me.TargetPath
  46.                 shortCut.WindowStyle = CInt(Me.WindowStyle)
  47.                 shortCut.Description = Me.Description
  48.                 shortCut.WorkingDirectory = Me.WorkingDirectory
  49.                 shortCut.IconLocation = String.Format("{0}, {1}", Me.IconPath, Me.IconIndex)
  50.                 shortCut.Arguments = Me.Arguments
  51.                 If Not String.IsNullOrWhiteSpace(Me.Hotkey) Then
  52.                     shortCut.Hotkey = Me.Hotkey
  53.                 End If
  54.  
  55.                 Try
  56.                     shortCut.Save()
  57.                     retval = System.IO.File.Exists(Me.ShortcutFullName)
  58.                 Catch ex As Exception
  59.                     Throw
  60.                 End Try
  61.             End If
  62.         End If
  63.         Return retVal
  64.     End Function
  65. End Class

Come possiamo vedere, il metodo Save() (che, rispetto al corrispettivo della WshShortcut restituisce un risultato) esegue i seguenti passi:

1) Crea un istanza della classe WshShell:

  1. Dim shell As WshShell = Nothing
  2. Try
  3.     shell = New WshShell()
  4. Catch ex As Exception
  5.     Throw
  6. End Try

2) Se l’istanza della shell è stata effettivamente creata, crea un’istanza della classe WshShortcut:

  1. Try
  2.     shortCut = CType(shell.CreateShortcut(Me.ShortcutFullName), IWshShortcut)
  3. Catch ex As Exception
  4.     Throw
  5. End Try

3) Se l’istanza dello shortcut è stata creata, vengono valorizzate le proprietà:

  1. shortCut.TargetPath = Me.TargetPath
  2. shortCut.WindowStyle = CInt(Me.WindowStyle)
  3. shortCut.Description = Me.Description
  4. shortCut.WorkingDirectory = Me.WorkingDirectory
  5. shortCut.IconLocation = String.Format("{0}, {1}", Me.IconPath, Me.IconIndex)
  6. shortCut.Arguments = Me.Arguments
  7. If Not String.IsNullOrWhiteSpace(Me.Hotkey) Then
  8.     shortCut.Hotkey = Me.Hotkey
  9. End If

4) Viene richiamato il metodo Save() della classe WshShortcut e controllato che il file lnk è effettivamente stato creato:

  1. Try
  2.     shortCut.Save()
  3.     retval = System.IO.File.Exists(Me.ShortcutFullName)
  4. Catch ex As Exception
  5.     Throw
  6. End Try

Un possibile utilizzo della classe è il seguente:

  1. Dim desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
  2. Dim shortcutFullname = System.IO.Path.Combine(desktop, "Doc.lnk")
  3. Dim shortcut = New Shortcut(shortcutFullname)
  4. shortcut.WindowStyle = ShortcutWindowsStyle.NormalNoFocus
  5. shortcut.Description = "I miei documenti"
  6. shortcut.TargetPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
  7. shortcut.Save()

In questo esempio viene creato un link chiamato Doc.lnk sul desktop dell’utente che permette l’apertura dei documenti.

Per concludere osserviamo che una delle proprietà della classe Shortcut da noi creata è l’enumerazione:

  1. Public Enum ShortcutWindowsStyle
  2.     NormalFocus = WshWindowStyle.WshNormalFocus
  3.     NormalNoFocus = WshWindowStyle.WshNormalNoFocus
  4.     MaximizedFocus = WshWindowStyle.WshMaximizedFocus
  5.     MinimizeFocus = WshWindowStyle.WshMinimizedFocus
  6.     MinimizedNoFocus = WshWindowStyle.WshMinimizedNoFocus
  7.     Hide = WshWindowStyle.WshHide
  8. End Enum

che definisce i possibili valori dello stile della finestra dello shortcut incapsulando l’analoga enumerazione WshWindowStyle della IWshRuntimeLibrary.

 

mercoledì 29 dicembre 2010

Tiriamo le somme per il 2010

Il 2010 volge al termine ed è ora di tirare le somme della mia attività di blogger.

In quest’anno ho scrito 153 post (decisamente più prolifico rispetto all’anno precedente) e la classifica assoluta (contemplando anche quelli scritti negli anni precedenti) dei migliori 5 è la seguente:

  1. VB.NET: SplashScreen con effetto fade-in
  2. Appunti di WPF – Settima Puntata – Il Layout
  3. Cambiare la lingua di Visual Studio 2008
  4. VB.NET: Convertire un file DOC in RTF e PDF con office interop
  5. Appunti di WPF – Dodicesima Puntata – Le figure geometriche

Se analizziamo la classifica dei migliori post scritti nel 2010 otteniamo:

  1. Appunti di WPF – Settima Puntata – Il Layout
  2. Appunti di WPF – Dodicesima Puntata – Le figure geometriche
  3. Briciole di WPF: Finestre non rettangolari, WPF vs Windows Forms
  4. Appunti di WPF – Quarta Puntata – XAML, le basi
  5. Briciole di WPF – SplashScreen in Visual Studio 2010
Questa ultima dimostra l’interesse verso WPF ma anche l’interesse verso i tutorial.

Per questo motivo durante il 2011 cercherò di concentrarmi nella scrittura di tutorial per chi si avvicina al mondo .NET.

Alla fine di questo anno posso ritenermi soddisfatto delle visite ottenute sul blog (con oltre 13K totali e una media di circa 1K al mese). Lo scorso anno mi fermai a circa 3k di visite totali (è vero che il blog è stato aperto a fine aprile, ma in ogni caso il numero è decisamente aumentato). Va detto, ad onor di cronaca, che debbo ringraziare la community DomusDotNet e, prima ancora, la defunta DotNetRomaCestà perchè mi hanno dato visibilità.

Tutto questo mi sprona ad impegnarmi ancora durante il 2011 per fornire sempre materiale di quantità.

martedì 21 dicembre 2010

WP7 WebBrowser control e target=”_blank”

Il controllo WebBrowser dei tool di sviluppo di WP7 non digerisce bene gli anchor con target=”_blank”.

Se provate a visualizzare una pagina con dei link che hanno specificato il target impostato su “_blank”, questi non funzioneranno.

Se, invece, il link ha target “_top”, “_parent” o “_self” (o non ha target), il webbrowser vi permette tranquillamente di navigare seguendo i link.

Questo significa che se visualizzate delle pagine web che hanno l’apertura di nuove pagine, queste non funzioneranno come vi aspettate.

Se state utilizzando il metodo NavigateToString() per visualizzare un vostro html, accertatevi di non avere il target negli anchor ed il gioco è fatto.

 

mercoledì 15 dicembre 2010

Connessione a TFS tramite DOM in un servizio web

In un progetto a cui sto lavorando mi è capitato di dover accedere a TFS 2010/2008 utilizzando il DOM messo a disposizione dal Team Explorer.

Abbiamo che fare con un web service che permette di gestire chiamate da una piattaforma non microsoft analizzando il traffico e eseguendo un certo lavoro sui dati ma che, alla fine della fiera, scrive dei workitem all’interno di TFS e non abbiamo scelto di utilizzare la integration platform di TFS.

Lato client, il Team Explore utilizza una serie di cartelle di cache per “cachare” i dati in modo da ottimizzare l’accesso alla piattaforma TFS.

La cartella solitamente utilizzata è nel seguente percorso:

C:\Documents and Settings\Default User\Local Settings\Application Data\Microsoft\Team Foundation\3.0\Cache

In particolare, questa cartella viene creata dal Team Explorer nel momento in cui un utente si connette.

Il problema nasce dal fatto che un servizio web “gira” con un utente che non si connette mai e, quindi, non troverà mai tale cartella.

Per evitare questo problema, in tutti gli oggetti derivati dalla classe TfsConnection (ad esempio TfsConfigurationServer o TfsTeamProjectCollection) si può impostare la proprietà ClientSettingsDirectory che permette di settare la cartella da utilizzare per la cache.

Ovviamente la cartella dovrà avere gli opportuni privilegi in modo che il servizio web possa scrivere all’interno di essa.

La stessa proprietà può essere utilizzata da un servizio Windows o da un client standard a finestra.

 

Tutto cambia…..anche il natale!!!

 

Tag di Technorati: ,,

mercoledì 8 dicembre 2010

Rilasciata la Feature CTP5 di EF

E’ stato annunciato (vedi il post) il rilascio della Feature CTP5 di EF per lo sviluppo di classi di accesso alla banca dati di tipo Code First.

Sul blog di ADO.NET sono disponibili anche dei post per cominciare a capire il funzionamento del framework:

Questa è l’ultima CTP prima del rilascio definitivo che avverrà nel primo quadrimestre del 2011.

Per scaricare la CTP utilizzare il link.

mercoledì 1 dicembre 2010

IE9– Creare un’attività nella jumplist senza immagine

IE9 permette agli sviluppatori di definire delle attività all’interno della jumplist di un sito agganciato alla task bar di Windows 7 (vedere post per maggiori info).

Un’attività altro non è che un accesso rapido ad una funzionalità di un’applicazione che, nel caso di un web site,  è che una pagina.

Le attività si definiscono attraverso dei meta tag nel formato:

  1. <META name="msapplication-task"
  2.       content="name=News; action-uri=url della pagina; icon-uri=imagine del task" >

dove il content è formato da tre parti distinte:

  • name : nome che compare nella lista dei tasks. Può essere anche vuoto (anche se non ha molto senso perché l’utente vedrebbe un’attività senza alcun nome e non saprebbe a cosa serve);
  • action-uri : indirizzo della pagina che corrisponde al task. Può anche essere vuoto (in questo caso viene aperta la root del sito) oppure un link esterno al nostro sito;
  • icon-uri : immagine da utilizzare nella lista dei task alla sinistra del nome. Questo campo non può essere vuoto e deve puntare ad una immagine in formato ico.

Le tre parti devono essere presenti anche se, name e action-uti possono essere vuote.

La parte relativa all’immagine, invece, non può restare vuota, altrimenti il tag non è riconosciuto (è come se non ci fosse).

Se vogliamo implementare un’attività senza immagine ci basta inserire un valore qualsiasi anzichè lasciare il campo vuoto, ad esempio la stringa “null”.

Il seguente tag, per esempio, implementa l’attività News senza immagine:

  1. <META name="msapplication-task"
  2.       content="name=News; action-uri=news.html; icon-uri=null" >

 

martedì 30 novembre 2010

Windows Phone 7 Developer Tools – Primo progetto VB

Notizia di ieri l’uscita dei Developer Tools per Windows Phone 7 dedicati agli sviluppatori VB in versione RTW.

Vediamo un brevissimo post su come creare un primo progetto.

Innanzitutto i tools sono installabili da chi possiede una versione compteta di Visual Studio dalla professional in su.

Una volta installati, i tools diventano uno dei tanti progetti presenti nella maschera di creazione di un progetto:

image

Come per la versione C#, abbiamo a disposizione 5 tipologie di progetto:

  • Windows Phone Application : è il template di progetto vuoto che prevede una window iniziale con pochissimi controlli;
  • Windows Phone Databound Application : è il template per le applicazioni di visualizzazione dei dati basate su una lista;
  • Windows Phone Class Library : è il progetto per la realizzazione di un assembly contenente le nostre classi per WP7;
  • Windows Phone Panorama Application : è il template di progetto per le applicazioni basate sul controllo panorama;
  • Windows Phone Pivot Application : è il template di progetto per le applicazioni basate sul controllo pivot.

Selezionato il progetto, Visual Studio crea, come di consueto, tutti i file necessari.

Il progetto generato è del tutto uguale a quello del cugino C# con l’ovvia differenza che il code behind delle windows XAML scritto in VB.

A questo punto il solo freno è la fantasia e sta a noi trovare nuove idee per implementare applicazioni di successo.

Le applicazioni scritte con i developer tools per VB.NET si possono sottomettere al marketplace come accade come le usuali applicazioni per WP7 scritte in C#.

 

domenica 28 novembre 2010

Facciamo lampeggiale l’overlay icon di IE9

IE9 introduce il concetto di “pinned site” (post) con il quale gli sviluppatori possono far sembrare le proprie web application delle applicazioni desktop.

Il fatto che un sito sia “pinnabile” è fornito “di serie” con IE9 cioè qualsiasi sito è agganciabile alla task bar di Windows.

Oltre a questa funzionalità, abbiamo modo di interagire, in un certo qual modo, con l’icona presente nella task bar di Windows grazie a dei metodi Javascript della classe window.external.

In particolare il metodo msSiteModeSetIconOverlay permette di visualizzare una overlay icon (cioè una iconetta in sovraimpressione) sull’icona del sito posizionata nella task bar. Questo ci permette di attrarre l’attenzione dei nostri utenti per segnalare l’accadimento di qualcosa.

L’istruzione:

  1. window.external.msSiteModeSetIconOverlay('/images/red.ico', 'Icona in sovraimpressione!!');

ci permette di visualizzare, al di sopra dell’icona del nostro sito “pinned”, l’icona red.ico.

L’istruzione ha l’effetto desiderato se la pagina da cui è stata invocata è stata aperta utilizzando l’icona della task bar e le icone della task bar siano nel formato “grande”.

In caso positivo otteniamo una cosa del genere:

image

Possiamo utilizzare qualsiasi formato di icona poichè ci pensa IE9 ad ridimensionare opportunamente l’icona da noi utilizzata.

Inoltre possiamo utilizzare il metodo più volte ottenendo sovraimpressioni multiple.

Infine, possimao rimuovere l’icona (o le icone) visualizzate utilizzando il metodo msSiteModeClearIconOverlay. Questo metodo, a prescindere da quante icone abbiamo visualizzato, riporta la situazione alla sola visualizzazione dell’icona del sito (la favicon.ico, tanto per intenderci).

L’idea che può venirci in mente è quella di far lampeggiare l’icona utilizzando alternativamente i due comandi e l’istruzione Javascript  setInterval per ripetere il tutto un certo numero di volte:

  1. function blinkOverlayIcon(numberOfBlinks, blinkInterval, icona) {
  2.     if (window.external.msIsSiteMode) {
  3.         if (numberOfBlinks >= 0) {
  4.             try {
  5.                 if (numberOfBlinks % 2 == 0) {
  6.                     window.external.msSiteModeSetIconOverlay(icona, "");
  7.                 } else {
  8.                     window.external.msSiteModeClearIconOverlay();
  9.                 }
  10.             } catch (e) {
  11.  
  12.             }
  13.             numberOfBlinks--;
  14.             var func = "blinkOverlayIcon(" + numberOfBlinks + "," + blinkInterval + ",'" + icona + "')"
  15.             setTimeout(func, blinkInterval);
  16.  
  17.         } else {
  18.             clearTimeout();
  19.             try {
  20.                 window.external.msSiteModeClearIconOverlay();
  21.             } catch (e) {
  22.             }
  23.         }
  24.     }
  25. }

In pratica il bottone:

  1. <input type="button" name="name" value="Lampeggia" onclick="javascript:blinkOverlayIcon(20,500,'/images/red.ico');" />

Permette di ripetere 20 volte la funzione (per un totale di 10 lampeggi) con un intervallo di mezzo secondo ciascuna.

Ulteriore possibilità è quella di alternare due o più icone in modo da ottenere effetti sempre più complessi. In particolare per alternare due immagini possiamo utilizzare questa funzione

  1. function alternateOverlayIcon(numberOfBlinks, blinkInterval, icona1, icona2) {
  2.     if (window.external.msIsSiteMode) {
  3.         if (numberOfBlinks >= 0) {
  4.             try {
  5.                 var icona = '';
  6.                 if (numberOfBlinks % 2 == 0) {
  7.                     icona = icona1;
  8.                 } else {
  9.                     icona = icona2;
  10.                 }
  11.                 window.external.msSiteModeClearIconOverlay();
  12.                 window.external.msSiteModeSetIconOverlay(icona, "");
  13.             } catch (e) {
  14.  
  15.             }
  16.             numberOfBlinks--;
  17.             var func = "alternateOverlayIcon(" + numberOfBlinks + "," + blinkInterval + ",'" + icona1 + "','" + icona2 + "')"
  18.             setTimeout(func, blinkInterval);
  19.  
  20.         } else {
  21.             clearTimeout();
  22.             try {
  23.                 window.external.msSiteModeClearIconOverlay();
  24.             } catch (e) {
  25.             }
  26.         }
  27.     }
  28. }

In questo caso, il bottone:

  1. <input type="button" name="name" value="Alterna" onclick="javascript:alternateOverlayIcon(20,250,'/images/red.ico', '/images/yellow.ico');" />

alterna le icone rossa e gialla per 20 volte, ciascuna della durata di 250 millisecondi.

Evidentemente unico freno è la fantasia e, al limite, possiamo pensare di eseguire una vera e propria animazione alternando tutti i frame della stessa.

Un limite è che, poichè IE9 esegue di suo un effetto fade sulla visualizzazione dell’icona di overlay, il tempo tra una visualizzazione e l’altra non può essere piccolo a piacere.

 

sabato 27 novembre 2010

Articolo su ioProgrammo di Dicembre

E’ in edicola il numero di dicembre di ioProgrammo.

4-157g

All’interno di questo numero potete trovare un mio articolo dal titolo:

Personalizza l'IDE di Microsoft per velocizzare l'analisi del tuo codice sorgente

 

venerdì 26 novembre 2010

Windows Azure Discover Event (Parte 2)

L’evento è terminato e la sensazione è stata di un evento decisamente utile.

Uscito dalla sede Microsoft, mi sono reso conto di saperne un pochino di più e, questo, a mio modo di vedere, rende un evento utile.

Un ringraziamento a Roberto Brunetti e Mario Fontana che hanno tenuto delle sessioni ottime, chiare e chiarificatrici.

Ho avuto il piacere di conoscere Roberto di persona dopo tanti eventi in cui l’ho visto sul “palco” e la sensazione è quella di una persona ottima nonchè di uno speaker d’eccezione (ma quello lo sapevo).

Ancora una volta torno a dire che chi non è venuto si è perso una buonissima occasione per fare formazione!!!!

 

Windows Azure Discover Event (Parte 1)

Evento dedicato a Windows Azure a Roma.

Nella mattinata, Mario Fontana, ha cercato di fare chiarezza su cosa è il Cloud e cosa nonè.

E, debbo dire, c’è pienamente riuscito!!

Tarda mattinata dedicata al pricing delle sottoscrizioni per Windows Azure che aveva poco di tecnico ma ha chiarito anche questo punto oscuro.

Nel pomeriggio tocca a Roberto Brunetti che andrà sul pratico e ……. ci sarà da divertirsi!!!

A più trdi per il resoconto!!!

Stay tuned!! Occhiolino

 

giovedì 25 novembre 2010

Rilasciati due update per IE9 Beta

Il seguente post annuncia il rilascio di due update per IE9 beta:

Updates for Internet Explorer 9 Beta - IEBlog - Site Home - MSDN Blogs

Gli update sono distribuiti via Windows Update, quindi gli utenti ( a meno che non abbiano Windows Update disabilitato) dovrebbero vederseli arrivare “a casa” direttamente!!

 

Tag di Technorati: ,,

venerdì 19 novembre 2010

Sfogliare il Marketplace di WP7 da Web

Il marketplace di WP7 è consultabile tramite il software Zune Client oppure direttamente dai dispositivi WP7 che dispongono dell’hub apposito.

Chi non ha installato lo Zune Client o non ha il telefonino non è in grado di vedere cosa c’è a disposizione. Per ovviare a questo si può utilizzare il sito http://www.marketplacebrowser.com/ che consente di ricercare le applicazioni presenti nel marketplace senza avere client installati sul proprio pc.

image

Ovviamente l’acquisto si esegue con lo Zune Client ma se dobbiamo solamente capire se c’è l’Applicazione con la A maiuscola, il sito è perfetto.

Pubblicata Acronimi per WP7 sul Marketplace

Da ieri sera è disponibile la mia applicazione Acronimi per conoscere il significato di migliaia di acronimi.

Screenshot02Screenshot01Screenshot04

L’applicazione è scaricabile dal marketplace:

wp7_300x50_blue

Prossimamente uscirà un aggiornamento alla lista degli Acronimi presenti nell’applicazione.

Se ne trovate di mancanti (e ce ne sono sicuramente) segnalatemeli e li inserirò nelle prossime versioni.

 

Tag di Technorati: ,,,

giovedì 18 novembre 2010

DataURI e le immagini dinamiche in ASP.NET

In questo post vorrei proporvi un modo per creare immagini dinamiche  (in maniera analoga a quanto già proposto in questo post) all’interno delle nostre pagine ASPX utilizzando il DataURI.

Partiamo dal definire cosa è il DataURI.

Il DataURI (o più esattamente lo schema data URI), la cui definizione esatta è rintracciabile seguendo il link,  rappresenta un modo per includere all’interno delle nostre pagine web delle risorse (ad esempio grafiche, ma non solo).

Lo schema data URI compare già nelle specifiche dell’HTML 4.01.

I vantaggi di utilizzare lo schema data URI sono i seguenti:

  • le risorse incorporate nella pagina non richiedono differenti chiamate al server come accadrebbe se le risorse fossero indicate con un normale URL. Si ha quindi un risparmi nel numero di richieste e si elimina il traffico dell’header delle stesse;
  • per files di piccole dimensioni si ha un guadagno di tempo, poichè, generalmente, l’avvio della comunicazione TCP è lento;
  • nelle comunicazioni HTTPS, il browser, di solito, richiede che tutti gli elementi della pagina siano scaricati in connessione sicura (pena la comunicazione all’utente che ci sono elementi non “sicuri”) e l’HTTPS aggiunge un ulteriore overhead alla trasmissione;
  • i messaggi email possono, in questo modo contanere immagini senza che queste appaiano come degli allegati;
  • se il browser ha un numero basso di connessioni simultanee, si ha un vantaggio di tempo.

Lo schema data URI, però, ha anche degli svantaggi:

  • le risorse incorporate come data URI non sono cachate come le comuni risorse (ad esempio immagini) referenziate con un comune URL;
  • alcuni browser ancora in circolazione (ad esempio IE7 con circa il 27% della distribuzione sul mercato a luglio 2010) non lo supportano;
  • alcuni browser hanno una limitazione sulla lunghezza massima del data URI (ad esempio IE8 ha una limitazione a 32KB);
  • l’encoding del data URI (in base 64) è mediamente 1/3 più largo dell’equivalente encoding binario;
  • i software che si occupano di controllare la sicurezza dei siti lavorano male sui dati contanuti nello schema data URI.

Il formato di una risorsa espressa secondo lo schema data URI è il seguente:

data:[<MIME-type>][;charset=<encoding>][;base64],<data>

Se non si indica il base64, si intende che i dati sono espressi in ASCII.

Ad esempio, un’immagine in HTML è espressa nel seguente modo:

  1. <img src="data:image/png;base64,
  2.         iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP
  3.         C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA
  4.         AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J
  5.         REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq
  6.         ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0
  7.         vr4MkhoXe0rZigAAAABJRU5ErkJggg==" alt="Red dot" />

Lo schema data URI può essere utilizzato anche all’interno di un CSS (per i browser che lo supportano) o per includere del JavaScript.

Capito cosa è lo schema data URI vediamo come possiamo utilizzarlo  nelle nostre pagine ASPX.

Innanzitutto vediamo cosa si ottiene in termini di richieste e dati trasferiti quando includiamo delle immagini tramite data URI e in maniera classica.

Per fare questo realizziamo due pagine all’interno delle quali visualizzeremo le immagini contenute in una cartella nelle due modalità.

Il code behind della pagina che utilizza la tecnica standard è la seguente:

  1. Imports System.IO
  2.  
  3. Public Class MultiImageStandard
  4.     Inherits System.Web.UI.Page
  5.  
  6.     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  7.         If Not IsPostBack Then
  8.             CreateImages(10)
  9.         End If
  10.     End Sub
  11.  
  12.     Private Sub CreateImages(ByVal numImages As Integer)
  13.         Dim imagePath = Server.MapPath("/images")
  14.         Dim imageRep = New ImageRepository()
  15.         Dim imageFiles = imageRep.GetAllImages(imagePath)
  16.         For Each imageFile In imageFiles
  17.             Dim image = New Image()
  18.             Dim fi = New FileInfo(imageFile)
  19.             image.ImageUrl = String.Format("/images/{0}", fi.Name)
  20.             Me.Controls.Add(image)
  21.         Next
  22.     End Sub
  23. End Class

La classe ImageRepository enumera le immagini presenti nella cartella.

In sostanza creiamo un oggetto Image (web control) per ogni immagine ed impostiamo il sui ImageUrl. Il risultato ottenuto è il seguente:

image

Utilizzando IE9 e la developer toolbar (tasto F12) possiamo osservare il numero di chiamate eseguite verso il server per recuperare la pagina e le 12 immagini visualizzate.

Il code behind della pagina che utilizza lo schema data URI è il seguente:

  1. Public Class MultiImageDataUri
  2.     Inherits System.Web.UI.Page
  3.  
  4.     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  5.         If Not IsPostBack Then
  6.             CreateImages(10)
  7.         End If
  8.  
  9.     End Sub
  10.  
  11.     Private Sub CreateImages(ByVal numImages As Integer)
  12.         Dim imagePath = Server.MapPath("/images")
  13.         Dim imageRep = New ImageRepository()
  14.         Dim imageFiles = imageRep.GetAllImages(imagePath)
  15.         For Each imageFile In imageFiles
  16.             Dim image = New Image()
  17.             image.ImageUrl = CreateDataUri(imageFile)
  18.             Me.Controls.Add(Image)
  19.         Next
  20.     End Sub
  21.  
  22.     Private Function CreateDataUri(ByVal imagePath As String) As String
  23.         Dim image = New Drawing.Bitmap(imagePath)
  24.         Dim base64String As String
  25.         Using ms As New IO.MemoryStream
  26.             image.Save(ms, image.RawFormat)
  27.             base64String = Convert.ToBase64String(ms.ToArray())
  28.         End Using
  29.         Return String.Format("data:image/png;base64,{0}", base64String)
  30.     End Function
  31.  
  32. End Class

In questo caso, per ogni immagine da visualizzare, craiamo un oggetto Bitmap, ne ricaviamo la sua rappresentazione come array di Byte e, quindi, lo encodiamo in base64.

Il risultato, in questo caso, è il seguente:

image

Osserviamo una sola connessione per recuperare l’intera pagina.

Un altro utilizzo dello schema data URI può essere quello di visualizzare delle immagini dinamiche.

Supponiamo di voler fare in modo che data un’immagine venga applicata su di essa una scritta di watermark (esattamente come già avevamo fatto nel post).

Per realizzare tutto ciò è sufficiente creare un immagine bitmap a partire dall’immagine su cui applicare il watermark, recuperare il suo contesto grafico, disegnare il watermark su di essa e, infine encodarla in base64.

In sostanza possiamo scrivere:

  1. Imports System.Drawing
  2.  
  3. Public Class DynamicImage
  4.     Inherits System.Web.UI.Page
  5.  
  6.     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  7.         If Not IsPostBack Then
  8.             CreateImage("/images/BigImage/DominicanRepublic_DE-DE1561561743.jpg", "CodeTailor", Image1)
  9.         End If
  10.     End Sub
  11.  
  12.     Private Sub CreateImage(ByVal imagePath As String,
  13.                             ByVal watermark As String,
  14.                             ByVal imageControl As System.Web.UI.WebControls.Image)
  15.  
  16.         Dim imageFullPath = HttpContext.Current.Server.MapPath(imagePath)
  17.         Dim image As New Bitmap(imageFullPath)
  18.         Dim gr = Graphics.FromImage(image)
  19.         Dim watermarkFont = New Font(FontFamily.GenericMonospace, _
  20.             10, FontStyle.Regular, GraphicsUnit.Pixel)
  21.         Dim textSize = gr.MeasureString(watermark, watermarkFont)
  22.         Dim x = 0
  23.         While x < image.Width
  24.             Dim y = 0
  25.             While y < image.Height
  26.                 gr.DrawString(watermark, watermarkFont, Brushes.White, x, y)
  27.                 y = CInt(y + (3 / 2 * textSize.Height))
  28.             End While
  29.             x = CInt(x + (3 / 2 * textSize.Width))
  30.         End While
  31.         Dim base64String As String
  32.         Using ms As New IO.MemoryStream
  33.             image.Save(ms, image.RawFormat)
  34.             base64String = Convert.ToBase64String(ms.ToArray())
  35.         End Using
  36.         imageControl.ImageUrl = String.Format("data:image/png;base64,{0}", base64String)
  37.     End Sub
  38. End Class

Il risultato che otteniamo è il seguente:

image



mercoledì 17 novembre 2010

IE9 Platform Preview 7 disponibile

Altro rilascio di una platform preview di IE9 con miglioramenti lato Javascript (“Chakra” cresce sempre di più).

Il post originale con l’annuncio è il seguente:

HTML5, and Real World Site Performance: Seventh IE9 Platform Preview Available for Developers - IEBlog - Site Home - MSDN Blogs

Vorrei solo portare alla vostra attenzione questi due grafici:

SunSpiderResultsPPB6

Dean_PPB7

Il primo è il risultato del SunSpider JavaScript eseguito sulla IE9 Platform Preview 6 mentre il secondo è quello eseguito sulla Platform Preview 7: la differenza si vede!!!

Per chi ne vuole sapere di più sul SunSpider JavaScript può seguire il link.

Il download della Preview 7 si può eseguire dal seguente link.