Tips&Tricks I trucchi del mestiere

 

Come validare un indirizzo e-mail con le Regular Expression

Un tip dedicato al riconoscimento della corretta sintassi di un indirizzo e-mail. Il tutto si basa su di una funzione legata all'uso delle "Regular Expression" (molto familiari ai masticatori del C, del Perl, ecc.) che riducono lo script a poche righe di codice.
Tip fornito dal Sig. M.Luciani

<%
Function IsMail(sEmail) 
  Dim objRegExp
  Set objRegExp = New RegExp
  objRegExp.Pattern = "^[a-z._-]+\@[a-z._-]+\.[a-z]{2,4}$"
  objRegExp.IgnoreCase = True 
  IsMail = objRegExp.Test(sEmail)
End Function 

Dim strEmail

strEmail = "webmaster@byluciani.com"

If IsMail(strEmail) Then
  Response.Write strEmail & _
                 " Φ un indirizzo email sintatticamente corretto"
Else
  Response.Write strEmail & _
                 " NON Φ un indirizzo email sintatticamente corretto"
End If
%>

Email a Go Go

Il tip proposto consente di spedire molto velocemente email; la parte di codice allegata funziona sia rinominato in .vbs che in moduli di access, macro di excel, pagine ASP. PerchΦ l'esempio funzioni occorre modificare l'indirizzo del server web e gli indirizzi di destinazione. Nell'esempio viene spedita via mail una pagina web, comprensiva di immagini, hyperlink ecc. E' molto veloce, consente di cambiare destinatario e spedire la stessa mail senza riconfigurare nulla. Il tip funziona in qualsiasi ambiente di scripting microsoft (vbs, asp, vba, vb). Ideale per mailing list. Con un server smtp locale, con un PIII a 800 mhz si possono passare le 10 mail al secondo.
Tip fornito dal sig. M.Piccinini

'Definizioni per CDO
dim cdoSendUsingMethod, cdoSendUsingPort,cdoSMTPServer,cdoSMTPServerPort,cdoSMTPAuthenticate,cdoAnonymous,cdoSuppressNone
cdoSendUsingMethod = "http://schemas.microsoft.com/cdo/configuration/sendusing"
cdoSendUsingPort = 2
cdoSMTPServer = "http://schemas.microsoft.com/cdo/configuration/smtpserver"
cdoSMTPServerPort = "http://schemas.microsoft.com/cdo/configuration/smtpserverport"
cdoSMTPAuthenticate = "http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"
cdoAnonymous = 0
cdoSuppressNone = 0

' invio una mail di prova
Dim oConf , oMail , oFlds , oAtt 

Set oMail = CreateObject("CDO.Message")
Set oConf = CreateObject("CDO.Configuration")
Set oFlds = oConf.Fields
oFlds(cdoSendUsingMethod) = cdoSendUsingPort
oFlds(cdoSMTPServer) = "mioServerSmtp"
oFlds(cdoSMTPServerPort) = 25
oFlds(cdoSMTPAuthenticate) = cdoAnonymous
oFlds.Update
Set oMail.Configuration = oConf

oMail.From = "MioMailer <io@mioprovider.it>"
oMail.Subject  = "Prova CDO"
oMail.CreateMHTMLBody "http://www.itportal.it", cdoSuppressNone

oMail.To = "Indirizzo1@provider1.it"
oMail.Send 

oMail.To = "Indirizzo2@provider2.it"
oMail.Send 

' etc etc etc

set oConf = Nothing
set oflds = Nothing
set oMail = Nothing


Come personalizzare WinAMP

Un tip di fondamentale importanza per tutte quelle persone che voglioni realizzare 'in casa' alcune versioni modificate del player mp3 pi∙ noto di tutti i tempi, oppure per chiunque intenda aggiungere un supporto esteso di playing mp3 nelle sue realizzazioni.
Tip fornito dal sig. S.Paganotti

La prima cosa da fare Φ identificare la finestra di winamp (estendendo la soluzione si potrebbe anche utilizzare una API di windows per lanciare winamp dallo stesso programma); l'identificazione avviene semplicemente nel seguente modo:

HWND winamp;
winamp = FindWindow("Winamp v1.x",NULL);

a questo punto i comandi eseguibili sono tantissimi, di seguito sono elencati solo i pi∙ utili, i comandi vengono inviati a winamp tramite l'API SendMessage:

