Les sons système et Delphi : comment les utiliser

Vincent CALLIES

Le système d'exploitation utilise un nombre impressionnant de sons qu'il peut être utile ou amusant d'intégrer dans une application Delphi. Cela économise de la place (les sons ne sont pas à distribuer avec l'application), cela permet d'avoir une interface complète (c'est-à-dire aussi bien graphique que sonore).

- Titre : Les sons système et Delphi : comment les utiliser

- Auteur : Vincent CALLIES

- Parution : 26 août 2000

- Mise à jour : 28 décembre 2019

- Licence : Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Sommaire

- I. Où se trouvent les sons du système d'exploitation ?

- II. L'API MessageBeep ou les sons accompagnant les fenêtres de dialogue

- III. L'API PlaySound, ou comment émettre n'importe quel son depuis Dephi ?

- IV. L'API SndPlaySound, ou comment émettre simplement n'importe quel son système ?

I - Où se trouvent les sons du système d'exploitation ?

L'ensemble des sons utilisés par le système peuvent être choisis depuis le Panneau de configuration : la boîte de dialogue Propriétés de sons vous permet d'associer un son à un évènement du système d'exploitation. Cette boîte de dialogue inscrit votre choix dans le registre de Windows. Il vous est déconseillé de les modifier directement par l'éditeur du registre. Les sons sont stockés sur le disque, dans le sous-répertoire \media du répertoire \Windows.

Les familles de sons (thèmes) sont indiquées au sein de la clé de registre :

HKEY_CURRENT_USER\AppEvents\Schemes\Names

La signification (description) des sons est indiquée au sein de la clé de registre :

HKEY_CURRENT_USER\AppEvents\EventLabels

L'affectation ou non des sons peut être vérifiée avec la clé suivante :

HKEY_CURRENT_USER\AppEvents\Schemes\Apps\.Default

Bien évidemment, ces informations peuvent varier quelque peu d'un système d'exploitation à l'autre, tout du moins je l'imagine. Aussi, le cas échéant, je vous invite à me contacter pour m'aider à compléter cette partie de l'article.

Note : voici les façons d'accéder à l'éditeur de registre et à la boîte de dialogue Propriétés des sons :

- RegEdit.exe est une application très commode qui vous permet d'éditer et de modifier la base de registre Windows. Elle est présente sur tous les systèmes (W95-98,2000,NT). Afin d'y accéder rapidement, il peut être utile de mettre un raccourci sur le bureau. Pour ce faire allez sur le bureau, faites un double-clic sur l'icône Poste de travail, faites Ctrl-F, renseignez le champ nommé par regedit.exe, renseignez le champ Rechercher dans par le chemin de votre répertoire Windows (généralement C:\WINDOWS), cliquez sur le bouton Recherche maintenant. Faites un clic du bouton droit de la souris sur le fichier RegEdit là où la recherche a abouti, choisissez dans le PopUpMenu l'option Envoyer vers… Bureau (créer un raccourci) ;

- pour accéder à la boîte de dialogue Propriétés de sons cliquez sur Démarrer, pointez sur Paramètres, cliquez sur Panneau de configuration, puis double-cliquez sur Sons.

II - L'API MessageBeep ou les sons accompagnant les fenêtres de dialogue

L'API MessageBeep permet d'émettre un son système. Cette API est déclarée dans l'unité WINDOWS.PAS. La déclaration de l'API est la suivante :

function MessageBeep; external user32 name 'MessageBeep';

Nous reviendrons en détail sur les déclarations de DLL dans le deuxième exercice. À ce point de l'article, il suffit de noter que Delphi vous propose d'utiliser la fonction MessageBeep située dans la bibliothèque user32.dll.

Cette API permet d'utiliser les sons système suivants :

Contexte

Correspondance TMsgDlgType

0xFFFFFFFF

Message sonore basic généré par le haut-parleur de votre PC.

mtCustom - Une boîte de dialogue ne contenant pas d'icône.

MB_ICONASTERISK

SystemAsterisk - Message d'information.

mtInformation - Une boîte de dialogue ayant pour icône un « i » bleu.

MB_ICONEXCLAMATION

SystemExclamation - Message d'avertissement

