Archive

Archive for settembre 2008

[AS3] – Analizzatore di Spettro Audio (Parte I)

26 settembre 2008 2 commenti

 
Questo esempio mostra come realizzare un semplice Analizzatore di Spettro Audio con effetti di sfocatura ( Classe : BlurFilter ), trasformazione del colore ( Classe : ColorMatrixFilter ), ed “avanzamento” della curva.

 

… click sull’immagine

… il codice

// .......................................................
// PROGRAM-ID.    SOUND010.fla
//
// AUTHOR.        silver peacock.
// DATE-WRITTEN.  10/06/2008
// DATE-COMPILED. 25/09/2009
//
// REMARKS.       Analizzatore di Spettro Audio.
//                Questo esempio mostra come acquisire i
//                valori della forma d'onda di un audio in
//                riproduzione con il metodo statico
//                computeSpectrum() della classe SoundMixer
//                e disegnare un grafico corrispondente in
//                un oggetto BitMapData con effetti di
//                sfocatura (BlurFilter) e trasformazione
//                del colore (ColorMatrixFilter).
// .......................................................

import flash.media.Sound;
import flash.utils.ByteArray;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.filters.BlurFilter;
import flash.filters.ColorMatrixFilter;

// ... dichiarazione variabili globali :
var audio       :Sound;
var byteArray   :ByteArray;

var bitMapData  :BitmapData;
var bitMap      :Bitmap;

var curva       :Sprite;
var filtro      :BlurFilter;
var mtxColori   :ColorMatrixFilter;

var box         :Sprite;

var x_0         :Number;
var y_0         :Number;
var xx          :Number;
var yy          :Number;
var coef_x      :uint;
var coef_y      :uint;

// ... crea gli oggetti :

// ... l'oggetto Sound
audio    = new Sound(new URLRequest("Heartbreaker.mp3"));

// ... l'oggetto ByteArray che sara' passato come
//     argomento al metodo statico computeSpectrum()
//     della Classe SounMixer che lo valorizzerà con 512
//     valori a virgola mobile, di cui i primi 256 valori
//     rappresentano il canale sinistro e gli altri 256
//     valori il canale destro.
//
// ... nota : i valori caricati nel ByteArray sono
//     "normalizzati" e compresi tra : -1.0 a +1.0
//     ( vedere la guida in linea )
byteArray   = new ByteArray();

// ... l'oggetto BitmapData (lo sfondo) su cui disegnare
// ... al metodo costruttore sono passati come argomenti :
//     larghezza, altezza, trasparenza e colore.
bitMapData = new BitmapData(400, 200, true, 0x00000000);

// ... la BitMap relativa
bitMap     = new Bitmap(bitMapData);

// ... l'oggetto Sprite
curva      = new Sprite();

// ... l'ggetto BlurFilter per creare l'effetto sfocatura.
// ... al costruttore sono passati come argomenti :
//     quantita' di sfocatura orizzontale, quantita' di
//     di sfocatura verticale e numero di operazioni di
//     sfocatura da ripetere (qualita' della sfocatura)
filtro     = new BlurFilter(2, 2, BitmapFilterQuality.LOW);

// ... l'oggetto ColorMatrixFilter per creare l'effetto di
//     trasformazione dei Colori.
// ... al costruttore viene passato un'Array di 20
//     elementi (una matrice 4x5) corrispondenti ai valori
//     per la trasformazione del colore ed alpha (RGBA)
mtxColori  = new ColorMatrixFilter([1,0,0,0,0,
					  				0,1,0,0,0,
									0,0,2,0,0,
									0,0,0,0.98,0]);

// ... crea un oggetto contenitore della BitMap
box        = new Sprite();
box.graphics.clear();
box.graphics.beginFill(0x666666, 1);
box.graphics.drawRect(0, 0, bitMap.width, bitMap.height);
box.graphics.endFill();

// ... imposta le posizioni iniziali del grafico
x_0    = 0;
y_0    = (bitMap.height/2);

// ... imposta i coefficienti moltiplicativi per ottenere
//     le coordinate x ed y a partire dai valori della
//     forma d'onda presenti nel ByteArray (-1.0 e + 1.0)
coef_x = 20;
coef_y = 80;

// ... aggiungi la BitMap al box (contenitore)
box.addChild(bitMap);