SendMessage(winamp, WM_COMMAND,40045,0);
Simula la pressione del tasto "play" di winamp, eseguendo il primo brano
della playlist.
 
SendMessage(winamp,WM_WA_IPC,playlistpos,121);
Winamp esegue il brano alla posizione specificata dalla 
variabile 'playlistpos'

Ed ecco un utilissimo comando che permette di aggiungere un file alla playlist di winamp:

COPYDATASTRUCT cds;
cds.dwData = 100;
cds.lpData = (void *) "file.mp3";
cds.cbData = strlen((char *) cds.lpData)+1; // include space for null char
SendMessage(winamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds)

Esistono tantissimi altri comandi per richamare praticamente tutte le funzionaliα di winamp, utilissimo a questo fine Φ il file frontend.h che si trova direttamente sul sito di winamp e che Φ allegato al supporto CDr-Rom della rivista


La serializzazione XML con C#


.NET mette a disposizione due metodi, Serialize e Deserialize, che permettono di leggere e scrivere XML in modo trasparente. Grazie, infatti, alla programmazione per attributi Φ possibile identificare ciascun membro di una classe con un elemento dello schema XML. All'atto della serializzazione della classe genererα un file XML che segue lo schema pre-definito con i valori dei vari attributi pari ai valori delle variabili membro delle classi. La lettura di un file XML avviene con il metodo Deserialize che non fa altro che assegnare ad ogni variabile membro della classe, il valore corrispondente del tag xml. Trovate il progetto completo nella directory /tips del Cd-Rom allegato o digitando l'url: www.itportal.it/ioprog71/tips Tip fornito dal Sig. D.Camassi


Shutdown di Windows...e non solo


Con questa procedura Φ possibile avere accesso alla libreria user32.dll per poter agire sull'uscita di Windows. E' possibile settare la procedura per: terminare bruscamente il sistema, riavviare, spegnere il computer, fare lo shutdown di sistema o semplicemente il logoff. Tip fornito dal Sig. P.Failla

//-------------------------------------------
 
E' necessario includere tra gli header winuser.h


void __fastcall TForm1::ShutDown(TObject *Sender)
{
        HANDLE hToken;
        TOKEN_PRIVILEGES tkp; //definisce una struttura che contiene il settaggio dei privilegi per il token


        // Prendo un token per questo processo.
       
        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))             
        //"OpenProcessToken" apre l'accesso a un token associato con un processo
        //"GetCurrentProcess" ritorna un pseudohandle per il processo corrente
        //"TOKEN_ADJUST_PRIVILEGES" abilita o disabilita i privilegi di accesso del token
        
        error("OpenProcessToken"); //o un'altra procedura di gestione errori
                
        // Prendo il LUID (Locally Unique IDentifier) per i privilegi di shutdown.
        
        LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        
        //"SE_SHUTDOWN_NAME" Φ il privilegio richiesto per spegnere una macchina locale
        // Prende i privilegi per questo processo
        
        AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
        
        //"AdjustTokenPrivileges" abilita o disabilita i privilegi di accesso del token
        
        if (GetLastError() != ERROR_SUCCESS)
        error("AdjustTokenPrivileges"); //o un'altra procedura di gestione errori
                
        //Chiudo il sistema e forzo la chiusura delle applicazioni
        
        if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0))
        error(ExitWindowsEx); //o un'altra procedura di gestione errori
        
        //"ExitWindowsEx" gestisce l'uscita da un sistema Windows supporta 5 tipi di parametri flag
        //" bool ExitWindowsEx (UINT flag, DWORD reserved); " 
        //"EWX_FORCE" forza la terminazione dei processi Windows non manda i messaggi di fine 
        //            sessione e il sistema termina drasticamente con possibili perdite di dati
        //"EWX_LOGOFF" termina i processi e fa il Logoff
        //"EWX_POWEROFF" termina i processi e spegne il computer
        //"EWX_REBOOT" riavvia
        //"EWX_SHUTDOWN" termina i processi e mette il computer in attesa di power off   
        
}

E' necessario includere tra gli header winuser.h

