martedì 7 febbraio 2012

[C#] Utilizzare Resources

Descrizione :
Un mio esempio pratico per utilizzare files di Risorse.

+ Articolo :

Argomento sicuramente già molto documentato sul Web.
I Files di Risorsa permettono di incorporare suoni, immagini, testi e quant'altro nell'eseguibile stesso.
Di documentazione in giro ce n'è tanta. Quello che forse manca, a mio avviso, sono esempi chiari e definitivi.
Molti "tutorial" poi, all'atto pratico, non funzionano, oppure utilizzano codice eccessivo, o ancora eseguono percorsi che secondo me si possono evitare tranquillamente.
Perciò inserisco questo semplice Articolo, con la dimostrazione pratica di alcune mie convinzioni sull'argomento :

1. Nessun bisogno di "ricavare" il file dalla Risorsa in cui è stato incluso, andando a ricostruire il nome originario, concatenando il percorso ( Assembly ), il nome, e addirittura l'estensione originaria.

2. Tutto può essere gestito seguendo la semplice logica dei pochi Oggetti e Metodi davvero necessari :
ResourceManager --> ResourceSet --> .GetObject().

3. Un UnmanagedMemoryStream, che è quanto restituito in uscita dalla Risorsa, può essere semplicemente assegnato all'Oggetto che lo deve utilizzare :
--> in VB, direttamente.
--> in C#, con un semplice Cast sul tipo di destinazione richiesto.

4. In particolare, per quanto riguarda l'esecuzione di Stream audio da file, tipicamente .WAV inclusi nelle Risorse, nessun bisogno di dichiarazioni/chiamate API, o peggio  ancora, controlli ActiveX "nascosti" o altro.
Basta un semplice System.Media.SoundPlayer per questo genere di cose, tanto in VB quanto in C#.

Per replicare l'esempio seguente basta una semplice Form "FormMain" con i seguenti controlli :
--> ComboBox : cmb_suoni
--> PictureBox : pbx_img
--> RichTextBox : rtb_testo

A questo punto, se ci si vuole semplificare ulteriormente le cose, si crea un File .resx per ogni gruppo omogeneo di Risorse.
Nel caso dell'esempio in questione :
--> SUONI.resx : SOUND_1.WAV, SOUND_2.WAV, SOUND_3.WAV.
--> IMMAGINI.resx : SOUND_1.jpg, SOUND_2.jpg, SOUND_3.jpg.
--> TESTI.resx : SOUND_1.txt, SOUND_2.txt, SOUND_3.txt.

La figura seguente per definire meglio il concetto :


--> Codice FormMain :

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;
using System.Resources;
using System.Globalization;

namespace UtilizzareResources
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }

        private string nomeProgetto = Assembly.GetExecutingAssembly().GetName().Name;

        private ResourceSet GetResxFiles(string nomeFileResx)
        {
            //Nome Risorsa senza estensione .resx
            ResourceManager RM = new ResourceManager(nomeProgetto + "." + nomeFileResx, Assembly.GetExecutingAssembly());
            ResourceSet RS = RM.GetResourceSet(CultureInfo.InvariantCulture, true, false);
            return RS;
        }

        private object GetResxFile(string nomeFileResx, string nomeRisorsa)
        {
            return GetResxFiles(nomeFileResx).GetObject(nomeRisorsa, true);
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            List<string> listaSuoni = new List<string>();
            foreach (DictionaryEntry DE in GetResxFiles("SUONI"))
            {
                listaSuoni.Add(DE.Key.ToString());
            }
            listaSuoni.Sort();
            cmb_suoni.DropDownStyle = ComboBoxStyle.DropDownList;
            cmb_suoni.Items.AddRange(listaSuoni.ToArray());
            cmb_suoni.SelectedIndex = 0;
        }

        private void cmb_suoni_SelectedIndexChanged(object sender, EventArgs e)
        {
            //Play Risorsa Audio
            using (System.Media.SoundPlayer SP = new System.Media.SoundPlayer())
            {
                SP.Stream = (System.IO.Stream)GetResxFile("SUONI", cmb_suoni.SelectedItem.ToString());
                SP.Play();
            }

            //Assegna Risorsa Immagine
            pbx_img.Image = (Image)GetResxFile("IMMAGINI", cmb_suoni.SelectedItem.ToString());

            //Assegna Risorsa Testo
            rtb_testo.Text = (String)GetResxFile("TESTI", cmb_suoni.SelectedItem.ToString());
        }

    }
}

La soluzione è pulita e funzionante : il ResourceManager genera un ResourceSet, che espone parecchi Metodi utili, tra cui .GetObject(), perciò direi che altro non serve.

+ Fine Articolo.


Un Click su "Mi Piace" è il modo migliore per ringraziare l'autore di questo articolo.



2 commenti:

Giovanni Lacchei ha detto...

E per [VB2010] come si traduce ? io ho inserito nelle resources dei file .Wav come faccio per ciclarli ed inserirli nella CMB ?

MarcoGG ha detto...

Basta che segui attentamente l'Articolo parallelo per VB :
http://marcoggblog.blogspot.com/2012/02/vbnet-utilizzare-resources.html

Posta un commento

 
Design by Free WordPress Themes Modificato da MarcoGG