<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.3" xml:lang="en-us" xmlns="http://purl.org/atom/ns#">
  <title>Blog2theMax</title>
  <link rel="alternate" type="text/html" href="http://www.dotnet2themax.it/blog/" />
  <modified>2008-10-28T07:19:38.6093750-07:00</modified>
  <tagline>Il blog del team di Code Architects</tagline>
  <generator>newtelligence dasBlog 1.7.5016.2</generator>
  <author>
    <name>Code Architects S.r.l.</name>
  </author>
  <entry>
    <title>La guida italiana a Open XML</title>
    <link rel="alternate" type="text/html" href="http://www.dotnet2themax.it/blog/PermaLink,guid,707213e4-ca90-44bc-a69b-c03ef23741ec.aspx" />
    <id>http://www.dotnet2themax.it/blog/PermaLink,guid,707213e4-ca90-44bc-a69b-c03ef23741ec.aspx</id>
    <issued>2008-10-28T07:19:38.6093750-07:00</issued>
    <modified>2008-10-28T07:19:38.6093750-07:00</modified>
    <created>2008-10-28T07:19:38.6093750-07:00</created>
    <author>
      <name>Francesco Balena</name>
    </author>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <table>
          <tbody>
            <tr>
              <td>
                <img src="http://media.hoepli.it/hoepli/Libro/GIACCAGLINI-GIANNI/OPEN-XML/9788882337438.jpeg" valign="top" />
              </td>
              <td>
                <p>
                  Fino a pochi anni fa per generare o modificare un file Word o Excel era necessario
                  operare sul modello a oggetti della stessa applicazione (e quindi avere a disposizione
                  una licenza di Office), oppure acquistare un componente di terze parti in grado di
                  generare tali file. In entrambi i casi si tratta di opzioni che hanno un costo, e
                  inoltre la prima opzione era improponibile per le applicazioni lato-server (che generano
                  file da inviare ai browser sul client) per i problemi di scalabilità che comporta.
               </p>
                <p>
                  La soluzione è arrivata con Office 2007 e il suo formato Open XML, che permette quindi
                  di salvare, rileggere, modificare e interrogare un file Word o Excel come se fosse
                  un semplice file di testo XML. Se lavorate in .NET, alla fine si riduce a saper usare
                  la classe XmlDocument per leggere/scrivere, conoscere la grammatica di XPath per le
                  query, e poco altro. Quello che realmente occorre è comprendere la sintassi e le sottigliezze
                  di Open XML, ma per quello da qualche tempo c'è un bel libro (in italiano!): <a href="http://www.hoepli.it/libro.asp?ib=9788882337438&amp;pc=000022007002024"><strong>Open
                  XML Guida allo Sviluppo.</strong></a>L'autore <strong>Gianni Giaccagliani</strong> è una
                  vecchia conoscenza per chi lavora in questo settore da tempo nonchè un mio amico dai
                  tempi delle gloriose riviste BIT (che non esiste più già da un paio di decenni) e
                  PC Magazine.
               </p>
                <p>
                  In questo agile libretto (250 pagine) Gianni introduce il DOM di Open XML e mostra
                  come manipolarlo usando direttamente il VBA degli stessi Word o Excel, quindi il libro
                  è alla portata anche di coloro che non hanno installato Visual Studio, anche se la
                  conversione in VB.NET è immediata, tanto più se si utilizza VSTO. Ci sono esempi approfonditi
                  sia con Word che Excel, e una buona introduzione a XPath, il tutto nello
                  stile semplice e "fluido" di Gianni, che ben conoscono i suoi lettori (incluso il
                  sottoscritto). Che volete di più?
               </p>
                <p>
                   
               </p>
                <p>
                   
               </p>
              </td>
            </tr>
          </tbody>
        </table>
        <p>
       
   </p>
        <p>
       
   </p>
        <img width="0" height="0" src="http://www.dotnet2themax.it/blog/aggbug.ashx?id=707213e4-ca90-44bc-a69b-c03ef23741ec" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Regional Director again!</title>
    <link rel="alternate" type="text/html" href="http://www.dotnet2themax.it/blog/PermaLink,guid,b4409446-e307-4ee6-ad3e-b100dcf2bd7e.aspx" />
    <id>http://www.dotnet2themax.it/blog/PermaLink,guid,b4409446-e307-4ee6-ad3e-b100dcf2bd7e.aspx</id>
    <issued>2008-01-11T02:00:24.4687500-08:00</issued>
    <modified>2008-01-11T02:00:24.4687500-08:00</modified>
    <created>2008-01-11T02:00:24.4687500-08:00</created>
    <author>
      <name>Francesco Balena</name>
    </author>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a ref="http://www.theregion.com">
            <img src="http://www.dotnet2themax.it/blog/content/binary/RDLogo.gif" border="0" />
          </a> Ecco
      una bella notizia che mi ha fatto cominciare l'anno nel migliore dei modi.
   </p>
        <p>
      Microsoft Corp. ha confermato <strong>Giuseppe Dimauro</strong> e il sottoscritto
      come <strong>gli unici due Regional Director per l'Italia</strong>, per gli anni 2008-09.
      E' una grande soddisfazione far parte di una elite di soli 140 esperti in tutto il
      mondo - a differenza di altri gruppi come gli MVP, il numero degl RD è "contingentato",
      tipicamente 1 o 2 per ciascuna nazione e per ciascuno dei 50 stati degli USA. Negli
      ultimi tempi il Regional Director Program si è arricchito di <a href="http://www.theregion.com">un
      sito </a>tutto nostro, che funge anche da aggregatore dei blog. Data la qualiltà del
      materiale che si può trovare, è quasi meglio di una rivista tecnica.
   </p>
        <img width="0" height="0" src="http://www.dotnet2themax.it/blog/aggbug.ashx?id=b4409446-e307-4ee6-ad3e-b100dcf2bd7e" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Velocizzare le concatenazioni di stringhe nei programmi migrati da VB6</title>
    <link rel="alternate" type="text/html" href="http://www.dotnet2themax.it/blog/PermaLink,guid,36446eb4-9d7c-45af-a758-42b87a7f54ff.aspx" />
    <id>http://www.dotnet2themax.it/blog/PermaLink,guid,36446eb4-9d7c-45af-a758-42b87a7f54ff.aspx</id>
    <issued>2007-12-16T03:44:27.4232500-08:00</issued>
    <modified>2007-12-16T03:44:27.4232500-08:00</modified>
    <created>2007-12-16T03:44:27.4232500-08:00</created>
    <author>
      <name>Francesco Balena</name>
    </author>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      In questo periodo sto facendo molta consulenza per aziende italiane alle prese con
      la migrazione da VB6, usando ovviamente la versione preliminare di <a href="http://www.vbmigration.com/">VB
      Migration Partner</a>. Oramai la beta è stabile e si comporta davvero molto bene.
      In un solo giorno, ad esempio, abbiamo migrato una applicazione di circa 20mila righe
      che lavora in modo intensivo con ADO in circa mezza giornata, e tutto funziona a meraviglia!
   </p>
        <p>
      Anche se la migrazione sta andando bene, a volte i programmi migrati sono più lenti
      del codice VB6 originario. Per esperienza le cause sono principalmente due: (1) l'uso
      di COM Interop per accedere agli oggetti ADO, (2) un uso massiccio di concatenazione
      di stringhe. Per il primo problema non c'è molto da fare, purtroppo: occorre migrare
      il codice di accesso al database da ADO a ADO.NET, un compito più semplice a dirsi
      che a farsi. Per il secondo problema ci sarebbe invece una soluzione semplice: basterebbe
      sostituire la variabile stringa con una variabile <strong>StringBuilder</strong>,
      e le concatenazioni sarebbero automaticamente più veloci. Peccato che questa sostituzione
      comporti una revisione completa del codice, perchè richiede di trasformare tutti gli
      operatori &amp; (concatenazione) con il metodo <strong>Append</strong>, per non parlare
      dei casi in cui la variabile stringa viene usata come argomento a funzioni come Trim
      o Left. Ad esempio, il seguente codice richiede ben 17 secondi sul mio sistema a 3GHz:
   </p>
        <p>
          <font color="#0000ff">Dim</font> s <font color="#0000ff">As</font> <font color="#0000ff">String</font> = <font color="#800000">""<br /></font><font color="#0000ff">Dim</font> sw <font color="#0000ff">As</font> Stopwatch
      = Stopwatch.StartNew()<br /><font color="#0000ff">For</font> i <font color="#0000ff">As</font><font color="#0000ff">Integer</font> =
      1 <font color="#0000ff">To</font> 100000<br />
          s = s + <font color="#800000">"*"<br /></font><font color="#0000ff">Next<br /></font>MsgBox(sw.Elapsed.ToString)
   </p>
        <p>
      Per fortuna la soluzione è davvero semplice: basta creare una classe che utilizzi
      internamente un oggetto StringBuilder, che ridefinisca gli operatori &amp; e +, e
      che supporti la conversione implicita da-a stringa. Il codice di questa classe StringBuilder6
      si scrive davvero in pochi minuti:
   </p>
        <font color="#0000ff">
          <p>
      Imports
   </p>
        </font>
        <font color="#000000"> System.Text</font>
        <font color="#008000">
          <p>
      ' a wrapper for the StringBuilder object, with support for + and &amp; operators
   </p>
        </font>
        <font color="#0000ff">
          <p>
      Public
   </p>
        </font>
        <font color="#000000">
        </font>
        <font color="#0000ff">Class</font>
        <font color="#000000"> StringBuilder6</font>
        <p>
          <font color="#0000ff">    Private</font> buffer <font color="#0000ff">As</font><font color="#0000ff">New</font> StringBuilder
   </p>
        <p>
          <font color="#008000">
            <font color="#0000ff">    </font>' return the
      inner string
      </font>
        </p>
        <p>
          <font color="#0000ff">    Public</font>
          <font color="#0000ff">Overrides</font>
          <font color="#0000ff">Function</font> ToString() <font color="#0000ff">As</font><font color="#0000ff">String<br />
              </font><font color="#0000ff">Return</font> buffer.ToString()<br /><font color="#0000ff">    End</font><font color="#0000ff">Function
      </font></p>
        <p>
          <font color="#0000ff">    Public</font>
          <font color="#0000ff">Shared</font>
          <font color="#0000ff">Operator</font> +(<font color="#0000ff">ByVal</font> op1 <font color="#0000ff">As</font> StringBuilder6, <font color="#0000ff">ByVal</font> op2 <font color="#0000ff">As</font><font color="#0000ff">String</font>) <font color="#0000ff">As</font> StringBuilder6<br />
              op1.buffer.Append(op2)<br />
              <font color="#0000ff">Return</font> op1<br /><font color="#0000ff">    End</font><font color="#0000ff">Operator
      </font></p>
        <p>
          <font color="#0000ff">    Public</font>
          <font color="#0000ff">Shared</font>
          <font color="#0000ff">Operator</font> &amp;(<font color="#0000ff">ByVal</font> op1 <font color="#0000ff">As</font> StringBuilder6, <font color="#0000ff">ByVal</font> op2 <font color="#0000ff">As</font><font color="#0000ff">String</font>) <font color="#0000ff">As</font> StringBuilder6<br />
              op1.buffer.Append(op2)<br />
              <font color="#0000ff">Return</font> op1<br /><font color="#0000ff">    End</font><font color="#0000ff">Operator
      </font></p>
        <p>
          <font color="#008000">    ' convert to string
      </font>
        </p>
        <p>
          <font color="#0000ff">    Public</font>
          <font color="#0000ff">Shared</font>
          <font color="#0000ff">Widening</font>
          <font color="#0000ff">Operator</font>
          <font color="#0000ff">CType</font>(<font color="#0000ff">ByVal</font> op <font color="#0000ff">As</font> StringBuilder6) <font color="#0000ff">As</font><font color="#0000ff">String<br />
              </font><font color="#0000ff">Return</font> op.ToString()<br /><font color="#0000ff">    End</font><font color="#0000ff">Operator
      </font></p>
        <p>
          <font color="#008000">    ' convert from string 
      </font>
        </p>
        <p>
          <font color="#0000ff">    Public</font>
          <font color="#0000ff">Shared</font>
          <font color="#0000ff">Widening</font>
          <font color="#0000ff">Operator</font>
          <font color="#0000ff">CType</font>(<font color="#0000ff">ByVal</font> str <font color="#0000ff">As</font><font color="#0000ff">String</font>) <font color="#0000ff">As</font> StringBuilder6<br />
              <font color="#0000ff">Dim</font> op <font color="#0000ff">As</font><font color="#0000ff">New</font> StringBuilder6()<br />
              op.buffer.Append(str)<br />
              <font color="#0000ff">Return</font> op<br /><font color="#0000ff">    End</font><font color="#0000ff">Operator
      </font></p>
        <p>
      End<font color="#000000"></font><font color="#0000ff">Class</font></p>
        <p>
      A questo punto per velocizzare il codice visto prima è sufficiente modificare UNA
      SOLA ISTRUZIONE, ovvero la dichiarazione della variabile stringa:
   </p>
        <p>
          <font color="#0000ff">Dim</font> s <font color="#0000ff">As</font> StringBuilder6
      = <font color="#800000">""<br /></font></p>
        <font color="#000000">
          <p>
      Dopo questa sostituzione, il ciclo visto prima viene eseguito in <strong><em>8 millesimi
      di secondo</em></strong>, ovvero <strong><font color="#ff0000">circa 2000 volte più
      velocemente</font></strong>!!! Non male, per una fix così semplice :-)
   </p>
          <p>
      Indipendentemente dal fatto che state migrando codice da VB6 o se avete scritto codice
      VB.NET (o C#) da zero: se trovate dei punti in cui fate uso massiccio di concatenazione
      di stringhe e che pensate possano rallentare l'esecuzione, provate a sostituire la
      variabile stringa con un oggetto StringBuilder6: in alcuni casi il programma girerà
      molto ma molto più velocemente.
   </p>
          <p>
          </p>
        </font>
        <font color="#0000ff"> 
   </font>
        <img width="0" height="0" src="http://www.dotnet2themax.it/blog/aggbug.ashx?id=36446eb4-9d7c-45af-a758-42b87a7f54ff" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Una regex per manipolare HTML</title>
    <link rel="alternate" type="text/html" href="http://www.dotnet2themax.it/blog/PermaLink,guid,78327f62-ab87-4f6b-b296-366aedcb1ab4.aspx" />
    <id>http://www.dotnet2themax.it/blog/PermaLink,guid,78327f62-ab87-4f6b-b296-366aedcb1ab4.aspx</id>
    <issued>2007-12-08T05:46:40.8803750-08:00</issued>
    <modified>2007-12-08T06:04:51.9585000-08:00</modified>
    <created>2007-12-08T05:46:40.8803750-08:00</created>
    <author>
      <name>Francesco Balena</name>
    </author>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      L'altro giorno un nostro amico-cliente ci chiama per un problema con un controllo
      WinForm wordprocessor-like. Nella loro applicazione usano questo controllo anche per
      la capacità di importare HTML, solo che a un certo punto scoprono che il controllo
      va in crash se il test HTML contiene un tag IMG con attributo ALIGN e che punta a
      una immagine "remota", ovvero il cui URL comincia per http:// , come in questo esempio:
   </p>
        <pre>   &lt;IMG SRC="http://www.somesite.com/image.jpg" ALIGN=left WIDTH=100&gt;</pre>
        <p>
      Con un po' di tentativi scoprono che il problema è la presenza dell'attributo ALIGN
      e che il crash si può evitare se si trasforma l'HTML in questo modo:
   </p>
        <pre>   &lt;DIV style="float:left"&gt;&lt;IMG SRC="http://www.somesite.com/image.jpg" WIDTH=100&gt;&lt;/DIV&gt;</pre>
        <p>
      in altre parole, occorre eliminare l'attributo ALIGN dall'interno del tag IMG e renderlo
      come style di un blocco DIV che racchiude il tag IMG. Questa sostituzione va fatta
      un attimo prima di caricare il testo HTML nel controllo, ma solo se il tag IMG contiene
      un attributo ALIGN e solo se l'URL dell'immagine comincia con i caratteri "http://".
      Il tutto è complicato dal fatto che il valore dei vari attributi può essere o non
      essere racchiuso tra virgolette. Insomma, un bel problemino. 
   </p>
        <p>
      Ovviamente, la soluzione sarebbe stata basata su qualche regex, ma era la prima volta
      che mi imbattevo in un caso di questo tipo. I problemi da risolvere erano principalmente
      due: come agire solo sui tag IMG contenenti un SRC remoto e come fare per "spostare"
      solo l'attributo ALIGN, senza toccare tutti gli altri attributi che compaiono nel
      tag IMG. Il primo problema lo si risolve con le cosiddette <em>positive look-ahed
      assertion</em>, ovvero il costrutto <strong>(?=...)</strong>, che permette di controllare
      che esista una certa sottostringa a destra della regex principale, ma senza consumare
      caratteri per il match. Il secondo problema si risolve facilmente se si pensa a suddividere
      l'intero contenuto del tag IMG in tre gruppi: il gruppo <strong>pre </strong>contiene
      tutti i caratteri prima dell'attributo ALIGN, il gruppo <strong>align </strong>contiene
      il valore dell'attributo ALIGN, e il gruppo <strong>post </strong>contiene tutti i
      caratteri dopo l'attributo align. Ecco la soluzione in VB e C#:
   </p>
        <p>
          <span style="COLOR: #0000ff; FONT-FAMILY: Microsoft Sans Serif">
            <font face="Courier New">   Dim
      search As String = "&lt;img(?=.*src=\""?http://.*?&gt;)(?=.*\balign=.*?&gt;)(?&lt;pre&gt;[^&gt;]*)\balign=\""?(?&lt;align&gt;[^
      \""]+)\""?(?&lt;post&gt;[^&gt;]*&gt;)"<br />
         Dim replace As String = "&lt;div style=""float:${align}""&gt;&lt;img
      ${pre} ${post}&lt;/div&gt;"<br />
         Dim result As String = Regex.Replace(htmlText, search, replace,
      RegexOptions.IgnoreCase Or RegexOptions.Multiline)</font>
          </span>
        </p>
        <span style="COLOR: #0000ff; FONT-FAMILY: Microsoft Sans Serif">
          <p>
            <span style="COLOR: #0000ff; FONT-FAMILY: Microsoft Sans Serif">
              <font face="Courier New">   string
      pattern = @"&lt;img(?=.*src=\""?http://.*?&gt;)(?=.*\balign=.*?&gt;)(?&lt;pre&gt;[^&gt;]*)\balign=\""?(?&lt;align&gt;[^
      \""]+)\""?(?&lt;post&gt;[^&gt;]*&gt;)";<br />
         string replace = @"&lt;div style=""float:${align}""&gt;&lt;img ${pre}
      ${post}&lt;/div&gt;";<br />
         string result = Regex.Replace(htmlText, search, replace, RegexOptions.IgnoreCase |
      RegexOptions.Multiline);</font>
            </span>
          </p>
        </span>
        <p>
      La cosa notevole non è tanto che questo problema è risolvibile con le regex - lo davo
      per scontato, in effetti - ma che possa essere risolto senza implementare un loop
      o un metodo di callback per il replace.
   </p>
        <img width="0" height="0" src="http://www.dotnet2themax.it/blog/aggbug.ashx?id=78327f62-ab87-4f6b-b296-366aedcb1ab4" />
      </body>
    </content>
  </entry>
  <entry>
    <title>VB Migration Partner è in beta</title>
    <link rel="alternate" type="text/html" href="http://www.dotnet2themax.it/blog/PermaLink,guid,cbed76be-be56-454b-a5a4-a116c7edabcd.aspx" />
    <id>http://www.dotnet2themax.it/blog/PermaLink,guid,cbed76be-be56-454b-a5a4-a116c7edabcd.aspx</id>
    <issued>2007-11-27T05:20:44.0317434-08:00</issued>
    <modified>2007-12-05T11:30:55.1018750-08:00</modified>
    <created>2007-11-27T05:20:44.0317434-08:00</created>
    <author>
      <name>Francesco Balena</name>
    </author>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      VB Migration Partner - il progetto a cui ho lavorato praticamente a tempo pieno negli
      ultimi 22 mesi è finalmente in beta!
   </p>
        <p>
      Cosa faccia questo tool lo dice il suo nome: è un <strong>convertitore di applicazioni
      da VB6 a VB.NET</strong>. Immagino bene che a questo punto molti di voi scrolleranno
      le spalle e penseranno "Ancora VB6?" oppure "Ecco un altro che ci tenta!", ma la verità
      è che VB6 continua a imperversare tra le software house, anche e soprattutto perchè
      non ci sono strumenti decenti per convertire centinaia di migliaia di righe di codice
      VB6 in VB.NET, in modo veloce e (almeno relativamente) indolore. Davanti alla prospettiva
      di sprecare diversi anni uomo di lavoro sulla migrazione di un gestionale VB6 complesso,
      e di dover fare tutto a mano, beh... sono in molti a farsi indietro. Ora però ci si
      sta rendendo conto che la decisione non può più essere rimandata: è risaputo che i
      programmi VB6 non funzionano bene sotto Vista (in particolare, non funzionano molti
      controlli ActiveX) e soprattutto Microsoft ha dichiarato che <a href="http://msdn2.microsoft.com/en-us/vbrun/ms788707.aspx">il
      supporto esteso per VB6 termina a Marzo del 2008</a></p>
        <p>
      Il problema dei convertitori automatici di codice è che quasi mai mantengono le promesse,
      si tratti di conversione da VB6, Java, Delphi, o qualsiasi altro linguaggio. Nel migliore
      dei casi, riescono a convertire circa il 95% delle istruzioni, ma con una applicazione
      VB6 da 100mila righe (quindi neanche estremamente complesse), il 5% di istruzioni
      errate significa dover mettere mano a <strong><i>cinque mila righe</i></strong>! Quel
      che è peggio è che quasi sempre non si tratta di piccole modifiche che prendono qualche
      minuto. Ad es. VB6 e VB.NET espongono due modelli completamente differenti per le
      istruzioni grafiche, il printing, e il drag-and-drop, quindi in realtà anche se il
      compilatore VB.NET segnala relativamente pochi errori, in effetti per implementare
      grafica, printing, e D&amp;D in VB.NET occorrerà rifare intere porzioni di programma.
      Per non parlare di tutti i controlli ActiveX non supportati, il databinding, e tanto
      altro.
   </p>
        <p>
      Nei test che abbiamo eseguito su centinaia di applicazioni VB6 (circa un milione di
      righe di codice in totale), VB Migration Partner offre la notevole media di <strong>un
      errore di compilazione ogni 1,100 righe di codice</strong>, ovvero una percentuale
      di precisione superiore al 99.9%. Scusate se è poco! Del resto, per avere una idea
      della precisione di questo strumento, basta un piccolo elenco delle feature di VB6
      che sono pienamente supportate (eccetto dove indicato) e che sono quasi tutti fuori
      dalla portata di qualsiasi altro strumento sul mercato, incluso ovviamente l’Upgrade
      Wizard incluso in Visual Studio:
   </p>
        <p>
        </p>
        <ul>
          <li>
         array con indice LBound diverso da zero</li>
          <li>
         Gosub, On...Goto, e On ...Gosub</li>
          <li>
         variabili auto-instancing (Dim x As New Person) che mantengono il comportamento anche
         in VB.NET</li>
          <li>
         Declare con parametri As Any e indirizzi di callback (es. EnumWindows)</li>
          <li>
         proprietà di default risolte correttamente anche in modalità late-bound</li>
          <li>
         finalizzazione deterministica per le variabili di tipo Connection, Recordset, ecc.,
         ad es. per ottenere che la connessione sia chiusa quando la variabile è messa a Nothing
         o esce dallo scope</li>
          <li>
         supporto (limitato) per Variant e propagazione dei valori Null</li>
          <li>
         tutti i 60+ controlli di VB6 (uniche eccezioni: OLE e Repeater)</li>
          <li>
         control array, anche di controlli ActiveX di terze parti</li>
          <li>
         menu popup</li>
          <li>
         metodo Controls.Add e oggetti VBControlExtender per creare dinamicamente form di data
         entry</li>
          <li>
         metodi grafici (Line, Circle, PSet, PaintPicture, ecc.) con supporto per ScaleMode
         custom</li>
          <li>
         oggetto Printer e collection Printers</li>
          <li>
         OLE drag-and-drop</li>
          <li>
         UserControl, con supporto di feature avanzate e oggetti Ambient e Extender</li>
          <li>
         data-binding con controlli Data ADO, RDO, ADO, con recordset ADO, con DataEnvironment</li>
          <li>
         classi DataEnvironment non gerarchici 
      </li>
          <li>
         classi e user control ADO data source e simple data consumer</li>
          <li>
         classi MultiUse, PublicNotCreatable, GlobalMultiUse</li>
          <li>
         classi persistable, classi MTS/COM+</li>
        </ul>
        <p>
      In realtà, è più semplice elencare cosa il nostro tool <b><i>non</i></b> supporta:
      gli UserDocument, le PropertyPage, le WebClass, gli DHTML Page designer, istruzioni
      non documentate (VarPtr, ObjPtr, StrPtr), il drag-and-drop “classico” (non OLE D&amp;D),
      e poco altro.
   </p>
        <p>
      VB Migration Partner è in grado di convertire un intero <b>gruppo di progetti VB6</b> in
      una sola operazione, e riesce a generare codice di migliore qualità proprio perchè
      riesce a vedere “dentro” una DLL che fa parte del project group. Il tool dispone anche
      di un <b>code analyzer</b> molto sofisticato, in grado ad esempio di segnalare classi,
      metodi, e variabili non utilizzate: se si considera che in un progetto di grandi dimensioni
      che si è evoluto negli anni molto spesso il 5-10% di codice è “dead code”, si vede
      che questa feature da sola è in grado di far risparmiare parecchio tempo prezioso.
   </p>
        <p>
      Uno dei segreti dell’alto tasso di conversione senza errori è il supporto per i <b>migration
      pragmas</b>. Un pragma di migrazione non è che uno speciale commento inserito nel
      codice VB6 che indica a VB Migration Partner come convertire certi costrutti che permettono
      approcci differenti. Per esempio, il seguente pragma ArrayBounds indica che l’indice
      di tutti gli array nel progetto corrente deve essere forzato a zero:
   </p>
        <pre>
          '##project:ArrayBounds ForceZero
