mercoledì 29 febbraio 2012

download Windows 8

Immagina un nuovo Windows



Oggi è stata rilasciata la versione Consumer Preview (ricordiamo che va installata su macchine virtuale e non di produzione, per evitare problemi al pc) del nuovo sistema operativo Windows.



Windows 8, scaricabile dal seguente sito http://windows.microsoft.com/it-it/windows-8/consumer-preview?ocid=O_MSC_W8P_OandO_Intl_MSCOM_IT-IT e http://windows.microsoft.com/it-IT/windows-8/download è il nuovo sistema operativo Windows 8, in versione beta, non ancora stabile e rilasciata.



Tutti quanti la possono scaricare gratuitamente, per fare dei test.



Ricordiamo di non installarla su macchine di produzione o che utilizziamo per lavoro, ma si consiglia l'installazione su macchine virtuali o pc utilizzati per test.



Che dirvi.. buon divertimento.

venerdì 24 febbraio 2012

Evento gratuito Creativity Day 2012































Torna anche quest'anno il Creativity Day, un evento gratuito dedicato alla creatività.

Nell'evento si parlerà di grafica, del linguaggio Html 5, comunicazione e tanto altro.

Il programma è consultabile al seguente sito http://www.insidesrl.it/creativityday/2012/programma.cfm .

Anche quest'anno si svolgerà a Milano (9 marzo) e Roma (28 marzo).

Per partecipare bisogna registrarsi gratuitamente al seguente indirizzo http://www.insidesrl.it/creativityday/2012/register/location.cfm selezionando la città di proprio interesse.

Per maggiori informazioni, visitate il seguente sito http://www.insidesrl.it/creativityday/2012/index.cfm

mercoledì 22 febbraio 2012

Tutorial XNA creazione di una barra energia

Riporto l'articolo scritto per il sito http://www.iprogrammatori.it/articoli/programmazione/art_xna-–-creazione-di-un-barra-come-indicat_1139.aspx



Introduzione
In questo articolo, vedremo come gestire nei nostri video giochi in XNA, una barra che indica il valore di energia.
Potrebbe tornare utile, per esempio per quei giochi in cui si fa uno di autoveicolo, in cui visualizzare una barra che indica il carburante a disposizione o in quei video giochi in cui due lottatori, si colpiscono e quindi diminuisce la propria energia.
Si crea una barra, come illustrato in figura 1.





Figura 1



A questo punto, si crea un nuovo progetto in XNA, nel progetto, nella sezione content, quella relativa alle risorse, aggiungiamo tale immagini.
Dalla finestra di “Esplora Soluzioni” facciamo click con il tasto destro sulla sezione “Content” e dal menu di scelta rapida, selezioniamo la voce “Aggiungi” e successivamente “Elemento esistente”.
Verifichiamo che è presenta la nostra risorsa.



Stesura di codice
Passiamo alla stesura del codice, nella classe “Game1” dichiariamo due variabili a livello di classe, una di tipo Texture2D che permette di gestire la risorsa ed una di tipo intero, per la gestione del valore per indicare la porzione.
Qui di seguito si riporta la dichiarazione di tali dichiarazioni.



//oggetto per l'immagine indicatore di energia



Texture2D BarraEnergia;



//imposto il valore iniziale della barra



int EnergiaCorrente = 100;





Nell’evento “LoadContent”, scriviamo il codice per quanto concerne il caricamento della risorsa.
Qui di seguito si riporta il codice dell’evento “LoadContent”.



protected override void LoadContent()



{



// Create a new SpriteBatch, which can be used to draw textures.



spriteBatch = new SpriteBatch(GraphicsDevice);





//Carico la risorsa immagine



BarraEnergia = Content.Load<Texture2D>("BarraEnergia");





// TODO: use this.Content to load your game content here



}





Nell’evento “Update” si crea un oggetto di tipo “KeyboardState” per gestire il tasto che è stato digitato, nel caso che è la freccia sinistra, si verifica un decremento di un valore, altrimenti aumento di un valore, l’arco dei valori va da 0 a 100.
Qui di seguito si riporta il codice completo dell’evento Update.




protected override void Update(GameTime gameTime)



{



// Allows the game to exit



if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)



this.Exit();



//gestione dei tasti



KeyboardState Tasto = Keyboard.GetState();