Void __fastcall TForm1::ShutDown(TObject *Sender)
{
        HANDLE hToken;
        TOKEN_PRIVILEGES tkp; //definisce una struttura che contiene il settaggio dei privilegi per il token


        // Prendo un token per questo processo.
       
        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))             
        //"OpenProcessToken" apre l'accesso a un token associato con un processo
        //"GetCurrentProcess" ritorna un pseudohandle per il processo corrente
        //"TOKEN_ADJUST_PRIVILEGES" abilita o disabilita i privilegi di accesso del token
        
        error("OpenProcessToken"); //o un'altra procedura di gestione errori
                
        // Prendo il LUID (Locally Unique IDentifier) per i privilegi di shutdown.
        
        LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        
        //"SE_SHUTDOWN_NAME" Φ il privilegio richiesto per spegnere una macchina locale
        // Prende i privilegi per questo processo
        
        AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
        
        //"AdjustTokenPrivileges" abilita o disabilita i privilegi di accesso del token
        
        if (GetLastError() != ERROR_SUCCESS)
        error("AdjustTokenPrivileges"); //o un'altra procedura di gestione errori
                
        //Chiudo il sistema e forzo la chiusura delle applicazioni
        
        if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0))
        error(ExitWindowsEx); //o un'altra procedura di gestione errori
        
        //"ExitWindowsEx" gestisce l'uscita da un sistema Windows supporta 5 tipi di parametri flag
        //" bool ExitWindowsEx (UINT flag, DWORD reserved); " 
        //"EWX_FORCE" forza la terminazione dei processi Windows non manda i messaggi di fine 
        //            sessione e il sistema termina drasticamente con possibili perdite di dati
        //"EWX_LOGOFF" termina i processi e fa il Logoff
        //"EWX_POWEROFF" termina i processi e spegne il computer
        //"EWX_REBOOT" riavvia
        //"EWX_SHUTDOWN" termina i processi e mette il computer in attesa di power off   
        
}


Controllare i processi di un PC remoto

Un tip che consente di ottenere la lista dettagliata dei processi attivi su un PC remoto. Il nome del computer Φ specificato dalla costante "COMPUTER"; con il punto si specifica il PC locale. L'esempio utilizza WMI, per cui Φ necessario che sia installato sia sul PC locale che su quello remoto.
Tip fornito dal sig. R.Cirillo

Procedure TForm1.Button1Click(Sender: TObject);
Const
        QUERY    = 'Select * From Win32_Process';
        COMPUTER = 'SERVER-AT12K';
Var
        Services  : SWbemServices;
        ObjectSet : ISWbemObjectSet;
        Enum      : IEnumVariant;
        tempObj   : OleVariant;
        SObject   : ISWbemObject;
        Value     : Cardinal;
Begin
        Services := Locator.ConnectServer(COMPUTER, 'root\cimv2', '', '', '',
                                          '', 0, nil);
        ObjectSet := Services.ExecQuery(QUERY, 'WQL',
                                        wbemFlagReturnImmediately, nil);
        Enum := (ObjectSet._NewEnum) As IEnumVariant;
        While (Enum.Next(1, TempObj, Value) = S_OK) Do
        Begin
                SObject := IUnknown(TempObj) As SWBemObject;
                Memo1.Lines.Add(SObject.GetObjectText_(0))
        End;
End;


Come personalizzare i componenti Delphi senza scriverne di nuovi

Esiste la possibilitα di personalizzare i componenti senza doverne scriverne di nuovi. Basta definire due nuovi tipi all'interno della unit, uno definisce un'alias al tipo del componente che vogliamo personalizzare, l'atro Φ una classe che si chiama come il componente ed eredita dall'alias specificato. In questo modo alla nuova classe possiamo aggiungere metodi e proprietα che verranno utilizzati all'interno del codice e saranno disponibili (non in design mode), per ogni componente di quel tipo.
Tip fornito dal sig. A.Albergoni

type
	TMyEdit	= TEdit;
	TEdit = class(TMyEdit)
	private
		function lfFloat : real;
		procedure lpFloat(lrValue : real);
	public
		property AsFloat : real read lfFloat write lpFloat;
	end;
	
	TForm1 = class(TForm)
		btnSqrt: TButton;
		edtValue: TEdit;
		procedure btnSqrtClick(Sender: TObject);
	end;

var
  Form1: TForm1;

implementation
function TEdit.lfFloat : real;
begin
	try
		Result	:= StrToFloat(Text);
	except
		Result	:= 0;
	end;
end;

procedure TEdit.lpFloat(lrValue : real);
begin
	Text	:= FloatToStr(lrValue);