</pre>
        <p>
      I pragma possono avere scope di progetto, di classe, di metodo o di singolo elemento;
      un pragma ha sempre la precedenza su tutti i pragma dello stesso tipo con scope più
      ampio. Per esempio, io posso fare l’override del precedente pragma dentro un metodo,
      e specificare un ulteriore pragma relativo ad uno specifico array:
   </p>
        <pre>
          Sub Test()
             '## ArrayBounds Shift
             '##arr.ForceZero
             Dim names(1 To 10) As String
             Dim values(1 To 10) As Long
             Dim arr(1 To 10) As Integer
          End Sub
</pre>
        <p>
      L’opzione Shift indica a VB Migration Partner che i valori di LBound e UBound dell’array
      devono essere “shiftati” verso lo zero, in modo da preservare il numero di elementi
      dell’array originario in VB6:
   </p>
        <pre>
          Sub Test()
             Dim names(9) As String
             Dim values(9) As Integer
             Dim arr(0 To 10) As Short
          End Sub
</pre>
        <p>
      VB Migration Partner supporta una cinquantina di pragma per gli scope più differenti.
      Ad esempio, SetName modifica il nome di un elemento, SetType il suo tipo, AutoNew
      implementa il comportamento auto-instancing delle variabili As New, AutoDispose fa
      sì che le variabili siano “disposed” correttamente prima di essere impostate a Nothing,
      ecc.
   </p>
        <p>
      Uno dei difetti principali di un tool di conversione “tradizionale” è il fatto che
      – dopo la prima conversione – il progetto originario VB6 e il nuovo progetto VB.NET
      vivono due vite completamente separate. Se la migrazione dura settimane o mesi – com’è
      plausibile per i gestionali di grandi dimensioni – quando finalmente il programma
      VB.NET compila ed esegue senza errori il codice sarà già “vecchio”, ovvero non allineato
      alle modifiche e ai bugfix che nel frattempo sono state apportate al programma VB6.
   </p>
        <p>
      Per evitare questo problema, VB Migration Partner offre il supporto al cosiddetto <b>ciclo
      convert-test-fix</b>. In pratica, si tratta della possibilità di migrare in modo iterativo
      un determinato progetto VB6 raggiungendo lo stadio <i>“zero compilation error”</i> e
      poi <i>“zero runtime error”</i> semplicemente arricchendo il sorgente VB6 con degli
      opportuni pragma, ma senza modificarlo in altro modo. Grazie al ciclo convert-test-fix
      è possibile affrontare migrazioni complesse – che possono durare anche settimane o
      mesi – mantenendo sempre sincronizzati le versioni VB6 e VB.NET della applicazione.
   </p>
        <p>
      Io sono particolarmente contento delle feature del <b>refactoring engine</b>, che
      dopo la prima conversione “grezza” applica al codice VB.NET numerose tecniche di ottimizzazione.
      Ad esempio, è in grado di accorpare la dichiarazione e l’inizializzazione di variabili,
      di generare istruzioni Return, di sfruttare gli operatori composti di assegnazione
      (tipo += e *=), e di altro ancora:
   </p>
        <pre>