//sposto la barra a destra



if (Tasto.IsKeyDown(Keys.Right ) == true)



{



EnergiaCorrente += 1;



}



//Sposto la barra a sinistra



if (Tasto.IsKeyDown(Keys.Left ) == true)



{



EnergiaCorrente -= 1;



}



//limito un valore tra due misure, ossia tra 0 e 100



EnergiaCorrente = (int)MathHelper.Clamp(EnergiaCorrente, 0, 100);



// TODO: Add your update logic here





base.Update(gameTime);



}





A questo punto scriviamo nell’evento “Draw” il codice che permette di disegnare la barra che indica l’energia disponibile, che è di colore rosso, una barra che indica l’energia che manca (griglio), ed il bordo della barra (nera).
Qui di seguito si riporta il codice delle suddette operazioni.




protected override void Draw(GameTime gameTime)



{



GraphicsDevice.Clear(Color.CornflowerBlue);





// TODO: Add your drawing code here



spriteBatch.Begin();



//disegno la barra quella relativo al valore negativo



spriteBatch.Draw(BarraEnergia, new Rectangle(this.Window.ClientBounds.Width / 2 - BarraEnergia.Width / 2, 30, BarraEnergia.Width, 44), new Rectangle(0, 45, BarraEnergia.Width, 44), Color.Gray);



//Indica il valore positivo, quanta energia



spriteBatch.Draw(BarraEnergia, new Rectangle(this.Window.ClientBounds.Width / 2 - BarraEnergia.Width / 2, 30, (int)(BarraEnergia.Width * ((double)EnergiaCorrente / 100)), 44), new Rectangle(0, 44, BarraEnergia.Width, 44), Color.Red);



//il bordo del rettangolo



spriteBatch.Draw(BarraEnergia, new Rectangle(this.Window.ClientBounds.Width / 2 - BarraEnergia.Width / 2, 30, BarraEnergia.Width, 46), new Rectangle(0, 0, BarraEnergia.Width, 38), Color.Black);





spriteBatch.End();









base.Draw(gameTime);



}



Riportiamo il codice completo della classe Game1



using System;



using System.Collections.Generic;



using System.Linq;



using Microsoft.Xna.Framework;



using Microsoft.Xna.Framework.Audio;



using Microsoft.Xna.Framework.Content;



using Microsoft.Xna.Framework.GamerServices;



using Microsoft.Xna.Framework.Graphics;



using Microsoft.Xna.Framework.Input;



using Microsoft.Xna.Framework.Media;





namespace XnaEnergia