end;

{$R *.dfm}

procedure TForm1.btnSqrtClick(Sender: TObject);
begin
	edtValue.AsFloat	:= Sqrt(edtValue.AsFloat);
end;


Limitare il movimento del mouse

Un semplice ma efficace "trucco" in Delphi che permette di confinare il mouse entro un'area rettangolare dello schermo definita dall'utente.
Tip fornito dal Sig. R.Grassi

procedure Limita_Mouse(Sx,Alto,Dx,Basso:Integer); 
/* Questi valori rappresentano i punti in alto a sinistra e in basso a destra del rettangolo entro cui si va a confinare il mouse */ 
var
 Area: TRect;
begin
  Area.Left:=Sx;
  Area.Top:=Alto;
  Area.Right:= Dx;
  Area.Bottom:= Basso;
  ClipCursor(@Area); 
end;

Per far tornare il mouse al suo stato "normale":

ClipCursor(nil);


Estrarre da un file ZIP


Dopo aver visto il il tip da Voi proposto nel mese di maggio, che mostrava come creare file zip compressi, ho programmato questa classe, che permette di estrarre una serie di file (non solo uno) da un archivio ZIP. Vi allego una piccola applicazione realizzata con interfaccia grafica awt che presenta una possibile implementazione di questa classe.
Tip fornito dal Sig. G.Rota

Ecco la classe principale:

//Classe unzipFile
class unzipFile {
 
    //Stream file sorgente (zip)
    FileInputStream sorgStream=null;
    //Stream file di destinazione
    FileOutputStream destStream=null;
    //Buffer input
    BufferedInputStream sorgStreamBuff=null;
    //Buffer output
    BufferedOutputStream destStreamBuff=null;
    //Stream per leggere da un file .zip
    ZipInputStream zipIn=null;
    //Zip entry
    ZipEntry zipEntry=null;
    //Array dati
    byte[] data=new byte[2048];
    //Stringa destinazione completa
    String destCompleta=null;
 
 
 
//sorg deve essere un percorso del tipo c:\prova.zip; dest deve essere un percorso di tipo c:\unzip\

    public void unzipFromTo(String sorg, String dest) {
 
        //Apertura stream di lettura
        try {
            //Apre stream di lettura
            sorgStream=new FileInputStream(sorg);
            //Apre buffer
            sorgStreamBuff=new BufferedInputStream(sorgStream);
        } catch (IOException e) {
            System.out.println("Errore durante l'apertura degli stream");
        }
 
        //Apertura ZipInputStream
        zipIn=new ZipInputStream(sorgStreamBuff);
 

        //Catch per posizionamento nell'entry da leggere
        try {
            //Apre entry ed esce dal ciclo se non ce ne sono pi∙
            while((zipEntry=zipIn.getNextEntry())!=null) {
 
                //Creazione del percorso del file in cui estrarre l'entry del file zip
                //concatenando il valore di ritorno di ZipEntry.getName() e la cartella scelta dall'utente
                destCompleta=dest + zipEntry.getName();
 

                //Apre stream di scrittura
                destStream=new FileOutputStream(destCompleta);
                //Apre buffer
                destStreamBuff=new BufferedOutputStream(destStream);
 

                //Lettura zip e scrittura file decompresso
                int count;
 
                //Legge 2048 byte dal file zip e controlla EOF
                while((count=zipIn.read(data,0,2048))!=-1) {
                    //Scrive su disco i dati decompressi
                    destStreamBuff.write(data,0,count);
                }
 
                //Chiude entry corrente
                zipIn.closeEntry();
                //Chiude file stream di output
                destStreamBuff.close();
                destStream.close();
            }
 
        } catch(IOException e) {
            System.out.println("Errore estrazione file.");
        }
 

        try {
        //Chiusura file stram e zip stream
        zipIn.close();
        sorgStreamBuff.close();
        } catch(IOException e) {
            System.out.println("Errore chiusura");
        }
    }
}


Eseguire un comando di sistema in Java


Come eseguire un comando, in java, che abbia un argomento con all'interno uno spazio. Esempio: windows - type "nome file.txt" Linux - cat 'nome file.txt' Sia le virgolette, sia gli apicetti che il carattere speciale \ prima dello spazio, non funzionano con Runtime.exe(), poichΦ quest'utilma fa uso della StringTokenizer per leggere la stringa di comando. La risposta a questo quesito Φ quello di utilizzare "un'altra" Runtime.exe; quella che prende come parametro un vettore di Stringhe. Ad essa bisogna passare la linea di comando giα suddivisa in token.
Tip fornito dal sig. Addisu Matusala