Function GetValue() As Long     =&gt;     Function GetValue() As Integer
   Dim x As Long                          Dim x As Integer = 123
   x = 123                                ...
   ...                                    If x &gt; 0 Then
   If x &gt; 0 Then                             Return x
      GetValue = x                        ElseIf x = 0 Then
	  Exit Function                          Return -1
   ElseIf x = 0 Then                      End If
      GetValue = -1                       ...
	  Exit Function                       x += 1
   End If                                 ...
   ...                                 End Function
   x = x + 1
End Function
</pre>
        <p>
      Ci sono altri tipi di refactoring che si possono ottenere mediante opportuni pragma.
      Ad esempio, è possibile inserire la dichiarazione di una variabile dentro un ciclo
      For o For Each, come in questo esempio:
   </p>
        <pre>
Dim i As Integer                =&gt;     For i As Integer = 1 To 100
For i = 1 To 100                          ...
   ...                                 Next
Next
</pre>
        <p>
      Ciliegina sulla torta: nonostante tutte queste feature VB Migration Partner è circa <b>8
      volte più veloce</b> dell’Upgrade Wizard incluso in Visual Studio. Devo dire che mi
      sono tolto una bella soddisfazione!
   </p>
        <p>
      Siamo alla fine di questo lungo post, ma ne seguiranno altri. Potete scoprire tutto
      (ma veramente tutto!) su VB Migration Partner sul nuovo sito <a href="http://www.vbmigration.com/">www.vbmigration.com</a>,
      dove troverete anche molto materiale sulla migrazione <i>tout court</i> nonchè <a href="http://www.vbmigration.com/Blog/default.aspx">il
      mio nuovo blog in inglese</a>, tutto dedicato alle problematiche di migrazione da
      VB6.
   </p>
        <img width="0" height="0" src="http://www.dotnet2themax.it/blog/aggbug.ashx?id=cbed76be-be56-454b-a5a4-a116c7edabcd" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Da non perdere: “la Redmond” che parla italiano</title>
    <link rel="alternate" type="text/html" href="http://www.dotnet2themax.it/blog/PermaLink,guid,cbed76be-be56-454b-a5a4-a116c7ed527d.aspx" />
    <id>http://www.dotnet2themax.it/blog/PermaLink,guid,cbed76be-be56-454b-a5a4-a116c7ed527d.aspx</id>
    <issued>2007-08-01T06:20:44.0317434-07:00</issued>
    <modified>2007-12-05T11:37:37.9768750-08:00</modified>
    <created>2007-08-01T06:20:44.0317434-07:00</created>
    <author>
      <name>Giuseppe Dimauro</name>
    </author>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.microsoft.com/silverlight/default_ns.aspx">
            <b>Silverlight</b>
          </a> in
      primis, ma anche le anteprime di <a href="http://go.microsoft.com/?linkid=7168453">Visual
      Studio 2008</a> e <a href="http://go.microsoft.com/?linkid=7168454">Windows server
      2008</a>, sono solo alcune delle novità che promettono un inverno più caldo di questa
      torrida estate italiana.
   </p>
        <p>
      Un aspetto trascurato, ma che non può lasciarci indifferenti, è che molte di queste
      novità hanno avuto un contributo da rappresentanti del Bel Paese. Sviluppatori, program
      manager, tester, evangelisti, ognuno di questi ruoli è rappresentato anche da italiani
      illustri come Vittorio Bertocci, Marco Ottaviani, il caro Aldo Donetti e molti altri.
      Vi segnalo una iniziativa da non perdere legata al nuovo tag center di <a href="http://channel9.msdn.com/">Channel9</a>: <a href="http://go.microsoft.com/?linkid=7168461">Italia9</a>.
      Vittorio Bertocci, si prodigherà in una serie di interviste, rigorosamente in italiano,
      in giro per il campus di Redmond parlandoci direttamente nella nostra lingua. Grande
      !!! Altre interviste saranno disponibili nei prossimi mesi; in linea è già disponibile
      la prima, fatta a Marco Ottaviani, devlead per le Performance nel Connected Framework
      team (Windows Communication Foundation, Windows Workflow), nella quale Marco ci mostra
      qualche errore tipico in cui si può incorrere quando si cerca di misurare le performance
      di WCF e ci svela quali strumenti utilizza nel suo mestiere.
   </p>
        <p>
      Che dire, un plauso a Vittorio e a tutti quelli che stanno sostenendo questa straordinaria
      inziativa oltre ad un in bocca al lupo per il prosieguo del lavoro a tutti i nostri
      connazionali oltreoceano dei quali essere orgogliosi.
   </p>
        <img width="0" height="0" src="http://www.dotnet2themax.it/blog/aggbug.ashx?id=cbed76be-be56-454b-a5a4-a116c7ed527d" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Anagrammi e regular expression</title>
    <link rel="alternate" type="text/html" href="http://www.dotnet2themax.it/blog/PermaLink,guid,d05d7bd5-5b99-4f96-9f0b-0aa828cc1d37.aspx" />
    <id>http://www.dotnet2themax.it/blog/PermaLink,guid,d05d7bd5-5b99-4f96-9f0b-0aa828cc1d37.aspx</id>
    <issued>2007-06-06T02:30:10.9002500-07:00</issued>
    <modified>2007-12-05T08:33:38.9143750-08:00</modified>
    <created>2007-06-06T02:30:10.9002500-07:00</created>
    <author>
      <name>Francesco Balena</name>
    </author>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Oggi gironzolavo per la rete e ho trovato un <a href="http://discuss.joelonsoftware.com/default.asp?design.4.502229.13">forum </a>dove
      qualcuno poneva la seguente domanda: "<em>data la stringa ABCD è possibile scrivere
      una regular expression che fa il match con un qualsiasi anagramma di tale stringa
      - ad es. DBAC o CDBA ma non ABDE oppure AABC?</em>". Ovviamente la domanda era intrigante
      per uno che come me smanetta molto con le regex, e stranamente non l'avevo mai vista
      in giro. Qualcuno obiettava che le regex non erano abbastanza potenti, e che serviva
      scrivere un piccolo programmino per testare le varie combinazioni, quindi mi sono
      sentito in obbligo di pensarci un po' su e postare la mia soluzione.
   </p>
        <p>
      Se state semplicemente controllando che una stringa fornita dall'utente sia una permutazione
      di ABCD la soluzione è in effetti molto semplice:
   </p>
        <p>
      ^(?=.*a)(?=.*b)(?=.*c)(?=.*d)[abcd]{4}$
   </p>
        <p>
      dove il costrutto <strong>(?=.*a) </strong>si chiama <em>positive lookahead </em>ed
      esegue il match con l'espressione nella parentesi <em>ma senza consumare caratteri</em>,
      quindi in altre parole significa che la stringa deve contenere il carattere A da qualche
      parte, ovvero preceduto da zero o più caratteri. Con le successive espressioni positive
      lookahead si controlla che nella stringa ci siano anche i caratteri B,C e D. Quando
      questa fase è completata, la regex [abcd]{4} assicura che la stringa contenga <strong>solo</strong> questi
      quattro caratteri e non altri.
   </p>
        <p>
      Se invece stiamo cercando tutti i possibili anagrammi di ABCD all'interno di un testo
      di lunghezza qualsiasi, allora la regex è solo leggermente più complicata:
   </p>
        <p>
      \b(?=.{0,3}a)(?=.{0,3}b)(?=.{0,3}c)(?=.{0,3}d)[abcd]{4}\b
   </p>
        <p>
      In questo caso oltre a imporre che i caratteri A,B,C,D siano tutti presenti ci accertiamo
      anche che non distino più di 3 caratteri dall'inizio della parola, e usiamo i delimitatori
      \b per imporre che la parola stessa contenga esattamente quattro caratteri. Ovviamente
      dovete specificare se il case dei caratteri è significativo o meno, perchè il match
      avvenga indipendentemente dal fatto che le parole siano in maiuscolo o minuscolo.
   </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <img width="0" height="0" src="http://www.dotnet2themax.it/blog/aggbug.ashx?id=d05d7bd5-5b99-4f96-9f0b-0aa828cc1d37" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Proteggere gli assembly dalla decompilazione e dalle copie illegali !</title>
    <link rel="alternate" type="text/html" href="http://www.dotnet2themax.it/blog/PermaLink,guid,d40b1b7e-3499-44af-9692-90f37a70bb33.aspx" />
    <id>http://www.dotnet2themax.it/blog/PermaLink,guid,d40b1b7e-3499-44af-9692-90f37a70bb33.aspx</id>
    <issued>2007-06-04T13:06:09.6815000-07:00</issued>
    <modified>2007-06-09T01:24:33.1971250-07:00</modified>
    <created>2007-06-04T13:06:09.6815000-07:00</created>
    <author>
      <name>Francesco Balena</name>
    </author>
  </entry>
  <entry>
    <title>La più grande pagina di errore ASP.NET</title>
    <link rel="alternate" type="text/html" href="http://www.dotnet2themax.it/blog/PermaLink,guid,4f8d02a2-1948-42bb-84bf-ea5e8c5ef7de.aspx" />
    <id>http://www.dotnet2themax.it/blog/PermaLink,guid,4f8d02a2-1948-42bb-84bf-ea5e8c5ef7de.aspx</id>
    <issued>2007-05-14T09:13:40.6261250-07:00</issued>
    <modified>2007-05-14T09:13:40.6261250-07:00</modified>
    <created>2007-05-14T09:13:40.6261250-07:00</created>
    <author>
      <name>Francesco Balena</name>
    </author>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <img src="http://www.dotnet2themax.it/blog/content/binary/Server_error.jpg" border="0" />
        </p>
        <p>
       
   </p>
        <p>
          <img src="http://www.dotnet2themax.it/blog/content/binary/PageNotFound_Error.jpg" border="0" />
        </p>
        <p>
      Sembra siano state scattate nella Silicon Valley e stanno diventando la barzelletta
      tra molti anti-Microsoft-tiani. Le potete trovare a <a href="http://www.tassography.com/ViewPhoto.aspx?CollectionType=Album&amp;CollectionFilter=PhotosInCollection&amp;CollectionID=167&amp;SlideShow=True&amp;PhotoID=1352">questo
      indirizzo</a>.
   </p>
        <p>
      Ovviamente, il problema non è nella tecnologia ma in quanto bene (o male, in questo
      caso) la si usa. Quanto costava controllare meglio gli errori o redirezionarli su
      una pagina più "carina"? Sicuramente meno della brutta figura che la ditta di mobili
      svedese (e non Microsoft) sta facendo. 
   </p>
        <img width="0" height="0" src="http://www.dotnet2themax.it/blog/aggbug.ashx?id=4f8d02a2-1948-42bb-84bf-ea5e8c5ef7de" />
      </body>
    </content>
  </entry>
  <entry>
    <title>TuaPensione.it</title>
    <link rel="alternate" type="text/html" href="http://www.dotnet2themax.it/blog/PermaLink,guid,334c17f5-aaee-4542-b086-a3c7504aad40.aspx" />
    <id>http://www.dotnet2themax.it/blog/PermaLink,guid,334c17f5-aaee-4542-b086-a3c7504aad40.aspx</id>
    <issued>2007-05-09T10:53:49.9698750-07:00</issued>
    <modified>2007-05-09T10:53:49.9698750-07:00</modified>
    <created>2007-05-09T10:53:49.9698750-07:00</created>
    <author>
      <name>Francesco Balena</name>
    </author>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.tuapensione.it/index.html">
            <img src="http://www.dotnet2themax.it/blog/content/binary/LogoTuaPensione.gif" border="0" />
          </a>
        </p>
        <p>
      Ecco un post che ha poco a che fare con la tecnologia e molto a che fare con il lavoro. 
   </p>
        <p>
      Il nostro amico <strong>Eugenio Lamesa</strong>, il migliore esperto che abbiamo in
      Italia di Mail Marketing nonchè la mente dietro il programma/sito <a href="http://www.salesware.it">SalesWare</a> (a
      cui sono orgoglioso di aver contribuito come consulente) ha da poco inaugurato
      il sito <a href="http://www.tuapensione.it/index.html">TuaPensione.it</a>, dedicato
      a chi entro il 30 giugno deve decidere cosa fare del proprio TFR. 
   </p>
        <p>
      Tra le tante iniziative Eugenio ha preparato una <a href="http://www.tuapensione.it/scaricaGuidaTFR.html">whitepaper</a> che
      spiega in modo chiaro e sintetico i dettagli della nuova leggere e come prendere la
      decisione più giusta e conveniente. Non solo le informazioni sono più chiare e dirette
      di quelle che ho potuto leggere su alcuni giornali, ma sono anche depurate dai possibili
      "conflitto di interessi" che abbondano anche in questo settore. Da qualche giorno
      su sito c'è anche un interessante <a href="http://www.tuapensione.it/TFR_SoftwareCalcolo.html">calcolatore
      online</a>, che permette di confrontare le varie opzioni. TuaPensione.it è assolutamente
      no-profit (non ci sono neanche i banner di Google!), come lo è <a href="http://www.menostato.it/">MenoStato.it</a>,
      l'altro sito a cui Eugenio lavora con passione da qualche anno.
   </p>
        <p>
       
   </p>
        <p>
       
   </p>
        <img width="0" height="0" src="http://www.dotnet2themax.it/blog/aggbug.ashx?id=334c17f5-aaee-4542-b086-a3c7504aad40" />
      </body>
    </content>
  </entry>
</feed>