{



/// <summary>



/// This is the main type for your game



/// </summary>



public class Game1 : Microsoft.Xna.Framework.Game



{



GraphicsDeviceManager graphics;



SpriteBatch spriteBatch;



//oggetto per l'immagine indicatore di energia



Texture2D BarraEnergia;



//imposto il valore iniziale della barra



int EnergiaCorrente = 100;





public Game1()



{



graphics = new GraphicsDeviceManager(this);



Content.RootDirectory = "Content";



}





/// <summary>



/// Allows the game to perform any initialization it needs to before starting to run.



/// This is where it can query for any required services and load any non-graphic



/// related content. Calling base.Initialize will enumerate through any components



/// and initialize them as well.



/// </summary>



protected override void Initialize()



{



// TODO: Add your initialization logic here





base.Initialize();



}





/// <summary>



/// LoadContent will be called once per game and is the place to load



/// all of your content.



/// </summary>



protected override void LoadContent()



{



// Create a new SpriteBatch, which can be used to draw textures.



spriteBatch = new SpriteBatch(GraphicsDevice);





//Carico la risorsa immagine



BarraEnergia = Content.Load<Texture2D>("BarraEnergia");





// TODO: use this.Content to load your game content here



}





/// <summary>



/// UnloadContent will be called once per game and is the place to unload



/// all content.



/// </summary>



protected override void UnloadContent()



{



// TODO: Unload any non ContentManager content here



}





/// <summary>



/// Allows the game to run logic such as updating the world,



/// checking for collisions, gathering input, and playing audio.



/// </summary>



/// <param name="gameTime">Provides a snapshot of timing values.</param>



protected override void Update(GameTime gameTime)



{



// Allows the game to exit



if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)



this.Exit();



//gestione dei tasti



KeyboardState Tasto = Keyboard.GetState();



//sposto la barra a destra



if (Tasto.IsKeyDown(Keys.Right ) == true)



{



EnergiaCorrente += 1;



}



//Sposto la barra a sinistra



if (Tasto.IsKeyDown(Keys.Left ) == true)



{



EnergiaCorrente -= 1;



}



//limito un valore tra due misure, ossia tra 0 e 100



EnergiaCorrente = (int)MathHelper.Clamp(EnergiaCorrente, 0, 100);



// TODO: Add your update logic here





base.Update(gameTime);



}





/// <summary>



/// This is called when the game should draw itself.



/// </summary>



/// <param name="gameTime">Provides a snapshot of timing values.</param>



protected override void Draw(GameTime gameTime)



{



GraphicsDevice.Clear(Color.CornflowerBlue);





// TODO: Add your drawing code here



spriteBatch.Begin();



//disegno la barra quella relativo al valore negativo



spriteBatch.Draw(BarraEnergia, new Rectangle(this.Window.ClientBounds.Width / 2 - BarraEnergia.Width / 2, 30, BarraEnergia.Width, 44), new Rectangle(0, 45, BarraEnergia.Width, 44), Color.Gray);



//Indica il valore positivo, quanta energia



spriteBatch.Draw(BarraEnergia, new Rectangle(this.Window.ClientBounds.Width / 2 - BarraEnergia.Width / 2, 30, (int)(BarraEnergia.Width * ((double)EnergiaCorrente / 100)), 44), new Rectangle(0, 44, BarraEnergia.Width, 44), Color.Red);



//il bordo del rettangolo



spriteBatch.Draw(BarraEnergia, new Rectangle(this.Window.ClientBounds.Width / 2 - BarraEnergia.Width / 2, 30, BarraEnergia.Width, 46), new Rectangle(0, 0, BarraEnergia.Width, 38), Color.Black);





spriteBatch.End();









base.Draw(gameTime);



}



}



}





Conclusioni
Ora non ci resta che testare il nostro programma, facendo click sul pulsante "Start" oppure tramite il tasto “F5”, ogni volta che si digita il pulsante freccia sinistra, la barra rossa, diventerà sempre più corta, mentre con il tasto freccia destra aumenterà.
L'articolo ha voluto fornire una delle tante tecniche per la gestione delle informazioni di un determinata situazione, come può essere un soldato la cui energia diminuisce in base ai colpi subiti oppure altre situazioni di gioco.

martedì 21 febbraio 2012

Evento NiDays 2012 - Programmare robot disegnando

Qualche giorno fa, ho riportato la notizia del NiDays 2012 http://emanuelemattei.blogspot.com/2012/02/evento-nidays-2012-evento-sulla.html che si preannuncia come l'evento dell'anno in ambito robotica.
Anche scuola di Robotica, parteciperà a tale evento, con una loro attività.
Riporto la notizia che trovate qui http://www.scuoladirobotica.eu/it/Item/418/Roma%2C%2029%20febbraio%202012.%20NIDays%202012%3A%20Seminario%20di%20Scuola%20di%20Robotica.html


Siamo lieti di invitarvi al seminario gratuito che Scuola di Robotica terrà il 29 febbraio p.v. nell'ambito di NIDays 2012 intitolato "Programmare robot disegnando".NIDays è l'evento annuale organizzato da National Instruments incentrato soprattutto sull'impiego avanzato di LabVIEW. Si terrà il 29 febbraio a Roma.
Il seminario di Scuola di Robotica è dedicato all'impiego di LabVIEW per il riconoscimento di immagini, le quali a loro volta possono essere utilizzate per programmare kit robotici.
In allegato, il Programma del seminario di Scuola di Robotica a NIDays 2012, con le indicazioni per l'iscrizione.
Alcune raccomandazioni.
1. I posto sono limitati, vi preghiamo quindi - se interessati - di iscrivervi subito.2. E' obbligatoria anche l'iscrizione a NIDays (che è gratuita). Qui trovate il Form per la registrazione alla Conferenza3. Una volta iscritti, riceverete tutte le informazioni aggiuntive.
Per iscrivervi inviare una mail con i vostri dati (Nome, cognome, affiliazione, telefono) a
info@scuoladirobotica.it
Scuola di RoboticaDavide CanepaTelefono 348 09 61 616
Il seminario partecipa alla campagna e-skills week coordinata da ECWT (European Center for Women and Technology).