String [] comando={"cat","nome file.txt"};
Runtime.getRuntime().Exec(comado);



Script in cascata


Se si vuole inserire in una pagina HTML uno Javascript che, per mezzo della funzione "document.write", genera un nuovo documento HTML che richiami dei nuovi script in cascata, ci si imbatte nel problema che il browser interpretando tali istanze annulla l'operazione. Per ovviare a questo problema si deve scomporre la chiamata allo script in cascata suddividendo la parola chiave stessa come mostrato nel tip.
Tip fornito dal Sig. L.Bertapelle

<script language="javascript">
    document.write("<sc"+"ript LANGUAGE=\"JavaScript\" SRC=\"...\"> </sc"+"ript>");
</script>



Un approfondimento del Tip "Pass-by-Value e Pass-By-Reference"


Un tip per evitare comportamenti non desiderati nelle proprie applicazioni, gestendo in modo ottimale il "Pass-by-Value e Pass-By-Reference"; in particolare il passaggio dei dati "By Reference" non funziona come tale nelle applicazioni che utilizzano RMI; per meglio comprendere il problema si consideri un metodo di un'interfaccia come il seguente "cambiaAttributo (MioOggetto mioOggetto).
Tip fornito dal Sig. M.Barbaro

import java.rmi.*;
public interface Libreria extends Remote
{
    public void cambiaAttributo(MioOggetto mioOggetto) throws RemoteException;
    àà
}

àà // fine classe

import java.io.Serializable;
public class MioOggetto implements Serializable
{
   public String nome;
   public MioOggetto(String nome)
   {
      this.nome = nome;
   }
   public void setNome(String nome)
   {
      this.nome = nome;
   }
   public String getNome()
   {
     return this.nome;
   }
}

àà // fine classe

Se un programma cliente in un'ipotetica applicazione client/server come il seguente:


import java.rmi.*;

public class Cliente
{
   public static void main(String args[])
   {
      ......
      try
      {
         MioOggetto mioOggetto = new MioOggetto("Marco");
         Libreria libreria = (Libreria) Naming.lookup("rmi://127.0.0.1:1099/istanzalibreria"); // Si suppone un oggetto servente abbia memorizzato nel RMIRegistry un istanza di Libreria con il nome indicato.
         libreria.cambiaAttributo(mioOggetto);
         System.out.println("Nome : " + mioOggetto.getNome());        
      } // end try
    catch(Exception e)
    {
    }
}

}

intende utilizzare una classe che implementa l'interfaccia "Libreria" e il relativo metodo "cambiaAttributo (MioOggetto mioOggetto)" desiderando che vengano apportate delle modifiche all'istanza dell'oggetto di tipo MioOggetto passato al metodo, occorre sapere che la comunicazione tramite RMI fa si che l'oggetto servente effettui una copia in locale dell'oggetto ricevuto come parametro del metodo e che ogni modifica effettuata su quell'oggetto ha effetto esclusivamente su quella copia e non sull'istanza di mioOggetto nella classe Cliente. Nel caso in esempio se l'implementazione di cambiaAttributo utilizzata dalla nostra applicazione fosse stata del tipo:

à
public void cambiaAttributo(MioOggetto mioOggetto)
{
   mioOggetto.setNome("Pippo");
}
à

al termine dell'esecuzione del programma Cliente l'istruzione System evidenziata avrebbe stampato:

Nome : Marco

Soluzione.
Per ovviare quindi a questo tipo di problemi, una soluzione Φ far si che il metodo dell'interfaccia dell'oggetto remoto che si intende utilizzare restituisca un'istanza dell'oggetto che si intendeva passare per riferimento (e di cui quindi si voleva modificare il valore):

public interface Libreria extends Remote
{
    public MioOggetto cambiaAttributo(MioOggetto mioOggetto) throws RemoteException;
    àà
}

Ecco anche come modificare il programma Cliente:

import java.rmi.*;