// ... aggiungta la cura al box
box.addChild(curva);

// ... posiziona ed aggiungi il box allo Stage
box.x   =  -1;
box.y   = 100;

addChild(box);

// ... aggiungi l'ascoltatore evento : ENTER_FRAME
// ... la funzione sara' richiamata ad ogni riproduzione
//     del frame (fps)
addEventListener(Event.ENTER_FRAME, disegnaAnalizzatore);

// ... ok, avvia il sound!
audio.play(0, 1);

// ...

// .......................................................
//  FUNCTION : disegnaAnalizzatore()
//             acquisizione dei dati realtivi alla forma
//             d'onda e disegno della curva
// .......................................................
function disegnaAnalizzatore(evento:Event):void
{
    // ... pulisci il graphics prima di ridisegnare
    curva.graphics.clear();

    // ... imposta lo stile (spessore e colore)
    curva.graphics.lineStyle(1, 0x99CCFF);

	// ... posiziona la penna
	curva.graphics.moveTo(x_0, y_0);

	// ... carica la forma d'onda del sound nel ByteArray
	SoundMixer.computeSpectrum(byteArray);

	// ... ciclo sugli elementi del ByteArray
	for(var i:uint = 0; i  (bitMap.width-2))
		{
			xx = (bitMap.width-1);
			yy = (bitMap.height/2);
		}

		if (xx == 0)
		{
			yy = (bitMap.height/2);
		}

		// ... calcola la coordinata y :
		//     leggi il valore dal byteArray e moltiplica
		//     per il coefficiente della y.
		// ... nota : i valori presenti nel byteArray sono
		//            compresi tra -1.0 e +1.0
		yy = y_0 + ( byteArray.readFloat() * coef_y );

		// ... traccia la linea fino a
		curva.graphics.lineTo(xx, yy);
	}

	// ... disegna la curva nella bitmap
	bitMapData.draw(curva);

	// ... applica il filtro di sfocatura
	bitMapData.applyFilter(bitMapData, bitMapData.rect,
						   new Point(), filtro);

	// ... applica la matrice di trasfomazione dei
	//     colori
	bitMapData.applyFilter(bitMapData, bitMapData.rect,
						   new Point(), mtxColori);

	// ... scroll della bitmapData, per dare l'effetto
	//     di avanzamento (e' lo sfondo che si sposta)
	//     (+ verso destra, - verso sinistra)
	bitMapData.scroll(3,0);
}
// .......................................................

// ... END OF PROGRAM

Categorie:ACTIONSCRIPT 3.0

[DELPHI] – Start e Stop del MySQL Server da un’applicazione Delphi su Pendrive

15 settembre 2008 1 commento

Scenario…

Abbiamo un’applicazione Delphi (desktop) con Data Base MySQL. Vogliamo che l’applicazione possa essere avviata da una pendrive e che i dati (le Tabelle) siano anch’essi memorizzati su pendrive. Ma vogliamo anche che lo stesso MySQL Server sia sulla pendrive e che la nostra applicazione lo avvii alla partenza e lo arresti all’uscita.

… in poche parole vogliamo che tutto (La nostra applicazione, le Tabelle del DataBase  e l’engine del MySQL Server) sia presente sulla pendrive … e che l’utilizzatore della nostra applicazione non debba installare alcun software sul proprio computer! 

 

 Il MySQL Server sulla Pendrive.

Prepariamo l’ambiente sulla pendrive :

1. Creamo un directory nella pendrive (es. \contab) in cui copieremo la nostra applicazione Delphi, l’eseguibile (es. coge.exe)

2. Nella stessa direcotory ( \contab ), copiamo l’intera cartella ( \mysql ) con tutte le sue sottocarelle : \bin, \data, \share e \Docs (possiamo anche, se preferiamo, rinominarla)

3. Nel file di configurazione del MySQL (my.ini), modifichiamo i percorsi assegnati a basedir e datadir

File di Configurazione del MySQL :  my.ini (presente nella cartella \mysql)

...
# CLIENT SECTION
# ----------------------------------------------------------------------
#
# The following options will be read by MySQL client applications.
# Note that only client applications shipped by MySQL are guaranteed
# to read this section. If you want your own MySQL client program to
# honor these values, you need to specify it as an option during the
# MySQL client library initialization.
#
[client]