lunedì 20 febbraio 2012

FT: happy hours al museo di zoologia - Anfibi italiani












Il prossimo appuntamento riguardante gli happy hours del museo di zoologia http://www.museodizoologia.it/attivita/incontri-e-convegni-1/happy-hours-al-museo-programma-2011-2012/copy_of_happy2012-anfibi riguarda gli anfibi.
Giovedì 23 febbraio, dalle ore 18 00, presso il museo di zoologia, si svolgerà l'evento gratuito happy hours, in cui l'esperto Massimo Capula, fornirà ai partecipanti, notizie ed informazioni sugli anfibi.
Per partecipare bisogna prenotare al numero indicato nel sito, dove trovate tutte le informazioni relative all'evento.

domenica 19 febbraio 2012

Tutorial Silverlight datagrid parte 6 vb.Net e C#

Riporto l'articolo scritto per il sito http://www.iprogrammatori.it/articoli/programmazione/art_tutorial-silverlight-datagrid-parte-6-vb_1138.aspx





Introduzione
Il tutorial sul controllo Datagrid, che da alcuni mesi stiamo trattando, continua con altre interessanti aspetti, ed in particolare sugli eventi esposti da questo controllo.
Il datagrid, fornisce al programmatore ampia flessibilità e dispone diversi eventi per gestire nel modo migliore i dati.
Riprendendo gli esempi precedenti, vediamo come applicare nel codice precedente nel controllo datagrid, la gestione di alcuni eventi





Stesura di codice
Prendendo l’esempio precedente, selezioniamo il controllo datagrid e nella finestra delle proprietà, selezioniamo l’evento "LoadingRow" il quale si scatena durante il caricamento dei dati nel controllo datagrid.
In questo evento, verifichiamo che il valore nella cella sia uguale al testo “Emanuele” in tal caso, impostiamo di colore rosso la cella che contiene tale valore.









VB.Net





Private Sub DataGrid1_LoadingRow(sender As System.Object, e As System.Windows.Controls.DataGridRowEventArgs) Handles DataGrid1.LoadingRow





'ottengo l'indice della riga





MessageBox.Show(e.Row.GetIndex())





Dim pers As New Persona





pers = CType(e.Row.DataContext, Persona)





If pers.Nome = "Emanuele" Then





'imposto la riga di colore verde





e.Row.Background = New SolidColorBrush(Colors.Green)





'ottengo la cella della prima colonna quella del nome





Dim celle = DataGrid1.Columns(0).GetCellContent(e.Row)





'imposto la cella con il valore, con lo sfondo rosso





Dim cella As DataGridCell = CType(celle.Parent, DataGridCell)





cella.Background = New SolidColorBrush(Colors.Red)





End If





End Sub









C#





private void dataGrid1_LoadingRow(object sender, DataGridRowEventArgs e)





{





//ottengo l'indice della riga





MessageBox.Show(e.Row.GetIndex().ToString());





Persona pers = new Persona();





pers = (Persona)e.Row.DataContext;





if (pers.Nome == "Emanuele")





{





//imposto la riga di colore verde





e.Row.Background = new SolidColorBrush(Colors.Green);





//ottengo la cella della prima colonna quella del nome





var celle = dataGrid1.Columns[0].GetCellContent(e.Row);





//imposto la cella con il valore, con lo sfondo rosso





DataGridCell cella = (DataGridCell)celle.Parent;





cella.Background = new SolidColorBrush(Colors.Red);





}









}












Come si vede dal codice precedente, si crea un oggetto, che corrisponde alla sorgente dati impostata nel controllo datagrid, una volta effettuato il casting della proprietà Datacontext, della proprietà Row, verifichiamo che la proprietà "Nome", contiene il valore “Emanuele”.
In tal caso impostiamo lo sfondo di tutta la riga di colore verde, mentre lo sfondo della cella che contiene il valore lo impostiamo di colore rosso.
L’evento "CellEditEnding" si verifica nel momento in cui è terminata la modifica che si sta compiendo in una determinata cella.
Tramite la proprietà “Cancel” possiamo validare o non la modifica, permettendo di non perdere il focus nella cella.
Qui di seguito si riporta un esempio, per entrambi i linguaggi.