public class Cliente
{
   public static void main(String args[])
   {
      ......
      try
      {
         MioOggetto mioOggetto = new MioOggetto("Marco");
         Libreria libreria = (Libreria) Naming.lookup("rmi://127.0.0.1:1099/istanzalibreria");
         mioOggetto = libreria.cambiaAttributo(mioOggetto);
         System.out.println("Nome : " + mioOggetto.getNome());        
      } // end try
    catch(Exception e)
    {
    }
}

}

Ed ecco infine come Φ modificata l'implementazione del metodo "cambiaAttributo(MioOggetto)":

à
public MioOggetto cambiaAttributo(MioOggetto mioOggetto)
{
   mioOggetto.setNome("Pippo");

   return mioOggetto;
}
à

L'esecuzione del programma Cliente modificato stamperα il seguente messaggio come volevasi dimostrare:

Nome : Pippo


Controllare i processi di un PC remoto


Un tip che consente di ottenere la lista dettagliata dei processi attivi su un PC remoto. Il nome del computer Φ specificato dalla costante "COMPUTER"; con il punto si specifica il PC locale. L'esempio utilizza WMI, per cui Φ necessario che sia installato sia sul PC locale che su quello remoto.
Tip fornito dal sig. R.Cirillo

Procedure TForm1.Button1Click(Sender: TObject);
Const
        QUERY    = 'Select * From Win32_Process';
        COMPUTER = 'SERVER-AT12K';
Var
        Services  : SWbemServices;
        ObjectSet : ISWbemObjectSet;
        Enum      : IEnumVariant;
        tempObj   : OleVariant;
        SObject   : ISWbemObject;
        Value     : Cardinal;
Begin
        Services := Locator.ConnectServer(COMPUTER, 'root\cimv2', '', '', '',
                                          '', 0, nil);
        ObjectSet := Services.ExecQuery(QUERY, 'WQL',
                                        wbemFlagReturnImmediately, nil);
        Enum := (ObjectSet._NewEnum) As IEnumVariant;
        While (Enum.Next(1, TempObj, Value) = S_OK) Do
        Begin
                SObject := IUnknown(TempObj) As SWBemObject;
                Memo1.Lines.Add(SObject.GetObjectText_(0))
        End;
End;

Visual Basic .NET - Menu facili con XML


Un tip che permette di costruire la barra dei menu di una Form leggendo le informazioni da un file XML.
Il tip si compone essenzialmente di una classe e di una interfaccia. La classe MenuBuilder legge il file XML e crea la struttura del menu, mentre l'interfaccia IActionMenu prevede un metodo Performed che Φ l'handler dell'evento click di una voce di menu.
Il documento XML prevede un elemento radice MAINMENU che pu≥ avere uno o pi∙ figli MENUITEM che possono a loro volta avere figli MENUITEM. Per ogni MENUITEM posso specificare l'etichetta (con LABEL) e la classe che deve gestire l'evento clic (con ACTION).
L'esempio che potrete trovare nel Cd-Rom allegato si compone di tre classi (OpenAction, NewAction, ExitAction) che implementano l'interfaccia e si limitano a visualizzare una MessageBox (Φ incluso un file XML con la definizione di un menu). La classe MenuBuilder comunque pu≥ essere personalizzata (e lo stesso vale per lo schema del file XML) per supportare altre funzionalitα, come lo stato di abilitazione e la gestione di altri eventi.
Trovate il progetto completo nella directory /tips del Cd-Rom allegato o digitando l'url: www.itportal.it/ioprog71/tips.
Tip fornito dal sig. Boscolo Alberto Gnolo


File troppo "ingombranti"


Il tip mostra come eseguire lo Split di un file, cioΦ la divisione dei dati in esso contenuti in pi∙ file di dimensioni nettamente inferiori, e l'UnSplit cioΦ il processo inverso attraverso il quale si ricrea il file originale.
Pu≥ essere utile splittare un file quando, ad esempio, questo occupi troppo spazio per poter essere copiato su un FloppyDisk. Lo si potrebbe splittare in tanti file di 1457664 bytes (1 Floppy 1.44 Mb) copiandoli ognuno su altrettanti dischetti, trasportarli su un qualsiasi altro sistema ed, eseguendo l'UnSplit, recuperare il file originale.
Trovate il progetto completo nella directory /tips del Cd-Rom allegato o digitando l'url: www.itportal.it/ioprog71/tips.
Tip fornito dal Sig. S.Scigliuzzi