port=3306

default-character-set=latin1

# SERVER SECTION
# ----------------------------------------------------------------------
#
# The following options will be read by the MySQL Server. Make sure that
# you have installed the server correctly (see above) so it reads this
# file.
#
[mysqld]

# The TCP/IP Port the MySQL Server will listen on
port=3306

#Path to installation directory. All paths are usually resolved relative to this.
basedir="\mysql\"

#Path to the database root
datadir="\mysql\data\"
...

Le Funzioni per lo Start e Stop del MySQL Sever.

Di seguito sono riportate le quattro funzioni per la gestione dell’avvio e l’arresto del MySQL Server.
Le funzioni SP_MySQLStart() e SP_MySQLStop() effettuano rispettivamente l’avvio e l’arresto del MySQL Server, la funzione SP_ExecProcess() avvia un processo richiamando a sua volta l’API di Windows CreateProcess(), ed infine la funzione SP_CheckProcess() controlla se un processo è in esecuzione o meno.

… le funzioni sono state raccolte in una unit : MySQLServer_Lib.pas, così da poter essere facilmente incluse ed utilizzate nei propri progetti…


unit MYSQLServer_Lib;

interface

Uses Forms,SysUtils, DBTables, Classes, DB, Dialogs, StdCtrls,
        WinTypes, WinProcs;

   // ... funzioni per lo Start e Stop del servizio MySQL Server
   function  SP_MySQLStart(var pHandle_Server:THandle):Integer;
   function  SP_MySQLStop(pHandle_Server:THandle) :Integer;

   function  SP_ExecProcess(pApplication, pCommandLine, pDirectory : string): THandle;
   function  SP_CheckProcess(pHandle: THandle): Boolean;

const

   // ... costanti relative ai valori di ritorno delle funzioni
   //     di Strat e Stop.
   ENGINE_STARTED             = 9001;
   ENGINE_RUNNING             = 9002;
   ENGINE_START_ERROR         = 9003;

   ENGINE_STOPPED             = 9004;
   ENGINE_NOT_RUNNING         = 9005;
   ENGINE_STOP_ERROR          = 9006;

implementation

//--------------------------------------------------------------------------
// FUNCTION  : SP_MySQLStart()
//             La Funzione effettua lo Start del MySQL Server (mysql-nt.exe)
//
// PARAMETRI : Nessuno
//
// RETURN    : La funzione ritorna uno dei valori interi dichiarati
//             come const :
//              ENGINE_STARTED      = 9001 - MySQL Server avviato.
//              ENGINE_RUNNING      = 9002 - MySQL Server gia' in esecuzione.
//              ENGINE_START_ERROR  = 9003 - Errore durante l'avvio.
//--------------------------------------------------------------------------
function SP_MySQLStart(var pHandle_Server:THandle):Integer;
var
  Start_Code        : Integer;

  PathEngine        : string;

  ApplicationName   : string;
  CommandLine       : string;
  CurrentDirectory  : string;
begin

  // ... directory corrente dell'Applicazione Delphi
  //     ( da dove l'applicazione è stata avviata)
  PathEngine        := GetCurrentDir;

  // ... assegna : Nome Applicazione, Linea di Comando e Directory di lavore
  ApplicationName   := PathEngine + '\DataBase\bin\mysqld-nt.exe';
  CommandLine       := '--defaults-file="\DataBase\my.ini"';
  CurrentDirectory  := PathEngine + '\DataBase';

  // ... controlla se il Processo ( il MySQL Engine è già in esecuzione )
  if SP_CheckProcess(pHandle_Server) = true then begin
     // ... il processo MySQL Server è gia' in esecuzione
     Start_Code := ENGINE_RUNNING;
     // ShowMessage('MYSQL Server gia'' in esecuzione');
  end
  else begin
     // ShowMessage('MYSQL Server non in esecuzione, START...');

     // ... Start dell'MSQL Engine!
     pHandle_Server := SP_ExecProcess(ApplicationName, CommandLine, CurrentDirectory);
     // ... Sleep ( attendi un po' )
     sleep(3000);
     if pHandle_Server <> 0 then begin
        // ... Ok, avviato !
        Start_Code := ENGINE_STARTED;
     end
     else begin
        // ... errore durante l'avvio del servizio MySQL Server
        Start_Code := ENGINE_START_ERROR;
        // ShowMessage('Errore durante lo START!');
     end;
  end;
  // ... ritorna lo Start Code relativo
  Result := Start_Code;