VB.Net





Private Sub DataGrid1_CellEditEnding(sender As System.Object, e As System.Windows.Controls.DataGridCellEditEndingEventArgs) Handles DataGrid1.CellEditEnding





MessageBox.Show(e.Column.Header)





'non permetto che la cella perda il focus





e.Cancel = True





End Sub









C#





private void dataGrid1_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)





{





MessageBox.Show(e.Column.Header.ToString());





//non permetto che la cella perda il focus





e.Cancel = true ;





}












In fine, vediamo un altro evento, riguardante la digitazione del testo nella cella.
Tramite l’evento "keydown", possiamo verificare il carattere digitato, per esempio nel caso che abbiamo una colonna relativa ai nomi e cognomi delle persone, possiamo verificare che il testo inserito nella cella, è solo un lettera, anziché un numero o altro.
Tramite la proprietà Key, dell’oggetto “KeyEventArgs”, verifichiamo che tipo di carattere è stato digitato. La proprietà “Handled”, impostata a true, permette di non validare il carattere e quindi la mancanza di inserire il carattere digitato.
Riportiamo qui di seguito un esempio di codice che verifica il carattere digitato.








VB.Net





Private Sub DataGrid1_KeyDown(sender As System.Object, e As System.Windows.Input.KeyEventArgs) Handles DataGrid1.KeyDown





If e.Key < Key.A Or e.Key > Key.Z Then





e.Handled = True





End If





End Sub









C#





private void dataGrid1_KeyDown(object sender, KeyEventArgs e)





{





if (e.Key < Key.A e.Key > Key.Z )





{





e.Handled = true;





}





}








Conclusioni
L’articolo ha fornito alcuni elementi di base sull’utilizzo degli eventi del controllo datagrid, un controllo dotato di tantissimi eventi, fornendo al programmatore, ampia scelta e completa libertà e flessibilità.
Non è difficile gestire in maniera adeguata la gestione dei dati, tramite questo controllo, visto le potenzialità offerte possiamo lavorare in maniera ottimale sui dati.
Gli eventi offerti da questo controllo sono variati, lasciamo al lettore di scoprire gli altri eventi.



A questo indirizzo http://emanuelemattei.blogspot.com/2012/01/tutorial-datagrid-silverlight-parte-5.html trovate la quinta parte del tutorial.

sabato 18 febbraio 2012

Caratteri speciali (ASCII) HTML

Oggi segnaliamo un simpatico sito italiano, in cui sono riportati i caratteri speciali in html.Il sito http://www.caratterispecialihtml.com/ fornisce un elenco di caratteri speciali, riguardante il codice html, per includerli nelle proprie pagine web. Utile per coloro che scrivono siti internet.

venerdì 17 febbraio 2012

c# formattazione data eval databinding

Qui di seguito si riporta un esempio, di come formattare la data (giorno, mese ed anno) in un campo di tipo data Binding con l'utilizzo di Eval .
Nella pagina Aspx, può capitare di caricare in determinate parti della pagina, delle informazioni tramite databing.
Qui l'esempio per formattare la data.

<%# Eval("NomeCampo", "{0:dd-MM-yyyy}")%>

giovedì 16 febbraio 2012

Silverlight 5 stampare una pagina

Si riporta l'articolo scritto per il sito http://www.iprogrammatori.it/articoli/programmazione/art_silverlight-5-la-stampa-tramite-vbnet-e-_1140.aspx



Introduzione
In questo articolo, vedremo come applicare nelle nostre applicazioni la stampa.
Con la tecnologia Silverlight, dalla versione 4 sono state introdotte diverse classi, tra queste quella relativa alla stampa.
Vedremo, come in VB.Net e C# poter effettuare delle stampe.



Stesura di codice
Si crea un nuovo progetto in Silverlight 5, si aggiunge nella pagina un controllo image ed un pulsante, per il controllo image, impostiamo un file immagine, e come nome il seguente valore “imgFoto
“ per la proprietà “Name”.
Il pulsante avrà la proprietà name impostata con il seguente valore “btnStampa
“ e la proprietà “Content” con il seguente valore “Stampa
“ .
Qui di seguito si riporta il codice del file XAML.