mtWarning - Une boîte de dialogue ayant pour icône un signe point d'exclamation jaune.

MB_ICONHAND

SystemHand - Message d'Erreur (interruption d'un processus)

mtError - Une boîte de dialogue contenant un signe de stop rouge.

MB_ICONQUESTION

SystemQuestion - Message demandant une confirmation ou une infirmation.

mtConfirmation - Une boîte de dialogue ayant pour icône un point d'interrogation vert.

MB_OK

SystemDefault - Message sonore par défaut.

Nous avons donc accès par cette API à l'ensemble des sons utilisés dans le cadre de la gestion de fenêtre modale. On observera la concordance de ces sons avec le type TMsgDlgType définissant les valeurs décrivant les types d'une boîte de dialogue de message.

Pour réaliser une application de test, nous allons :

1. Créer une nouvelle application (Fichier, Nouveau, Application) ;

2. Déposer sur la fenêtre un TButton (double-cliquez sur son icône dans l'onglet standard de la palette des composants) ;

3. Modifier l'évènement OnClick du bouton (dans l'inspecteur d'objet, allez dans les Évènements de l'objet Button1 et double-cliquez dans l'évènement OnClick) ;

4. Copier la routine ci-dessous…

procedure TForm1.Button1Click(Sender: TObject);
begin
MessageBeep(MB_ICONQUESTION);
MessageDlg('Que pensez-vous de cet exemple. Vous plait-il ?',
mtConfirmation, [mbYes, mbNo], 0);
end;

Il peut être intéressant d'accéder aux sons utilisés dans une autre cadre que celui des fenêtres de dialogue, tels que ceux caractérisant la réduction d'une fenêtre, le démarrage d'un programme, la notification d'un e-mail ou l'arrêt de Windows… La simple API MessageBeep devient alors insuffisante.

Pour aller plus loin… Comme nous venons de le voir, les messages de dialogues Delphi - les TMessageDlg - ne sont pas pourvus d'un accompagnement sonore. Il est très simple, maintenant que vous maîtrisez l'utilisation de l'API MessageBeep de créer un descendant de TMessageDlg pour ajouter cette propriété au composant !

III - L'API PlaySound, ou comment émettre n'importe quel son depuis Dephi ?

Une bibliothèque de fonctions dénommée WINMM.DLL regroupe les API multimédias de Windows. Parmi ses fonctions, il y a l'API PlaySound permettant d'émettre n'importe quel son WAVE.

Nous allons :

1. Créer une nouvelle application (Fichier, Nouveau, Application) ;

2. Déposer sur la fenêtre un TButton (double-cliquez sur son icône dans l'onglet standard de la palette des composants) ;

3. Modifier l'évènement OnClick du bouton (dans l'inspecteur d'objet, allez dans les Évènements de l'objet Button1 et double-cliquez dans l'évènement OnClick) ;

4. Copier la routine ci-dessous :

procedure TForm1.Button1Click(Sender: TObject);
begin
if not (FaireduBruit(MonFichier, handle,SND_ASYNC)) then
showmessage('Il y a un problème !');
end;

En l'état la fonction ne peut être appelée. La précédente API, MessageBeep avait été déclarée dans l'unité WINDOWS.PAS que l'on retrouvait dans la clause Uses. En ce qui concerne FaireduBruit, il convient de déclarer cette API ainsi que les constantes utiles (en l'occurrence SND_ASYNC). Nous allons ajouter les déclarations suivantes, avant et après la section implementation :

const
//Vous pouvez appeler le fichier que vous souhaitez
MonFichier = 'c:\WINDOWS\MEDIA\logoff.wav';

//Constante indiquant que le fichier doit être joué de façon asynchrone,
//c'est-à-dire permettre à votre programme de continuer son exécution sans
//attendre la fin de la lecture du fichier son.
SND_ASYNC = 0;

implementation
function FaireduBruit(lpszName : String; hModule : Integer; dwFlags : Integer):Boolean;
stdcall;external 'winmm.dll' name 'PlaySound';

Dès lors, notre projet peut être exécuté : vous pouvez le lancer (en appuyant sur la touche de raccourci de l'EDI F9, par exemple).

IV - L'API SndPlaySound, ou comment émettre simplement n'importe quel son système ?

Le précédent exemple était bien compliqué pour lire un fichier système, mais cela avait pour but de vous montrer comment lire n'importe quel fichier WAVE et comment faire la déclaration d'une DLL. Mais il y a un moyen bien plus simple de faire ce travail que nous allons voir ici.

- Les déclarations des fonctions de la bibliothèque WINMM.DLL (les API multimédias de Windows) ont déjà été faites par Borland : inutile de les déclarer vous-même, il suffit d'inclure dans la clause uses mmsystem ! Il en est de même pour les constantes utiles à l'utilisation de l'API.

- Dès lors, nous avons accès à l'API PlaySound, mais aussi à son petit frère SndPlaySound à l'utilisation enfantine !

Nous allons refaire entièrement notre projet :

1. Créer une nouvelle application (Fichier, Nouveau, Application) ;

2. Insérer dans la clause uses, mmsystem ;

3. Déposer sur la fenêtre un TButton (double-cliquez sur son icône dans l'onglet standard de la palette des composants) ;

4. Modifier l'évènement OnClick du bouton (dans l'inspecteur d'objets, allez dans les Évènements de l'objet Button1 et double-cliquez dans l'évènement OnClick) ;

5. Copier la routine ci-dessous :

procedure TForm1.Button1Click(Sender: TObject);
begin
if not(PlaySound('c:\WINDOWS\MEDIA\logoff.wav', handle,SND_ASYNC)) then
showmessage('Il y a un problème ! Peut-être le chemin indiqué n''est pas bon...');
end;

Notre projet peut être exécuté : il a été élaboré trois fois plus rapidement !
Vous pouvez exécuter le projet en appuyant sur la touche F9.

Note : si vous avez un message d'erreur, vérifiez que vous avez bien fait une référence à l'unité mmsystem dans la clause uses.

La fonction sndPlaySound permet de lire un fichier WAVE qui est indiqué à la fonction soit par son chemin d'accès soit par une clé du registre. Il est à noter que la Fonction PlaySound le permet aussi, mais gère inutilement plusieurs paramètres.

Nous allons modifier notre projet comme il suit :

1. Ajouter un composant ComboBox sur votre fiche ;

2. Ajouter un évènement OnCreate à votre Form ;

3. Modifier les évènements OnClick du bouton ;

4. Copier la routine d'évènement FormCreate de la form ci-dessous :

procedure TForm1.FormCreate(Sender: TObject);
begin
with ComboBox1.Items do
begin
Add('.Default');
Add('AppGPFault');
Add('CCSelect');
Add('Close');
Add('EmptyRecycleBin');
Add('MailBeep');
Add('Maximize');
Add('MenuCommand');
Add('MenuPopup');
Add('Minimize');
Add('NMain-MouseClick');
Add('NMain-MouseLeave');
Add('NMain-MouseOver');
Add('Open');
Add('RestoreDown');
Add('RestoreUp');
Add('ShowBand');
Add('SystemAsterisk');
Add('SystemExclamation');
Add('SystemExit');
Add('SystemHand');
Add('SystemQuestion');
Add('SystemStart');
end;
ComboBox1.Style := csDropDownList;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if not (sndPlaySound (pchar(ComboBox1.items[ComboBox1.ItemIndex]) ,SND_ASYNC ))
then ShowMessage('Il y a un problème ! Peut-être n''y a-t-il pas de son affecté !');
end;

Note : le gestionnaire d'erreurs n'est pas utile. En effet, si l'utilisateur n'a pas affecté de son pour un évènement, il me semble inutile de le lui infliger dans votre application. Tout du moins, me semble-t-il, non ?

Pour aller plus loin… La présente astuce existe aussi en Visual Basic. N'hésitez pas à aller voir sa traduction en Basic et de prendre note de la différence avec votre environnement (justement) bien aimé !

N'hésitez pas à me faire part de vos remarques ou suggestions en vue d'améliorer cet article !
Vincent CALLIES

Voir aussi
Sons Wav, musiques Midi/MP3, 3D, 3DNow, MMX, DirectX, Glide, Open GL & Jeux en Delphi