end;
//--------------------------------------------------------------------------

//--------------------------------------------------------------------------
//
// FUNCTION  : SP_MySQLStop()
//             La Funzione effettua lo Stop del servizion MySQL Server
//
// PARAMETRI : Nessuno
//
// RETURN    : La funzione ritorna uno dei valori interi dichiarati
//             come const :
//              ENGINE_STOPPED      = 9004 - MySQL Server arrestato.
//              ENGINE_NOT_RUNNING  = 9005 - MySQL Server non in esecuzione.
//              ENGINE_STOP_ERROR   = 9005 - Errore durante l'arresto.
//
//--------------------------------------------------------------------------
function SP_MySQLStop(pHandle_Server:THandle):Integer;
var
  Stop_Code         : Integer;

  Handle_Admin      : THandle;

  PathEngine        : string;

  ApplicationName   : string;
  CommandLine       : string;
  CurrentDirectory  : string;

  contatore         : Integer;
begin

  // ... directory dell'Applicazione Delphi ( da dove è stata avviata )
  PathEngine        := GetCurrentDir;

  // ... avviamo il msqladmin.exe che ci consentirà di arretsare il MySQL Engine
  //     (mysqld-nt.exe)

  // ... assegna : Nome Applicazione, Linea di Comando e Directory di lavoro
  ApplicationName   := PathEngine + '\DataBase\bin\mysqladmin.exe';

  // ... User e Password (sono impostate a root root ...impostare le proprie)
  CommandLine       := '-u root -proot shutdown';

  // ... direcoty di lavoro
  CurrentDirectory  := PathEngine + '\DataBase';

  // ... controlla se il Processo ( il MySQL Engine è in esecuzione )
  if SP_CheckProcess(pHandle_Server) = FALSE then begin
     // ... esci!
     Stop_Code := ENGINE_NOT_RUNNING;
     // ShowMessage('MySQL NON E'' IN ESECUZIONE');
  end
  else begin
     // ShowMessage('MySQL E'' IN ESECUZIONE, STOP...');

     // ... per fermare il servizio MySQL Server, dobbiamo avviare il servizio
     // mysqladmin.exe indicando, nella riga di comando ( CommandLine ),
     // ... lo shutdown del servizio con la relativa utenza e password
     Handle_Admin := SP_ExecProcess(ApplicationName, CommandLine, CurrentDirectory);

     if Handle_Admin <> 0 then begin
        // ... il servizio myqladmin.exe e' avviato,
        // ... ora attendi che il mysqladmin arresti il MySQL Engine (msqld-nt.exe)
        contatore := 10;
        repeat
            // ... decrementa il contatore
            dec(contatore);
            // ... controlla se il Processo è ancora attivo
            if SP_CheckProcess(pHandle_Server) = TRUE then begin
               // ... si, ancora attivo ... attendi un po'
               Sleep(3000);
            end;
        until (contatore < 1) or (Handle_Admin = 0);

        // ... chiudi l'Handle del msqladmin.exe
        CloseHandle(Handle_Admin);
        // ShowMessage('MySQl Server stopped');
        Stop_Code := ENGINE_STOPPED;
        // ShowMessage('STOPPED OK !');
     end
     else begin
        // ... errore durante l'avvio del servizio msqadmin.exe...
        //     (che avrebbe dovuto fermare il mysqld-nt.exe)
        Stop_Code := ENGINE_STOP_ERROR;
        // ShowMessage('ERRORE DURANTE LO STOP !');
     end;
  end;

  // ... ritorna lo Stop Code relativo
  Result := Stop_Code;
end;
//--------------------------------------------------------------------------