<Grid x:Name="LayoutRoot" Background="White">



<Button Content="Stampa" Height="23" HorizontalAlignment="Left" Margin="270,10,0,0" Name="btnStampa" VerticalAlignment="Top" Width="75" />



<Image Height="259" HorizontalAlignment="Left" Margin="10,10,0,0" Name="imgFoto" Opacity="1" Source="/SLPrint;component/Images/FileImg.jpg" Stretch="UniformToFill" VerticalAlignment="Top" Width="243" />



</Grid>





Passiamo in visualizzazione codice, per scrivere il codice che permette di effettuare la stampa.
Per utilizzare le classi per la stampa, dobbiamo aggiungere lo spazio dei nomi per la stampa, qui di seguito si riporta il codice di tali operazioni




VB.Net



'per la stampa



Imports System.Windows.Printing





C#



//per la stampa



using System.Windows.Printing;





Terminata tale operazioni, si crea un oggetto a livello di classe riguardante la classe “PrintDocument” il quale tramite il metodo Print stamperà il file.
Dichiariamo tale membro nel seguente modo.




VB.Net



Dim stampa As PrintDocument





C#



PrintDocument stampa;



Nel costruttore, dopo l’inizializzazione, impostiamo il nostro membro e si creano i gestori di eventi per questa classe.
Nel costruttore scriviamo il seguente codice.



VB.Net



Public Sub New()



InitializeComponent()



stampa = New PrintDocument



AddHandler stampa.PrintPage, AddressOf stampa_PrintPage



AddHandler stampa.EndPrint, AddressOf stampa_EndPrint





End Sub





C#



public MainPage()



{



InitializeComponent();



stampa = new PrintDocument();



//gestore di evento



stampa.PrintPage += new EventHandler<PrintPageEventArgs>(stampa_PrintPage);



stampa.EndPrint += new EventHandler<EndPrintEventArgs>(stampa_EndPrint);





}



Qui di seguito si riporta il codice relativo all’evento PrintPage, che si verifica nel momento in cui viene eseguita la stampa.
Nell’evento, viene passato alla proprietà “PageVisual” la nostra griglia contenente i controlli, possiamo anche effettuare la stampa dei singoli controlli.
Qui di seguito si riporta il codice per la stampa di tutto ciò che si trova nella form.



VB.Net



Private Sub stampa_PrintPage(sender As Object, e As PrintPageEventArgs)



btnStampa.Visibility = System.Windows.Visibility.Collapsed



e.PageVisual = LayoutRoot





End Sub







C#



void stampa_PrintPage(object sender, PrintPageEventArgs e)



{



btnStampa.Visibility = System.Windows.Visibility.Collapsed;



e.PageVisual = LayoutRoot;



}



Qui di seguito il codice per la stampa del singolo controllo.



VB.Net



Private Sub stampa_PrintPage(sender As Object, e As PrintPageEventArgs)



e.PageVisual = imgFoto



End Sub





C#



void stampa_PrintPage(object sender, PrintPageEventArgs e)



{



e.PageVisual = imgFoto;



}







Nell’evento “EndPrint”, scriviamo il codice per verificare che la stampa è andata a buon fine oppure si è verificato un errore, e la visualizzazione del pulsante, che durante l’evento di stampa abbiamo nascosto per evitare la relativa stampa.
Qui di seguito si riporta il codice completo dell’evento “EndiPrint”.




VB.Net



Private Sub stampa_EndPrint(sender As Object, e As EndPrintEventArgs)



If Not e.Error Is Nothing Then MessageBox.Show(e.Error.Message)



btnStampa.Visibility = System.Windows.Visibility.Visible



End Sub





C#



void stampa_EndPrint(object sender, EndPrintEventArgs e)



{



if (e.Error != null)



MessageBox.Show(e.Error.Message);





btnStampa.Visibility = System.Windows.Visibility.Visible;





}







Conclusioni
Ora non ci resta che eseguire la nostra applicazione e fare delle proved di stampa.
Con la versione 4 e la versione 5 da poco rilasciata, nella tecnologia Silverlight ci sono notevole funzionalità, migliorando di molto questa tecnologia. Con la classe per la stampa possiamo dotare le nostre applicazioni ulteriore professionalità.