//--------------------------------------------------------------------------
//
// FUNCTION  :  SP_ExecProcess()
//              La Funzione avvia un'applicazione creandone il
//              processo relativo.
//              Richiama l'API di Windows CreateProcess().
//
// PARAMS    :  Sono previsti tre parametri in ingresso :
//
//              pApplication = Nome del l'applicazione che
//                             da avviare.
//
//              pCommandLine = Linea di comando.
//                             (eventuali parametri e flags
//                              da passare all'applicazione
//                              da avviare).
//
//              pDirectory   = Directory di lavoro
//                             dell'applicazione.
//
// RETURN    :  La funzione ritorna l'handle relativo al processo
//              avviato.
//
//--------------------------------------------------------------------------
function SP_ExecProcess(pApplication, pCommandLine,
                        pDirectory : string): THandle;
var
  // ... struttura contenete le Info di StartUp dell'applicazione
  //     da avviare.
  //     (vedere la documentazione Windows SDK Developer's Reference)
  sInfo          : TStartupInfo;

  // ... struttura contenete le Info del processo avviato.
  //     (vedere la documentazione Windows SDK Developer's Reference)
  pInfo          : TProcessInformation;

  // ... handle del processo
  Handle_Process : THandle;

  // ... flag che indica se il processo e' stato creato o meno
  CreatedOK      : Boolean;

begin

  // ... inizializza la Struttura sInfo
  FillChar(sInfo, SizeOf(sInfo), 0);

  // ... ora inizializza la Struttura pInfo
  FillChar(pInfo, SizeOf(pInfo), 0);

  // ... l'elemento .cb (della struttura TStartupInfo) indica
  //     la taglia, in bytes, della struttura...
  // ... assegnagli il valore!
  sInfo.cb := SizeOf(TStartupInfo);

  // ... l'elemento .wShowWindow indica SE e COME deve apparire
  //     la Window relativa al processo che stiamo avviando.
  // ... voglio che il MySQL Sever parta senza che appaia
  //     la finestra del prompt dei comandi.
  sInfo.wShowWindow := SW_HIDE;
  sInfo.dwFlags     := STARTF_USESHOWWINDOW;

  // ... inizializza a FALSE il Flag di creazione del processo
  CreatedOK := FALSE;

  // ... richiama l'API di Windows CreateProcess()
  CreatedOK := CreateProcess(nil, PChar(pApplication + ' ' +
                                        pCommandLine),
                                        nil,
                                        nil,
                                        False,
                                        CREATE_NEW_PROCESS_GROUP +
                                        HIGH_PRIORITY_CLASS,
                                        nil,
                                        PChar(pDirectory),
                                        sInfo,
                                        pInfo);

  // ... test del valore di ritorno della funzione CreateProcess()
  if (createdOK = TRUE) then begin
     // ... ok! il processo e' stato creato...
     // ... ritorna l'id del processo
     Handle_Process := pInfo.hProcess;
  end
  else begin
     // ... il processo non e' stato creato !
     // ... ritorna 0 !
     Handle_Process := 0;
  end;
  //
  Result := Handle_Process;
end;
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//
// FUNCTION  : SP_CheckProcess()
//             La Funzione controlla se un processo è attivo o meno
//
// PARAMETRI : E' previsto un unico parametro in ingresso :
//             pHandle  =  L'identificativo (Handle) del processo
//                         ...il valore dell'Handle è quello ritornato dalla
//                         funzione SP_ExecProcess()
//
// RETURN    : La funzione ritorna un valore Booleano :
//             True  = se il processo è attivo
//             False = se il processo non è attivo
//
//--------------------------------------------------------------------------
function SP_CheckProcess(pHandle: THandle): Boolean;
var
  Check_Flag : Boolean;
  ExitCode   : Cardinal;
begin

  // ... assegna FALSE al valore di ritorno
  Check_Flag := FALSE;

  // ... test sull'Handle del processo
  if (pHandle <> 0) then begin
     // ... è diverso da ZERO... allora :
     // ... richiamo dell'API di Windows GetExitCode() che valorizzerà
     //     ExitCode e ritornerà TRUE se la funzione ha successo.
     if (GetExitCodeProcess(pHandle, ExitCode) = TRUE) then begin
        // ... analisi dell'ExitCode
        if (ExitCode = STILL_ACTIVE) then begin
           // ... il processo è ancora attivo
           // showmessage('ancora attivo');
           Check_Flag := TRUE;
        end
        else begin
           // ... il processo non e' attivo
           // showmessage('non attivo');
           CloseHandle(pHandle);
           pHandle    := 0;
           // ... il processo non e' attivo
           Check_Flag := FALSE;
        end;
     end
     else begin
        // ShowMessage('Valore della ExitCodeProcess = FALSE (insuccesso) ');
     end;
  end
  else begin
     // ShowMessage('Halndle da controllare e'' ZERO');
  end;

  // ... ritorna il Check Flag
  Result := Check_Flag;
end;
//--------------------------------------------------------------------------

end.

La Form per il test delle Funzioni…

Una semplice Form per effettuare il test delle funzioni di Start e Stop del MySQL Server.
La Form prevede solo due bottoni, uno per l’avvio e l’altro per l’arresto del MySQL Server, ed una Label in cui sarà visualizzato il messaggio relativo…


unit UMySQLServer_Test;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons,

  MySQLServer_Lib;

type
  TFMySQLServer_Test = class(TForm)
    B_START : TBitBtn;
    B_STOP  : TBitBtn;

    MSG     : TLabel;

    procedure B_STARTClick(Sender: TObject);
    procedure B_STOPClick(Sender: TObject);

    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }

  end;

var
  FMySQLServer_Test    : TFMySQLServer_Test;

  //  ... identificativo del processo relativo al MySQL Server
  MySQL_Server_Handle : THandle;

implementation

{$R *.DFM}

//--------------------------------------------------------------------------
//   EVENTO : FormCreate
//--------------------------------------------------------------------------
procedure TFMySQLServer_Test.FormCreate(Sender: TObject);
begin
  // ... inizializza a 0
  MySQL_Server_Handle := 0;
end;
//--------------------------------------------------------------------------

//--------------------------------------------------------------------------
//   EVENTO : FormShow
//--------------------------------------------------------------------------
procedure TFMySQLServer_Test.FormShow(Sender: TObject);
begin
  // ... messaggio a video
  MSG.Caption := '';
end;
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//   EVENTO : Click sul BOTTONE START_ENGINE
//--------------------------------------------------------------------------
procedure TFMySQLServer_Test.B_STARTClick(Sender: TObject);
var
  Start_Code : Integer;
begin

  // Start MySQL Server

  // ... imposta il Cursore a clessidra
  Screen.Cursor := crHourglass;

  // ... eventuale messaggio di attesa
  MSG.Caption := 'Start MySQL Server ...please wait';

  // ... forza la visualizzazione del messaggio
  Application.ProcessMessages;

  // ... richiamo della Funzione di Start del MySQL Server
  Start_Code := SP_MySQLStart(MySQL_Server_Handle);

  // ... analisi del Codice di ritorno :
  case Start_Code of
           ENGINE_STARTED : begin
                               MSG.Caption := 'MySQL Server started!';
                            end;

           ENGINE_RUNNING : begin
                               MSG.Caption := 'MySQL Server running';
                            end;

       ENGINE_START_ERROR : begin
                               MSG.Caption := 'MySQL Server Start Error!';
                            end;
  end;

  // ... ripristina il Cursore
  Screen.Cursor := crDefault;
end;
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//   EVENTO : Click sul BOTTONE STOP_ENGINE
//--------------------------------------------------------------------------
procedure TFMySQLServer_Test.B_STOPClick(Sender: TObject);
var
  Stop_Code : Integer;
begin

  // ... Stop MYSQL Server :

  // ... imposta il Cursore a clessidra
  Screen.Cursor := crHourglass;

  // ... eventuale messaggio di attesa
  MSG.Caption := 'Stop MySQL Server ...please wait';

  // ... forza la visualizzazione del messaggio
  Application.ProcessMessages;

  // ... richiamo della Funzione di Start del MySQL Server
  Stop_Code   := SP_MySQLStop(MySQL_Server_Handle);

  // ... analisi del Codice di ritorno :
  case Stop_Code of
          ENGINE_STOPPED : begin
                               MSG.Caption := 'MySQL Server stopped!';
                           end;

      ENGINE_NOT_RUNNING : begin
                               MSG.Caption := 'MySQL Server not running';
                           end;

       ENGINE_STOP_ERROR : begin
                               MSG.Caption := 'MySQL Server Stop Error!';
                           end;
  end;

  // ... ripristina il Cursore
  Screen.Cursor := crDefault;
end;
//--------------------------------------------------------------------------

end.